diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..4e7d6aac0 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +golang 1.21.13 diff --git a/cloud/cpi_cmd_runner.go b/cloud/cpi_cmd_runner.go index a3fc0d074..8ad0680f5 100644 --- a/cloud/cpi_cmd_runner.go +++ b/cloud/cpi_cmd_runner.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "os" - "strconv" bosherr "github.com/cloudfoundry/bosh-utils/errors" boshlog "github.com/cloudfoundry/bosh-utils/logger" @@ -67,22 +66,25 @@ type CPICmdRunner interface { } type cpiCmdRunner struct { - cmdRunner boshsys.CmdRunner - cpi CPI - logger boshlog.Logger - logTag string + cmdRunner boshsys.CmdRunner + cpi CPI + logger boshlog.Logger + logTag string + useIsolatedEnv bool } func NewCPICmdRunner( cmdRunner boshsys.CmdRunner, cpi CPI, logger boshlog.Logger, + useIsolatedEnv bool, ) CPICmdRunner { return &cpiCmdRunner{ - cmdRunner: cmdRunner, - cpi: cpi, - logger: logger, - logTag: "cpiCmdRunner", + cmdRunner: cmdRunner, + cpi: cpi, + logger: logger, + logTag: "cpiCmdRunner", + useIsolatedEnv: useIsolatedEnv, } } @@ -100,14 +102,6 @@ func (r *cpiCmdRunner) Run(context CmdContext, method string, apiVersion int, ar if err != nil { return CmdOutput{}, bosherr.WrapErrorf(err, "Marshalling external CPI command input %#v", cmdInput) } - useIsolatedEnv := true - value, present := os.LookupEnv("BOSH_CPI_USE_ISOLATED_ENV") - if present { - useIsolatedEnv, err = strconv.ParseBool(value) - if err != nil { - return CmdOutput{}, bosherr.WrapErrorf(err, "Parsing $BOSH_CPI_USE_ISOLATED_ENV error, could not parse value: %v", value) - } - } cmdPath := r.cpi.ExecutablePath() cmd := boshsys.Command{ @@ -115,11 +109,12 @@ func (r *cpiCmdRunner) Run(context CmdContext, method string, apiVersion int, ar Env: map[string]string{ "BOSH_PACKAGES_DIR": r.cpi.PackagesDir, "BOSH_JOBS_DIR": r.cpi.JobsDir, - "PATH": "/usr/local/bin:/usr/bin:/bin:/sbin", + "PATH": os.Getenv("PATH"), }, - UseIsolatedEnv: useIsolatedEnv, + UseIsolatedEnv: r.useIsolatedEnv, Stdin: bytes.NewReader(inputBytes), } + stdout, stderr, exitCode, err := r.cmdRunner.RunComplexCommand(cmd) r.logger.Debug(r.logTag, "Exit Code %d when executing external CPI command '%s'\nSTDIN: '%s'\nSTDOUT: '%s'\nSTDERR: '%s'", exitCode, cmdPath, string(inputBytes), stdout, stderr) if err != nil { diff --git a/cloud/cpi_cmd_runner_test.go b/cloud/cpi_cmd_runner_test.go index 6ce84b23d..4b9d512d0 100644 --- a/cloud/cpi_cmd_runner_test.go +++ b/cloud/cpi_cmd_runner_test.go @@ -21,6 +21,7 @@ var _ = Describe("CpiCmdRunner", func() { cmdRunner *fakesys.FakeCmdRunner cpi CPI apiVersion int + logger boshlog.Logger ) BeforeEach(func() { @@ -35,8 +36,8 @@ var _ = Describe("CpiCmdRunner", func() { } cmdRunner = fakesys.NewFakeCmdRunner() - logger := boshlog.NewLogger(boshlog.LevelNone) - cpiCmdRunner = NewCPICmdRunner(cmdRunner, cpi, logger) + logger = boshlog.NewLogger(boshlog.LevelNone) + cpiCmdRunner = NewCPICmdRunner(cmdRunner, cpi, logger, true) apiVersion = 1 }) @@ -63,7 +64,7 @@ var _ = Describe("CpiCmdRunner", func() { Expect(actualCmd.Env).To(Equal(map[string]string{ "BOSH_PACKAGES_DIR": cpi.PackagesDir, "BOSH_JOBS_DIR": cpi.JobsDir, - "PATH": "/usr/local/bin:/usr/bin:/bin:/sbin", + "PATH": os.Getenv("PATH"), })) Expect(actualCmd.UseIsolatedEnv).To(BeTrue()) bytes, err := io.ReadAll(actualCmd.Stdin) @@ -89,11 +90,8 @@ var _ = Describe("CpiCmdRunner", func() { apiVersion = 2 }) - AfterEach(func() { - os.Unsetenv("BOSH_CPI_USE_ISOLATED_ENV") - }) - It("creates correct command with UseIsolatedEnv false if BOSH_CPI_USE_ISOLATED_ENV is set", func() { - os.Setenv("BOSH_CPI_USE_ISOLATED_ENV", "false") + It("creates correct command with UseIsolatedEnv false if NewCPICmdRunner is initialized with false", func() { + cpiCmdRunner = NewCPICmdRunner(cmdRunner, cpi, logger, false) cmdOutput := CmdOutput{} outputBytes, err := json.Marshal(cmdOutput) Expect(err).NotTo(HaveOccurred()) @@ -109,21 +107,6 @@ var _ = Describe("CpiCmdRunner", func() { Expect(actualCmd.UseIsolatedEnv).To(BeFalse()) }) - It("throws helpful error if the value of BOSH_CPI_USE_ISOLATED_ENV cannot be parsed into a bool", func() { - os.Setenv("BOSH_CPI_USE_ISOLATED_ENV", "falasdse") - cmdOutput := CmdOutput{} - outputBytes, err := json.Marshal(cmdOutput) - Expect(err).NotTo(HaveOccurred()) - - result := fakesys.FakeCmdResult{ - Stdout: string(outputBytes), - ExitStatus: 0, - } - cmdRunner.AddCmdResult("/jobs/cpi/bin/cpi", result) - _, err = cpiCmdRunner.Run(context, "fake-method", apiVersion, "fake-argument-1", "fake-argument-2") - Expect(err).To(HaveOccurred()) - Expect(MatchRegexp("BOSH_CPI_USE_ISOLATED_ENV cannot be parsed", err)) - }) It("creates correct command with stemcell api_version in context", func() { cmdOutput := CmdOutput{} outputBytes, err := json.Marshal(cmdOutput) @@ -145,7 +128,7 @@ var _ = Describe("CpiCmdRunner", func() { Expect(actualCmd.Env).To(Equal(map[string]string{ "BOSH_PACKAGES_DIR": cpi.PackagesDir, "BOSH_JOBS_DIR": cpi.JobsDir, - "PATH": "/usr/local/bin:/usr/bin:/bin:/sbin", + "PATH": os.Getenv("PATH"), })) Expect(actualCmd.UseIsolatedEnv).To(BeTrue()) bytes, err := io.ReadAll(actualCmd.Stdin) diff --git a/cloud/factory.go b/cloud/factory.go index 562352e39..6ff3781d7 100644 --- a/cloud/factory.go +++ b/cloud/factory.go @@ -13,20 +13,23 @@ type Factory interface { } type factory struct { - fs boshsys.FileSystem - cmdRunner boshsys.CmdRunner - logger boshlog.Logger + fs boshsys.FileSystem + cmdRunner boshsys.CmdRunner + logger boshlog.Logger + useIsolatedEnv bool } func NewFactory( fs boshsys.FileSystem, cmdRunner boshsys.CmdRunner, logger boshlog.Logger, + useIsolatedEnv bool, ) Factory { return &factory{ - fs: fs, - cmdRunner: cmdRunner, - logger: logger, + fs: fs, + cmdRunner: cmdRunner, + logger: logger, + useIsolatedEnv: useIsolatedEnv, } } @@ -53,6 +56,6 @@ func (f *factory) NewCloud(installation biinstall.Installation, directorID strin return nil, bosherr.Errorf("Found %d Jobs with a 'bin/cpi' binary. Expected 1.", numberCpiBinariesFound) } - cpiCmdRunner := NewCPICmdRunner(f.cmdRunner, foundCPI, f.logger) + cpiCmdRunner := NewCPICmdRunner(f.cmdRunner, foundCPI, f.logger, f.useIsolatedEnv) return NewCloud(cpiCmdRunner, directorID, stemcellApiVersion, f.logger), nil } diff --git a/cmd/cmd.go b/cmd/cmd.go index 3f0832b6a..48c88282c 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -72,7 +72,7 @@ func (c Cmd) Execute() (cmdErr error) { case *CreateEnvOpts: envProvider := func(manifestPath string, statePath string, vars boshtpl.Variables, op patch.Op) DeploymentPreparer { - return NewEnvFactory(deps, manifestPath, statePath, vars, op, opts.RecreatePersistentDisks, opts.PackageDir).Preparer() + return NewEnvFactory(deps, manifestPath, statePath, vars, op, opts.RecreatePersistentDisks, opts.PackageDir, !opts.AvoidIsolatedEnv).Preparer() } stage := boshui.NewStage(deps.UI, deps.Time, deps.Logger) @@ -80,7 +80,7 @@ func (c Cmd) Execute() (cmdErr error) { case *DeleteEnvOpts: envProvider := func(manifestPath string, statePath string, vars boshtpl.Variables, op patch.Op) DeploymentDeleter { - return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, opts.PackageDir).Deleter() + return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, opts.PackageDir, true).Deleter() } stage := boshui.NewStage(deps.UI, deps.Time, deps.Logger) @@ -88,7 +88,7 @@ func (c Cmd) Execute() (cmdErr error) { case *StopEnvOpts: envProvider := func(manifestPath string, statePath string, vars boshtpl.Variables, op patch.Op) DeploymentStateManager { - return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, "").StateManager() + return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, "", true).StateManager() } stage := boshui.NewStage(deps.UI, deps.Time, deps.Logger) @@ -96,7 +96,7 @@ func (c Cmd) Execute() (cmdErr error) { case *StartEnvOpts: envProvider := func(manifestPath string, statePath string, vars boshtpl.Variables, op patch.Op) DeploymentStateManager { - return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, "").StateManager() + return NewEnvFactory(deps, manifestPath, statePath, vars, op, false, "", true).StateManager() } stage := boshui.NewStage(deps.UI, deps.Time, deps.Logger) diff --git a/cmd/env_factory.go b/cmd/env_factory.go index b54cb77f0..6a76973dd 100644 --- a/cmd/env_factory.go +++ b/cmd/env_factory.go @@ -72,6 +72,7 @@ func NewEnvFactory( manifestOp patch.Op, recreatePersistentDisks bool, packageDir string, + useIsolatedEnv bool, ) *envFactory { f := envFactory{ deps: deps, @@ -117,7 +118,7 @@ func NewEnvFactory( { installerFactory := boshinst.NewInstallerFactory( deps.UI, deps.CmdRunner, deps.Compressor, releaseJobResolver, - deps.UUIDGen, deps.Logger, deps.FS, deps.DigestCreationAlgorithms) + deps.UUIDGen, deps.Logger, useIsolatedEnv, deps.FS, deps.DigestCreationAlgorithms) f.cpiInstaller = bicpirel.CpiInstaller{ ReleaseManager: f.releaseManager, @@ -149,7 +150,7 @@ func NewEnvFactory( f.blobstoreFactory = biblobstore.NewBlobstoreFactory(deps.UUIDGen, deps.FS, deps.Logger) f.deploymentFactory = bidepl.NewFactory(10*time.Second, 500*time.Millisecond) f.agentClientFactory = bihttpagent.NewAgentClientFactory(1*time.Second, deps.Logger) - f.cloudFactory = bicloud.NewFactory(deps.FS, deps.CmdRunner, deps.Logger) + f.cloudFactory = bicloud.NewFactory(deps.FS, deps.CmdRunner, deps.Logger, useIsolatedEnv) } { diff --git a/cmd/opts/opts.go b/cmd/opts/opts.go index 1839e8ea4..90b7485c8 100644 --- a/cmd/opts/opts.go +++ b/cmd/opts/opts.go @@ -197,6 +197,7 @@ type CreateEnvOpts struct { StatePath string `long:"state" value-name:"PATH" description:"State file path"` Recreate bool `long:"recreate" description:"Recreate VM in deployment"` RecreatePersistentDisks bool `long:"recreate-persistent-disks" description:"Recreate persistent disks in the deployment"` + AvoidIsolatedEnv bool `long:"avoid-isolated-environment" short:"I" description:"Compile and run cpi-commands in a clean environment or not"` PackageDir string `long:"package-dir" value-name:"DIR" description:"Package cache location override"` cmd } diff --git a/installation/installer_factory.go b/installation/installer_factory.go index 79e152537..ec597aab4 100644 --- a/installation/installer_factory.go +++ b/installation/installer_factory.go @@ -30,6 +30,7 @@ type installerFactory struct { releaseJobResolver bideplrel.JobResolver uuidGenerator boshuuid.Generator logger boshlog.Logger + useIsolatedEnv bool logTag string fs boshsys.FileSystem digestCreateAlgorithms []boshcrypto.Algorithm @@ -42,6 +43,7 @@ func NewInstallerFactory( releaseJobResolver bideplrel.JobResolver, uuidGenerator boshuuid.Generator, logger boshlog.Logger, + useIsolatedEnv bool, fs boshsys.FileSystem, digestCreateAlgorithms []boshcrypto.Algorithm, ) InstallerFactory { @@ -52,6 +54,7 @@ func NewInstallerFactory( releaseJobResolver: releaseJobResolver, uuidGenerator: uuidGenerator, logger: logger, + useIsolatedEnv: useIsolatedEnv, logTag: "installer", fs: fs, digestCreateAlgorithms: digestCreateAlgorithms, @@ -63,6 +66,7 @@ func (f *installerFactory) NewInstaller(target Target) Installer { target: target, runner: f.runner, logger: f.logger, + useIsolatedEnv: f.useIsolatedEnv, extractor: f.extractor, uuidGenerator: f.uuidGenerator, releaseJobResolver: f.releaseJobResolver, @@ -85,6 +89,7 @@ type installerFactoryContext struct { fs boshsys.FileSystem runner boshsys.CmdRunner logger boshlog.Logger + useIsolatedEnv bool extractor boshcmd.Compressor uuidGenerator boshuuid.Generator releaseJobResolver bideplrel.JobResolver @@ -148,6 +153,7 @@ func (c *installerFactoryContext) InstallationStatePackageCompiler() bistatepkg. c.CompiledPackageRepo(), c.BlobExtractor(), c.logger, + c.useIsolatedEnv, ) return c.packageCompiler diff --git a/installation/pkg/compiler.go b/installation/pkg/compiler.go index dfd7b2f26..2ed653263 100644 --- a/installation/pkg/compiler.go +++ b/installation/pkg/compiler.go @@ -26,6 +26,7 @@ type compiler struct { blobExtractor blobextract.Extractor logger boshlog.Logger logTag string + useIsolatedEnv bool } func NewPackageCompiler( @@ -37,6 +38,7 @@ func NewPackageCompiler( compiledPackageRepo bistatepkg.CompiledPackageRepo, blobExtractor blobextract.Extractor, logger boshlog.Logger, + useIsolatedEnv bool, ) bistatepkg.Compiler { return &compiler{ runner: runner, @@ -48,6 +50,7 @@ func NewPackageCompiler( blobExtractor: blobExtractor, logger: logger, logTag: "packageCompiler", + useIsolatedEnv: useIsolatedEnv, } } @@ -105,7 +108,7 @@ func (c *compiler) Compile(pkg birelpkg.Compilable) (bistatepkg.CompiledPackageR "PATH": os.Getenv("PATH"), "LD_LIBRARY_PATH": os.Getenv("LD_LIBRARY_PATH"), }, - UseIsolatedEnv: true, + UseIsolatedEnv: c.useIsolatedEnv, WorkingDir: packageSrcDir, } diff --git a/installation/pkg/compiler_test.go b/installation/pkg/compiler_test.go index acf666b0f..35a55688c 100644 --- a/installation/pkg/compiler_test.go +++ b/installation/pkg/compiler_test.go @@ -37,6 +37,7 @@ var _ = Describe("PackageCompiler", func() { var ( logger boshlog.Logger + useIsolatedEnv bool compiler bistatepkg.Compiler runner *fakesys.FakeCmdRunner pkg *birelpkg.Package @@ -54,6 +55,8 @@ var _ = Describe("PackageCompiler", func() { BeforeEach(func() { logger = boshlog.NewLogger(boshlog.LevelNone) + useIsolatedEnv = true + packagesDir = "fake-packages-dir" runner = fakesys.NewFakeCmdRunner() fs = fakesys.NewFakeFileSystem() @@ -83,6 +86,7 @@ var _ = Describe("PackageCompiler", func() { mockCompiledPackageRepo, fakeExtractor, logger, + useIsolatedEnv, ) }) @@ -186,6 +190,46 @@ var _ = Describe("PackageCompiler", func() { Expect(runner.RunComplexCommands[0]).To(Equal(expectedCmd)) }) + Context("when useIsolatedEnv is set to false", func() { + BeforeEach(func() { + useIsolatedEnv = false + compiler = NewPackageCompiler( + runner, + packagesDir, + fs, + compressor, + blobstore, + mockCompiledPackageRepo, + fakeExtractor, + logger, + useIsolatedEnv, + ) + }) + + It("runs the packaging script with UseIsolatedEnv set to false", func() { + _, _, err := compiler.Compile(pkg) + Expect(err).ToNot(HaveOccurred()) + + expectedCmd := boshsys.Command{ + Name: "bash", + Args: []string{"-x", "packaging"}, + Env: map[string]string{ + "BOSH_COMPILE_TARGET": "/pkg-dir", + "BOSH_INSTALL_TARGET": installPath, + "BOSH_PACKAGE_NAME": "pkg1-name", + "BOSH_PACKAGES_DIR": packagesDir, + "PATH": os.Getenv("PATH"), + "LD_LIBRARY_PATH": os.Getenv("LD_LIBRARY_PATH"), + }, + UseIsolatedEnv: false, + WorkingDir: "/pkg-dir", + } + + Expect(runner.RunComplexCommands).To(HaveLen(1)) + Expect(runner.RunComplexCommands[0]).To(Equal(expectedCmd)) + }) + }) + It("compresses the compiled package", func() { _, _, err := compiler.Compile(pkg) Expect(err).ToNot(HaveOccurred())