From 0c59fab5482df2ccf9d07301e2f66d4895716da6 Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 16:01:17 +0000 Subject: [PATCH 1/8] Change message about embed directory to be more clear --- winfsinjector/application.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winfsinjector/application.go b/winfsinjector/application.go index 2db235b0..ef30ae59 100644 --- a/winfsinjector/application.go +++ b/winfsinjector/application.go @@ -71,7 +71,7 @@ func (a Application) Run(inputTile, outputTile, registry, workingDir string) err embeddedReleaseDir := filepath.Join(extractedTileDir, "embed/windowsfs-release") if _, err := os.Stat(embeddedReleaseDir); os.IsNotExist(err) { - fmt.Println("The file system has already been injected in the tile; skipping injection") + fmt.Println("No file system found or the file system has already been injected in the tile; skipping injection") return nil } releaseVersion, err := a.extractReleaseVersion(embeddedReleaseDir) From 42a2bf39efcbbca86ba13fbe2b8f9f2ba908a364 Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 16:02:04 +0000 Subject: [PATCH 2/8] Add argument to preserve files extracted from the input tile --- main.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/main.go b/main.go index bc4f377b..f1753f59 100644 --- a/main.go +++ b/main.go @@ -14,18 +14,20 @@ import ( const usageText = `winfs-injector injects the Windows 2016 root file system into the Windows 2016 Runtime Tile. Usage: winfs-injector - --input-tile, -i path to input tile (example: /path/to/input.pivotal) - --output-tile, -o path to output tile (example: /path/to/output.pivotal) - --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") - --help, -h prints this usage information + --input-tile, -i path to input tile (example: /path/to/input.pivotal) + --output-tile, -o path to output tile (example: /path/to/output.pivotal) + --preserve-extracted, -p preserve the files created during the tile extraction process (useful for debugging) + --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") + --help, -h prints this usage information ` func main() { var arguments struct { - InputTile string `short:"i" long:"input-tile"` - OutputTile string `short:"o" long:"output-tile"` - Registry string `short:"r" long:"registry" default:"https://registry.hub.docker.com"` - Help bool `short:"h" long:"help"` + InputTile string `short:"i" long:"input-tile"` + OutputTile string `short:"o" long:"output-tile"` + PreserveExtracted bool `short:"p" long:"preserve-extracted"` + Registry string `short:"r" long:"registry" default:"https://registry.hub.docker.com"` + Help bool `short:"h" long:"help"` } _, err := jhanda.Parse(&arguments, os.Args[1:]) @@ -46,7 +48,11 @@ func main() { if err != nil { log.Fatal(err) } - defer os.RemoveAll(wd) + + fmt.Fprintf(os.Stdout, "tile extraction directory: %s\n", wd) + if !arguments.PreserveExtracted { + defer os.RemoveAll(wd) + } app := winfsinjector.NewApplication(releaseCreator, tileInjector, zipper) From a70a69854ad36a7a00934ac242006208ccb9296e Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 16:10:07 +0000 Subject: [PATCH 3/8] Replace uses of deprecated ioutil with appropriate io/os fuctions --- main.go | 3 +-- tile/tile_injector.go | 6 +++--- tile/tile_injector_test.go | 17 ++++++++--------- tile/zipper_test.go | 18 +++++++++--------- winfsinjector/application.go | 3 +-- winfsinjector/application_test.go | 6 +++--- winfsinjector/exports_test.go | 3 +-- winfsinjector/release_creator.go | 3 +-- 8 files changed, 27 insertions(+), 32 deletions(-) diff --git a/main.go b/main.go index f1753f59..99861fa6 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "log" "os" @@ -44,7 +43,7 @@ func main() { var zipper = tile.NewZipper() var releaseCreator = winfsinjector.ReleaseCreator{} - wd, err := ioutil.TempDir("", "") + wd, err := os.MkdirTemp("", "") if err != nil { log.Fatal(err) } diff --git a/tile/tile_injector.go b/tile/tile_injector.go index b189d790..f7696f19 100644 --- a/tile/tile_injector.go +++ b/tile/tile_injector.go @@ -2,7 +2,7 @@ package tile import ( "fmt" - "io/ioutil" + "io" "os" "path/filepath" @@ -37,7 +37,7 @@ func (i TileInjector) AddReleaseToMetadata(releasePath, releaseName, releaseVers } defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) if err != nil { return err } @@ -59,5 +59,5 @@ func (i TileInjector) AddReleaseToMetadata(releasePath, releaseName, releaseVers return err } - return ioutil.WriteFile(metadataFilePath, contents, 0644) + return os.WriteFile(metadataFilePath, contents, 0644) } diff --git a/tile/tile_injector_test.go b/tile/tile_injector_test.go index bfacd52e..b679299e 100644 --- a/tile/tile_injector_test.go +++ b/tile/tile_injector_test.go @@ -1,7 +1,6 @@ package tile_test import ( - "io/ioutil" "os" "path/filepath" @@ -30,11 +29,11 @@ var _ = Describe("TileInjector", func() { releaseVersion = "1.2.3" var err error - baseTmpDir, err = ioutil.TempDir("", "") + baseTmpDir, err = os.MkdirTemp("", "") Expect(err).NotTo(HaveOccurred()) releasePath = filepath.Join(baseTmpDir, "some-release.tgz") - err = ioutil.WriteFile(releasePath, []byte("something"), 0644) + err = os.WriteFile(releasePath, []byte("something"), 0644) Expect(err).NotTo(HaveOccurred()) tileDir = filepath.Join(baseTmpDir, "some-tile") @@ -42,18 +41,18 @@ var _ = Describe("TileInjector", func() { Expect(err).NotTo(HaveOccurred()) initialMetadataPath := filepath.Join("fixtures", "initial_metadata.yml") - initialMetadataContents, err := ioutil.ReadFile(initialMetadataPath) + initialMetadataContents, err := os.ReadFile(initialMetadataPath) Expect(err).NotTo(HaveOccurred()) err = os.Mkdir(filepath.Join(tileDir, "metadata"), 0755) Expect(err).NotTo(HaveOccurred()) metadataPath = filepath.Join(tileDir, "metadata", "some-product-metadata.yml") - err = ioutil.WriteFile(metadataPath, initialMetadataContents, 0644) + err = os.WriteFile(metadataPath, initialMetadataContents, 0644) Expect(err).NotTo(HaveOccurred()) expectedMetadataPath := filepath.Join("fixtures", "expected_metadata.yml") - expectedMetadataContents, err := ioutil.ReadFile(expectedMetadataPath) + expectedMetadataContents, err := os.ReadFile(expectedMetadataPath) Expect(err).NotTo(HaveOccurred()) err = yaml.Unmarshal(expectedMetadataContents, &expectedMetadata) @@ -71,7 +70,7 @@ var _ = Describe("TileInjector", func() { err := tileInjector.AddReleaseToMetadata(releasePath, releaseName, releaseVersion, tileDir) Expect(err).NotTo(HaveOccurred()) - rawMetadata, err := ioutil.ReadFile(metadataPath) + rawMetadata, err := os.ReadFile(metadataPath) Expect(err).NotTo(HaveOccurred()) var actualMetadata tile.Metadata @@ -97,7 +96,7 @@ var _ = Describe("TileInjector", func() { }) It("returns an error when metadata contains malformed yaml", func() { - err := ioutil.WriteFile(metadataPath, []byte("%%%%"), 0644) + err := os.WriteFile(metadataPath, []byte("%%%%"), 0644) Expect(err).NotTo(HaveOccurred()) err = tileInjector.AddReleaseToMetadata(releasePath, releaseName, releaseVersion, tileDir) @@ -106,7 +105,7 @@ var _ = Describe("TileInjector", func() { It("returns an error when multiple yaml files exist in the metadata directory", func() { secondMetadataPath := filepath.Join(filepath.Dir(metadataPath), "second.yml") - err := ioutil.WriteFile(secondMetadataPath, []byte("{}"), 0644) + err := os.WriteFile(secondMetadataPath, []byte("{}"), 0644) Expect(err).NotTo(HaveOccurred()) err = tileInjector.AddReleaseToMetadata(releasePath, releaseName, releaseVersion, tileDir) diff --git a/tile/zipper_test.go b/tile/zipper_test.go index 0f60dcd0..1e01f972 100644 --- a/tile/zipper_test.go +++ b/tile/zipper_test.go @@ -2,7 +2,7 @@ package tile_test import ( "archive/zip" - "io/ioutil" + "io" "os" "path/filepath" @@ -23,19 +23,19 @@ var _ = Describe("Zipper", func() { zipper = tile.NewZipper() var err error - srcDir, err = ioutil.TempDir("", "") + srcDir, err = os.MkdirTemp("", "") Expect(err).NotTo(HaveOccurred()) - zipFile, err = ioutil.TempFile("", "") + zipFile, err = os.CreateTemp("", "") Expect(err).NotTo(HaveOccurred()) - err = ioutil.WriteFile(filepath.Join(srcDir, "top-level-file"), []byte("foo"), os.FileMode(0644)) + err = os.WriteFile(filepath.Join(srcDir, "top-level-file"), []byte("foo"), os.FileMode(0644)) Expect(err).NotTo(HaveOccurred()) err = os.Mkdir(filepath.Join(srcDir, "second-level-dir"), os.FileMode(0755)) Expect(err).NotTo(HaveOccurred()) - err = ioutil.WriteFile(filepath.Join(srcDir, "second-level-dir", "second-level-file"), []byte("bar"), os.FileMode(0644)) + err = os.WriteFile(filepath.Join(srcDir, "second-level-dir", "second-level-file"), []byte("bar"), os.FileMode(0644)) Expect(err).NotTo(HaveOccurred()) }) @@ -60,8 +60,8 @@ var _ = Describe("Zipper", func() { Expect(actualZip.File).To(HaveLen(3)) fileAssertions := map[string]string{ - "top-level-file": "foo", - "second-level-dir": "", + "top-level-file": "foo", + "second-level-dir": "", filepath.Join("second-level-dir", "second-level-file"): "bar", } @@ -71,7 +71,7 @@ var _ = Describe("Zipper", func() { defer openedFile.Close() - fileContents, err := ioutil.ReadAll(openedFile) + fileContents, err := io.ReadAll(openedFile) Expect(err).NotTo(HaveOccurred()) Expect(string(fileContents)).To(Equal(fileAssertions[f.Name])) } @@ -105,7 +105,7 @@ var _ = Describe("Zipper", func() { inputTile = filepath.Join("fixtures", "test.zip") var err error - destDir, err = ioutil.TempDir("", "") + destDir, err = os.MkdirTemp("", "") Expect(err).NotTo(HaveOccurred()) }) diff --git a/winfsinjector/application.go b/winfsinjector/application.go index ef30ae59..b541cb63 100644 --- a/winfsinjector/application.go +++ b/winfsinjector/application.go @@ -3,7 +3,6 @@ package winfsinjector import ( "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -15,7 +14,7 @@ import ( ) var ( - readFile = ioutil.ReadFile + readFile = os.ReadFile removeAll = os.RemoveAll ) diff --git a/winfsinjector/application_test.go b/winfsinjector/application_test.go index d45614d9..f5723d70 100644 --- a/winfsinjector/application_test.go +++ b/winfsinjector/application_test.go @@ -3,7 +3,7 @@ package winfsinjector_test import ( "errors" "fmt" - "io/ioutil" + "io" "os" "path/filepath" @@ -39,7 +39,7 @@ var _ = Describe("application", func() { outputTile = "/path/to/output/tile" registry = "/path/to/docker/registry" - workingDir, err = ioutil.TempDir("", "") + workingDir, err = os.MkdirTemp("", "") Expect(err).ToNot(HaveOccurred()) embedFilePath := fmt.Sprintf("%s/extracted-tile/embed", workingDir) @@ -246,7 +246,7 @@ windows2019fs/windows2016fs-MISSING-IMAGE-TAG.tgz: w.Close() Expect(err).ToNot(HaveOccurred()) - stdout, _ := ioutil.ReadAll(r) + stdout, _ := io.ReadAll(r) Expect(string(stdout)).To(ContainSubstring("The file system has already been injected in the tile; skipping injection")) }) }) diff --git a/winfsinjector/exports_test.go b/winfsinjector/exports_test.go index 34c982b6..5498dbcf 100644 --- a/winfsinjector/exports_test.go +++ b/winfsinjector/exports_test.go @@ -1,7 +1,6 @@ package winfsinjector import ( - "io/ioutil" "os" ) @@ -10,7 +9,7 @@ func SetReadFile(f func(string) ([]byte, error)) { } func ResetReadFile() { - readFile = ioutil.ReadFile + readFile = os.ReadFile } func SetRemoveAll(f func(string) error) { diff --git a/winfsinjector/release_creator.go b/winfsinjector/release_creator.go index b1ab41c9..d60ccd82 100644 --- a/winfsinjector/release_creator.go +++ b/winfsinjector/release_creator.go @@ -1,7 +1,6 @@ package winfsinjector import ( - "io/ioutil" "log" "os" "path/filepath" @@ -49,7 +48,7 @@ func (rc ReleaseCreator) CreateRelease(releaseName, imageName, releaseDir, tarba } // bosh create-release adds ~7GB of temp files that should be cleaned up - tmpDir, err := ioutil.TempDir("", "winfs-create-release") + tmpDir, err := os.MkdirTemp("", "winfs-create-release") if err != nil { return err } From 57777d8ba9d02bcaaca3e5a6576071644f865b27 Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 16:18:19 +0000 Subject: [PATCH 4/8] Update tests to match new argument and embed info message --- acceptance/main_test.go | 9 +++++---- winfsinjector/application_test.go | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/acceptance/main_test.go b/acceptance/main_test.go index 6d471a9d..2c3fce10 100644 --- a/acceptance/main_test.go +++ b/acceptance/main_test.go @@ -52,10 +52,11 @@ var _ = Describe("acceptance", func() { Expect(err).NotTo(HaveOccurred()) Eventually(session).Should(gexec.Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(` - --input-tile, -i path to input tile (example: /path/to/input.pivotal) - --output-tile, -o path to output tile (example: /path/to/output.pivotal) - --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") - --help, -h prints this usage information`)) + --input-tile, -i path to input tile (example: /path/to/input.pivotal) + --output-tile, -o path to output tile (example: /path/to/output.pivotal) + --preserve-extracted, -p preserve the files created during the tile extraction process (useful for debugging) + --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") + --help, -h prints this usage information`)) }) }) }) diff --git a/winfsinjector/application_test.go b/winfsinjector/application_test.go index f5723d70..fa94ee2f 100644 --- a/winfsinjector/application_test.go +++ b/winfsinjector/application_test.go @@ -247,7 +247,7 @@ windows2019fs/windows2016fs-MISSING-IMAGE-TAG.tgz: Expect(err).ToNot(HaveOccurred()) stdout, _ := io.ReadAll(r) - Expect(string(stdout)).To(ContainSubstring("The file system has already been injected in the tile; skipping injection")) + Expect(string(stdout)).To(ContainSubstring("No file system found or the file system has already been injected in the tile; skipping injection")) }) }) From e5979ac61d49d2ae991559f823a486c2e094e28e Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 16:46:50 +0000 Subject: [PATCH 5/8] Fix whitespace for help message --- acceptance/main_test.go | 8 ++++---- main.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/acceptance/main_test.go b/acceptance/main_test.go index 2c3fce10..d1963784 100644 --- a/acceptance/main_test.go +++ b/acceptance/main_test.go @@ -52,11 +52,11 @@ var _ = Describe("acceptance", func() { Expect(err).NotTo(HaveOccurred()) Eventually(session).Should(gexec.Exit(0)) Expect(string(session.Out.Contents())).To(ContainSubstring(` - --input-tile, -i path to input tile (example: /path/to/input.pivotal) - --output-tile, -o path to output tile (example: /path/to/output.pivotal) + --input-tile, -i path to input tile (example: /path/to/input.pivotal) + --output-tile, -o path to output tile (example: /path/to/output.pivotal) --preserve-extracted, -p preserve the files created during the tile extraction process (useful for debugging) - --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") - --help, -h prints this usage information`)) + --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") + --help, -h prints this usage information`)) }) }) }) diff --git a/main.go b/main.go index 99861fa6..eab93bd9 100644 --- a/main.go +++ b/main.go @@ -13,11 +13,11 @@ import ( const usageText = `winfs-injector injects the Windows 2016 root file system into the Windows 2016 Runtime Tile. Usage: winfs-injector - --input-tile, -i path to input tile (example: /path/to/input.pivotal) - --output-tile, -o path to output tile (example: /path/to/output.pivotal) + --input-tile, -i path to input tile (example: /path/to/input.pivotal) + --output-tile, -o path to output tile (example: /path/to/output.pivotal) --preserve-extracted, -p preserve the files created during the tile extraction process (useful for debugging) - --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") - --help, -h prints this usage information + --registry, -r path to docker registry (example: /path/to/registry, default: "https://registry.hub.docker.com") + --help, -h prints this usage information ` func main() { From a73f645a48c5c02e088261db421d95f9d938c11e Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 17:19:38 +0000 Subject: [PATCH 6/8] Only print tile extraction directory when --preserve-extracted is set --- main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index eab93bd9..afea76a2 100644 --- a/main.go +++ b/main.go @@ -48,8 +48,9 @@ func main() { log.Fatal(err) } - fmt.Fprintf(os.Stdout, "tile extraction directory: %s\n", wd) - if !arguments.PreserveExtracted { + if arguments.PreserveExtracted { + fmt.Fprintf(os.Stdout, "tile extraction directory: %s\n", wd) + } else { defer os.RemoveAll(wd) } From 254244156757e3ac8a3e400954de91c26f69eec8 Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 19:50:04 +0000 Subject: [PATCH 7/8] Split the checks for existing file system and missing file system --- winfsinjector/application.go | 10 +++++++++- winfsinjector/application_test.go | 29 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/winfsinjector/application.go b/winfsinjector/application.go index b541cb63..686f4a9c 100644 --- a/winfsinjector/application.go +++ b/winfsinjector/application.go @@ -68,11 +68,19 @@ func (a Application) Run(inputTile, outputTile, registry, workingDir string) err return err } + injectedReleaseTarball := filepath.Join(extractedTileDir, "releases/windows*fs*") + matches, _ := filepath.Glob(injectedReleaseTarball) + if len(matches) > 0 { + fmt.Println("File system has already been injected in the tile; skipping injection") + return nil + } + embeddedReleaseDir := filepath.Join(extractedTileDir, "embed/windowsfs-release") if _, err := os.Stat(embeddedReleaseDir); os.IsNotExist(err) { - fmt.Println("No file system found or the file system has already been injected in the tile; skipping injection") + fmt.Println("No file system found; skipping injection") return nil } + releaseVersion, err := a.extractReleaseVersion(embeddedReleaseDir) if err != nil { return err diff --git a/winfsinjector/application_test.go b/winfsinjector/application_test.go index fa94ee2f..cbb56c69 100644 --- a/winfsinjector/application_test.go +++ b/winfsinjector/application_test.go @@ -228,6 +228,33 @@ windows2019fs/windows2016fs-MISSING-IMAGE-TAG.tgz: }) }) + Context("when windowsfs-release is already embedded in the tile", func() { + BeforeEach(func() { + releaseDir := fmt.Sprintf("%s/extracted-tile/releases", workingDir) + os.MkdirAll(releaseDir, os.ModePerm) + + tarballPath := filepath.Join(releaseDir, "/windows2019fs-9.3.6.tgz") + os.WriteFile(tarballPath, []byte("windows"), 0644) + }) + + It("does not return an error and exits", func() { + var err error + r, w, _ := os.Pipe() + tmp := os.Stdout + defer func() { + os.Stdout = tmp + }() + os.Stdout = w + + err = app.Run(inputTile, outputTile, registry, workingDir) + w.Close() + + Expect(err).ToNot(HaveOccurred()) + stdout, _ := io.ReadAll(r) + Expect(string(stdout)).To(ContainSubstring("File system has already been injected in the tile; skipping injection")) + }) + }) + Context("when windowsfs-release is not embedded in the tile from being previously hydrated", func() { BeforeEach(func() { embedFilePath := fmt.Sprintf("%s/extracted-tile/embed", workingDir) @@ -247,7 +274,7 @@ windows2019fs/windows2016fs-MISSING-IMAGE-TAG.tgz: Expect(err).ToNot(HaveOccurred()) stdout, _ := io.ReadAll(r) - Expect(string(stdout)).To(ContainSubstring("No file system found or the file system has already been injected in the tile; skipping injection")) + Expect(string(stdout)).To(ContainSubstring("No file system found; skipping injection")) }) }) From 4998411e5e330250ead106743cab87224727574d Mon Sep 17 00:00:00 2001 From: Brandon Roberson Date: Mon, 31 Jul 2023 20:42:50 +0000 Subject: [PATCH 8/8] Added test for --preserve-extracted flag --- acceptance/main_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acceptance/main_test.go b/acceptance/main_test.go index d1963784..b8506534 100644 --- a/acceptance/main_test.go +++ b/acceptance/main_test.go @@ -46,6 +46,14 @@ var _ = Describe("acceptance", func() { Expect(string(session.Err.Contents())).To(ContainSubstring("--output-tile is required")) }) + It("prints the tile extraction directory when the preserve-extracted flag is provided", func() { + cmd = exec.Command(winfsInjector, "-p") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(session).Should(gexec.Exit(1)) + Expect(string(session.Out.Contents())).To(ContainSubstring("tile extraction directory")) + }) + It("prints usage when the help flag is provided", func() { cmd = exec.Command(winfsInjector, "--help") session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)