diff --git a/cmd/k3s/main.go b/cmd/k3s/main.go index 4e63c5770c..3572c56518 100644 --- a/cmd/k3s/main.go +++ b/cmd/k3s/main.go @@ -18,11 +18,15 @@ import ( ) func main() { + if runKubectl() { + return + } + app := cmds.NewApp() app.Commands = []cli.Command{ cmds.NewServerCommand(wrap("k3s-server", os.Args)), cmds.NewAgentCommand(wrap("k3s-agent", os.Args)), - cmds.NewKubectlCommand(kubectl), + cmds.NewKubectlCommand(kubectlCLI), } err := app.Run(os.Args) @@ -31,25 +35,46 @@ func main() { } } -func kubectl(ctx *cli.Context) error { - return stageAndRun(ctx, "kubectl", append([]string{"kubectl"}, ctx.Args()...)) +func runKubectl() bool { + if filepath.Base(os.Args[0]) == "kubectl" { + if err := kubectl("", os.Args[1:]); err != nil { + logrus.Fatal(err) + } + return true + } + return false +} + +func kubectlCLI(cli *cli.Context) error { + return kubectl(cli.String("data-dir"), cli.Args()) +} + +func kubectl(dataDir string, args []string) error { + dataDir, err := datadir.Resolve(dataDir) + if err != nil { + return err + } + return stageAndRun(dataDir, "kubectl", append([]string{"kubectl"}, args...)) } func wrap(cmd string, args []string) func(ctx *cli.Context) error { return func(ctx *cli.Context) error { - return stageAndRun(ctx, cmd, args) + return stageAndRunCLI(ctx, cmd, args) } } -func stageAndRun(cli *cli.Context, cmd string, args []string) error { +func stageAndRunCLI(cli *cli.Context, cmd string, args []string) error { dataDir, err := datadir.Resolve(cli.String("data-dir")) if err != nil { return err } - asset, dir := getAssetAndDir(dataDir) + return stageAndRun(dataDir, cmd, args) +} - if err := extract(asset, dir); err != nil { +func stageAndRun(dataDir string, cmd string, args []string) error { + dir, err := extract(dataDir) + if err != nil { return errors.Wrap(err, "extracting data") } @@ -62,6 +87,7 @@ func stageAndRun(cli *cli.Context, cmd string, args []string) error { return err } + logrus.Debugf("Running %s %v", cmd, args) return syscall.Exec(cmd, args, os.Environ()) } @@ -71,18 +97,25 @@ func getAssetAndDir(dataDir string) (string, string) { return asset, dir } -func extract(asset, dir string) error { - logrus.Debugf("Asset dir %s", dir) - +func extract(dataDir string) (string, error) { + // first look for global asset folder so we don't create a HOME version if not needed + asset, dir := getAssetAndDir(datadir.DefaultDataDir) if _, err := os.Stat(dir); err == nil { - return nil + logrus.Debugf("Asset dir %s", dir) + return dir, nil + } + + asset, dir = getAssetAndDir(dataDir) + if _, err := os.Stat(dir); err == nil { + logrus.Debugf("Asset dir %s", dir) + return "", nil } logrus.Infof("Preparing data dir %s", dir) content, err := data.Asset(asset) if err != nil { - return err + return "", err } buf := bytes.NewBuffer(content) @@ -92,8 +125,8 @@ func extract(asset, dir string) error { os.RemoveAll(tempDest) if err := untar.Untar(buf, tempDest); err != nil { - return err + return "", err } - return os.Rename(tempDest, dir) + return dir, os.Rename(tempDest, dir) } diff --git a/pkg/datadir/datadir.go b/pkg/datadir/datadir.go index 863b65a57a..a5bc8b2903 100644 --- a/pkg/datadir/datadir.go +++ b/pkg/datadir/datadir.go @@ -7,12 +7,17 @@ import ( "github.com/rancher/norman/pkg/resolvehome" ) +const ( + DefaultDataDir = "/var/lib/rancher/k3s" + DefaultHomeDataDir = "${HOME}/.rancher/k3s" +) + func Resolve(dataDir string) (string, error) { if dataDir == "" { if os.Getuid() == 0 { - dataDir = "/var/lib/rancher/k3s" + dataDir = DefaultDataDir } else { - dataDir = "${HOME}/.rancher/k3s" + dataDir = DefaultHomeDataDir } }