From de74f5bb94ba23f299a96313fe8a3ccea3213956 Mon Sep 17 00:00:00 2001 From: Sam Chew Date: Thu, 19 Sep 2024 13:53:41 -0700 Subject: [PATCH] Add DevContainers functionality to Finch Signed-off-by: Sam Chew --- cmd/finch/nerdctl_remote.go | 101 +++++++++++++++++++++-------------- pkg/config/config.go | 1 + pkg/config/config_darwin.go | 1 - pkg/config/config_windows.go | 1 - pkg/path/finch_linux.go | 2 +- 5 files changed, 63 insertions(+), 43 deletions(-) diff --git a/cmd/finch/nerdctl_remote.go b/cmd/finch/nerdctl_remote.go index 9441097bd..6353f6924 100644 --- a/cmd/finch/nerdctl_remote.go +++ b/cmd/finch/nerdctl_remote.go @@ -33,6 +33,9 @@ type ( ) func (nc *nerdctlCommand) run(cmdName string, args []string) error { + + logrus.Warn("nc.run invoked: ", append([]string{cmdName}, args...)) + err := nc.assertVMIsRunning(nc.ncc, nc.logger) if err != nil { return err @@ -72,7 +75,6 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { } switch cmdName { - case "container run", "exec", "compose": // check if an option flag is present; immediately following the command switch { @@ -140,6 +142,13 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { } arg = fmt.Sprintf("%s%s", arg[0:11], resolvedIP) nerdctlArgs = append(nerdctlArgs, arg) + case arg == "--load": + // This is a docker specific command which alias for --output=type=docker. + // This should only applied for build args. + // Long term, this run command potentially needs to be refactored. + // Currently, the way it handles the args is too hacky. + nc.logger.Info("found --load converting to --output flag") + nerdctlArgs = handleLoad(nc.fc, nerdctlArgs) case strings.HasPrefix(arg, "--env-file"): // exact match to --env-file // or arg begins with --env-file @@ -149,11 +158,6 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { } skip = shouldSkip fileEnvs = append(fileEnvs, addEnvs...) - // This is a docker specific command which alias for --output=type=docker. This should only applied for build args. - // On a long term this run command potentially needs to be refactored, currently it is too hacky the way it handles the args. - case arg == "--load": - nc.logger.Info("found --load converting to --output flag") - nerdctlArgs = handleLoad(nc.fc, nerdctlArgs) case argIsEnv(arg): // exact match to either -e or --env // or arg begins with -e or --env @@ -164,18 +168,27 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { if addEnv != "" { envs = append(envs, addEnv) } - case longFlagBoolSet.Has(strings.Split(arg, "=")[0]) || longFlagBoolSet.Has(arg): - // exact match to a short flag: -? + case shortFlagBoolSet.Has(arg) || longFlagBoolSet.Has(arg): + // exact match to a short no argument flag: -? // or exact match to: -- nerdctlArgs = append(nerdctlArgs, arg) + case longFlagBoolSet.Has(strings.Split(arg, "=")[0]): + // begins with -- + // e.g. --sig-proxy=false + nerdctlArgs = append(nerdctlArgs, arg) case shortFlagBoolSet.Has(arg[:2]): - // begins with a defined short flag, but is adjacent to one or more short flags: -???? + // or begins with a defined short no argument flag, but is adjacent to something + // -???? one or more short bool flags; no following values + // -????="" one or more short bool flags ending with a short arg flag equated to value + // -????"" one or more short bool flags ending with a short arg flag concatenated to value addArg := nc.handleMultipleShortFlags(shortFlagBoolSet, shortFlagArgSet, args, i) nerdctlArgs = append(nerdctlArgs, addArg) case shortFlagArgSet.Has(arg) || shortFlagArgSet.Has(arg[:2]): - // exact match to: -h,-m,-u,-w,-p,-l,-v - // or begins with: -h,-m,-u,-w,-p,-l,-v - // concatenated short flags and values: -p"8080:8080" + // exact match to a short arg flag: -? + // next arg must be the + // or begins with a short arg flag: + // short arg flag concatenated to value: -?"" + // short arg flag equated to value: -?="" or -?= shouldSkip, addKey, addVal := nc.handleFlagArg(arg, args[i+1]) skip = shouldSkip if addKey != "" { @@ -183,7 +196,11 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { nerdctlArgs = append(nerdctlArgs, addVal) } case strings.HasPrefix(arg, "--"): - // --="", -- "" + // exact match to a long arg flag: - + // next arg must be the + // or begins with a long arg flag: + // long arg flag concatenated to value: --"" + // long arg flag equated to value: --="" or --= shouldSkip, addKey, addVal := nc.handleFlagArg(arg, args[i+1]) skip = shouldSkip if addKey != "" { @@ -256,7 +273,6 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { case arg == "--help": nerdctlArgs = append(nerdctlArgs, arg) case arg == "--load": - nc.logger.Info("found --load converting to --output flag") nerdctlArgs = handleLoad(nc.fc, nerdctlArgs) default: nerdctlArgs = append(nerdctlArgs, arg) @@ -295,7 +311,7 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { if slices.Contains(args, "run") { ensureRemoteCredentials(nc.fc, nc.ecc, &additionalEnv, nc.logger) } - case "build", "pull", "push", "run": + case "build", "pull", "push", "container run": ensureRemoteCredentials(nc.fc, nc.ecc, &additionalEnv, nc.logger) } @@ -322,7 +338,7 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error { runArgs = handleDockerCompatInspect(nc.fc, runArgs) - nc.logger.Info("Running nerdctl command args ", runArgs, " end") + logrus.Warn("Attempting to run: ", runArgs) return nc.ncc.Create(runArgs...).Run() } @@ -525,20 +541,24 @@ func handleEnvFile(fs afero.Fs, systemDeps NerdctlCommandSystemDeps, arg, arg2 s func handleCache(fc *config.Finch, arg string) string { // Hack to handle consistency params during mounts. This is assuming no other commands or env variable will have the word consistency. - if fc.Mode == nil || *fc.Mode != "dockercompat" || runtime.GOOS != "darwin" { + if fc == nil || fc.Mode == nil || *fc.Mode != "dockercompat" || runtime.GOOS != "darwin" { + logrus.Warn("handleCache returning unchanged: ", arg) + //logrus.Warn("handleCache info: ", fc.Mode, *fc.Mode, runtime.GOOS) return arg } if strings.Contains(arg, "consistency") { - arg = strings.Replace(arg, ",consistency=cache", "", 1) + logrus.Warn("handleCache manipulating: ", arg) + arg = strings.Replace(arg, ",consistency=cached", "", 1) arg = strings.Replace(arg, ",consistency=delegated", "", 1) arg = strings.Replace(arg, ",consistency=consistent", "", 1) + logrus.Warn("handleCache returning: ", arg) } return arg } func handleLoad(fc *config.Finch, args []string) []string { - if fc.Mode == nil || *fc.Mode != "dockercompat" || args == nil { + if fc == nil || fc.Mode == nil || *fc.Mode != "dockercompat" || args == nil { return args } @@ -553,8 +573,7 @@ func handleLoad(fc *config.Finch, args []string) []string { } func handleDockerCompatInspect(fc *config.Finch, args []string) []string { - - if fc.Mode == nil || *fc.Mode != "dockercompat" { + if fc == nil || fc.Mode == nil || *fc.Mode != "dockercompat" { return args } @@ -575,7 +594,7 @@ func handleDockerCompatInspect(fc *config.Finch, args []string) []string { newArgList = append(newArgList, arg) } - if strings.Contains(arg, "--type") && (idx < len(args)+1) && isInspect { + if strings.Contains(arg, "--type") && (idx < len(args)-1) && isInspect { if strings.Contains(arg, "=") { inspectType = strings.Split(arg, "=")[1] } else { @@ -587,7 +606,6 @@ func handleDockerCompatInspect(fc *config.Finch, args []string) []string { continue } newArgList = append(newArgList, arg) - } if !isInspect { @@ -596,7 +614,9 @@ func handleDockerCompatInspect(fc *config.Finch, args []string) []string { switch inspectType { case "container": - newArgList = append(newArgList[:inspectIndex], append([]string{inspectType}, append([]string{newArgList[inspectIndex+1]}, append([]string{"--mode=dockercompat"}, newArgList[inspectIndex+2:]...)...)...)...) + dcTrailingArgs := append([]string{"--mode=dockercompat"}, newArgList[inspectIndex+2:]...) + dcMidArgs := append([]string{inspectType}, append([]string{newArgList[inspectIndex+1]}, dcTrailingArgs...)...) + newArgList = append(newArgList[:inspectIndex], dcMidArgs...) case "": break default: @@ -607,43 +627,44 @@ func handleDockerCompatInspect(fc *config.Finch, args []string) []string { } func handleBuildx(fc *config.Finch, limaArgs []string) (bool, []string) { - logrus.Warn("handling buildx") - buildx := false skipCmd := true var newLimaArgs []string buildxSubcommands := []string{"bake", "create", "debug", "du", "imagetools", "inspect", "ls", "prune", "rm", "stop", "use", "version"} - if fc.Mode == nil || *fc.Mode != "dockercompat" { + if fc == nil || fc.Mode == nil || *fc.Mode != "dockercompat" { return !skipCmd, limaArgs } - for idx, arg := range limaArgs { - logrus.Warnf("looking at arg %s at index %d", arg, idx) + for _, arg := range limaArgs { if arg == "buildx" { buildx = true newLimaArgs = append(newLimaArgs, "build") logrus.Warn("buildx is not supported. using standard buildkit instead...") + continue } - if buildx { - - buildxWarnMsg := "buildx %s command is not supported." + //// Find standard vsc container identifier to truncate to less than 76chars + //re := regexp.MustCompile(`(vsc)\-(\S+?)\-(\S+?)\-(\S+)`) + //if re.MatchString(arg) { + // matchSlice := re.FindStringSubmatch(arg) + // matchSlice[3] = matchSlice[3][:6] + // newArg := strings.Join(matchSlice[1:], "-") + // arg = newArg + //} + if buildx { if arg == "build" { - logrus.Warnf("found build") + logrus.Warnf("skipping the redundant 'build' arg") + // Do not add "build" again to the newLimaArgs continue } else if slices.Contains(buildxSubcommands, arg) { - logrus.Warnf(buildxWarnMsg, arg) + logrus.Warn("Unsupported buildx command: ", arg) return skipCmd, nil } - - logrus.Warnf("appending build") - newLimaArgs = append(newLimaArgs, arg) - - } else { - newLimaArgs = append(newLimaArgs, arg) } + + newLimaArgs = append(newLimaArgs, arg) } return !skipCmd, newLimaArgs diff --git a/pkg/config/config.go b/pkg/config/config.go index 0d02ed55c..428319074 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -32,6 +32,7 @@ type AdditionalDirectory struct { // SharedSystemSettings represents all settings shared by virtualized Finch configurations. type SharedSystemSettings struct { VMType *limayaml.VMType `yaml:"vmType,omitempty"` + Mode *string `yaml:"mode,omitempty"` } // SharedSettings represents settings shared by all Finch configurations. diff --git a/pkg/config/config_darwin.go b/pkg/config/config_darwin.go index b19b543d7..1e38aaea3 100644 --- a/pkg/config/config_darwin.go +++ b/pkg/config/config_darwin.go @@ -25,7 +25,6 @@ type SystemSettings struct { Memory *string `yaml:"memory,omitempty"` AdditionalDirectories []AdditionalDirectory `yaml:"additional_directories,omitempty"` Rosetta *bool `yaml:"rosetta,omitempty"` - Mode *string `yaml:"mode,omitempty"` SharedSystemSettings `yaml:",inline"` } diff --git a/pkg/config/config_windows.go b/pkg/config/config_windows.go index 3fb716382..9a4fff62c 100644 --- a/pkg/config/config_windows.go +++ b/pkg/config/config_windows.go @@ -11,7 +11,6 @@ import ( // SystemSettings represents the system configuration specifc to Windows. type SystemSettings struct { - Mode *string `yaml:"mode,omitempty"` SharedSystemSettings `yaml:",inline"` } diff --git a/pkg/path/finch_linux.go b/pkg/path/finch_linux.go index 8b3e84e8a..368452ae8 100644 --- a/pkg/path/finch_linux.go +++ b/pkg/path/finch_linux.go @@ -31,7 +31,7 @@ func (fp Finch) NerdctlConfigFilePath() string { // BuildkitSocketPath returns the path to the Buildkit socket file. func (fp Finch) BuildkitSocketPath() string { - return filepath.Join(string(fp), "buildkit", "buildkitd.toml") + return filepath.Join(fp.FinchRuntimeDataDir(), "buildkit", "buildkitd.sock") } // FinchDependencyBinDir returns the path to Finch's local helper or dependency binaries.