mirror of https://github.com/k3s-io/k3s.git
Unlink existing CNI bin symlinks
Fixes "file exists" error when upgrading k3s. Signed-off-by: Brad Davidson <brad.davidson@rancher.com>pull/11162/head
parent
5ec454f50e
commit
8e1701dfa8
|
@ -30,6 +30,10 @@ var criDefaultConfigPath = "/etc/crictl.yaml"
|
|||
|
||||
// main entrypoint for the k3s multicall binary
|
||||
func main() {
|
||||
if findDebug(os.Args) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
dataDir := findDataDir(os.Args)
|
||||
|
||||
// Handle direct invocation via symlink alias (multicall binary behavior)
|
||||
|
@ -87,6 +91,24 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
// findDebug reads debug settings from the environment, CLI args, and config file.
|
||||
func findDebug(args []string) bool {
|
||||
debug, _ := strconv.ParseBool(os.Getenv(version.ProgramUpper + "_DEBUG"))
|
||||
if debug {
|
||||
return debug
|
||||
}
|
||||
fs := pflag.NewFlagSet("debug-set", pflag.ContinueOnError)
|
||||
fs.ParseErrorsWhitelist.UnknownFlags = true
|
||||
fs.SetOutput(io.Discard)
|
||||
fs.BoolVarP(&debug, "debug", "", false, "(logging) Turn on debug logs")
|
||||
fs.Parse(args)
|
||||
if debug {
|
||||
return debug
|
||||
}
|
||||
debug, _ = strconv.ParseBool(configfilearg.MustFindString(args, "debug"))
|
||||
return debug
|
||||
}
|
||||
|
||||
// findDataDir reads data-dir settings from the environment, CLI args, and config file.
|
||||
// If not found, the default will be used, which varies depending on whether
|
||||
// k3s is being run as root or not.
|
||||
|
@ -280,11 +302,6 @@ func extract(dataDir string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
// Rename the new directory into place, before updating symlinks
|
||||
if err := os.Rename(tempDest, dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a stable CNI bin dir and place it first in the path so that users have a
|
||||
// consistent location to drop their own CNI plugin binaries.
|
||||
cniPath := filepath.Join(dataDir, "data", "cni")
|
||||
|
@ -292,19 +309,38 @@ func extract(dataDir string) (string, error) {
|
|||
if err := os.MkdirAll(cniPath, 0755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Create symlink that points at the cni multicall binary itself
|
||||
logrus.Debugf("Creating symlink %s -> %s", filepath.Join(cniPath, "cni"), cniBin)
|
||||
os.Remove(filepath.Join(cniPath, "cni"))
|
||||
if err := os.Symlink(cniBin, filepath.Join(cniPath, "cni")); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Find symlinks that point to the cni multicall binary, and clone them in the stable CNI bin dir.
|
||||
ents, err := os.ReadDir(filepath.Join(dir, "bin"))
|
||||
// Non-symlink plugins in the stable CNI bin dir will not be overwritten, to allow users to replace our
|
||||
// CNI plugins with their own versions if they want. Note that the cni multicall binary itself is always
|
||||
// symlinked into the stable bin dir and should not be replaced.
|
||||
ents, err := os.ReadDir(filepath.Join(tempDest, "bin"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, ent := range ents {
|
||||
if info, err := ent.Info(); err == nil && info.Mode()&fs.ModeSymlink != 0 {
|
||||
if target, err := os.Readlink(filepath.Join(dir, "bin", ent.Name())); err == nil && target == "cni" {
|
||||
if err := os.Symlink(cniBin, filepath.Join(cniPath, ent.Name())); err != nil {
|
||||
if target, err := os.Readlink(filepath.Join(tempDest, "bin", ent.Name())); err == nil && target == "cni" {
|
||||
src := filepath.Join(cniPath, ent.Name())
|
||||
// Check if plugin already exists in stable CNI bin dir
|
||||
if info, err := os.Lstat(src); err == nil {
|
||||
if info.Mode()&fs.ModeSymlink != 0 {
|
||||
// Exists and is a symlink, remove it so we can create a new symlink for the new bin.
|
||||
os.Remove(src)
|
||||
} else {
|
||||
// Not a symlink, leave it alone
|
||||
logrus.Debugf("Not replacing non-symlink CNI plugin %s with mode %O", src, info.Mode())
|
||||
continue
|
||||
}
|
||||
}
|
||||
logrus.Debugf("Creating symlink %s -> %s", src, cniBin)
|
||||
if err := os.Symlink(cniBin, src); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
@ -324,6 +360,12 @@ func extract(dataDir string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
// Rename the new directory into place after updating symlinks, so that the k3s binary check at the start
|
||||
// of this function only succeeds if everything else has been completed successfully.
|
||||
if err := os.Rename(tempDest, dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue