From b6e3f6f6c07d70abb09454e94f7d6bffb0655e3a Mon Sep 17 00:00:00 2001 From: Kadukuntla Poornima Date: Wed, 24 Jun 2026 11:48:28 +0000 Subject: [PATCH 1/2] feat(packer): restore packer-manifest.json state across blueprint regenerations --- pkg/modulewriter/modulewriter_test.go | 38 +++++++++++++++++++++ pkg/modulewriter/packerwriter.go | 48 ++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/pkg/modulewriter/modulewriter_test.go b/pkg/modulewriter/modulewriter_test.go index 0492ba253e..6a33025a0c 100644 --- a/pkg/modulewriter/modulewriter_test.go +++ b/pkg/modulewriter/modulewriter_test.go @@ -179,6 +179,44 @@ func (s *zeroSuite) TestRestoreTfState(c *C) { c.Check(err, IsNil) } +func (s *zeroSuite) TestRestorePackerState(c *C) { + // set up dir structure + // + // └── test_dir + // ├── .ghpc + // └── previous_deployment_groups + // └── packer_group + // └── image + // └── packer-manifest.json + // └── packer_group + // └── image + depDir := c.MkDir() + groupName := "packer_group" + subPath := "image" + manifestContent := `{"builds": [{"artifact_id": "my-image"}]}` + + prevGroup := filepath.Join(HiddenGhpcDir(depDir), prevGroupDirName, groupName, subPath) + curGroup := filepath.Join(depDir, groupName, subPath) + prevManifest := filepath.Join(prevGroup, packerManifestFileName) + + c.Assert(os.MkdirAll(prevGroup, 0755), IsNil) + c.Assert(os.MkdirAll(curGroup, 0755), IsNil) + c.Assert(os.WriteFile(prevManifest, []byte(manifestContent), 0644), IsNil) + + testWriter := PackerWriter{} + c.Check(testWriter.restoreState(depDir), IsNil) + + // check manifest file was copied to current resource group dir + curManifest := filepath.Join(curGroup, packerManifestFileName) + _, err := os.Stat(curManifest) + c.Check(err, IsNil) + + // check content is identical + gotContent, err := os.ReadFile(curManifest) + c.Check(err, IsNil) + c.Check(string(gotContent), Equals, manifestContent) +} + func TestGetTypeTokensRelaxed(t *testing.T) { type test struct { input cty.Type diff --git a/pkg/modulewriter/packerwriter.go b/pkg/modulewriter/packerwriter.go index eac4094194..1fe03a89c7 100644 --- a/pkg/modulewriter/packerwriter.go +++ b/pkg/modulewriter/packerwriter.go @@ -19,9 +19,11 @@ package modulewriter import ( "fmt" "io" + "os" "path/filepath" "hpc-toolkit/pkg/config" + "hpc-toolkit/pkg/logging" "github.com/zclconf/go-cty/cty" ) @@ -85,8 +87,52 @@ func (w PackerWriter) writeGroup( return nil } +const packerManifestFileName = "packer-manifest.json" + func (w PackerWriter) restoreState(deploymentDir string) error { - // TODO: restore packer-manifest.json if it exists + prevGroupPath := filepath.Join(HiddenGhpcDir(deploymentDir), prevGroupDirName) + + // If the previous deployment groups directory doesn't exist, there is nothing to restore. + if _, err := os.Stat(prevGroupPath); os.IsNotExist(err) { + return nil + } + + err := filepath.WalkDir(prevGroupPath, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() || d.Name() != packerManifestFileName { + return nil + } + + // Found a packer-manifest.json. Determine its relative path from prevGroupPath. + relPath, err := filepath.Rel(prevGroupPath, path) + if err != nil { + return fmt.Errorf("failed to get relative path for %s: %w", path, err) + } + + dest := filepath.Join(deploymentDir, relPath) + + // Ensure the destination directory exists before writing (it should have been created by writeGroup). + if _, err := os.Stat(filepath.Dir(dest)); err == nil { + bytesRead, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read previous packer manifest %s: %w", path, err) + } + err = os.WriteFile(dest, bytesRead, 0644) + if err != nil { + return fmt.Errorf("failed to write previous packer manifest %s: %w", dest, err) + } + logging.Info("Restored packer manifest to %s", dest) + } + + return nil + }) + + if err != nil { + return fmt.Errorf("error trying to restore packer manifests: %w", err) + } + return nil } From 44f307532813d66c975fba80c3f4e9411b948f58 Mon Sep 17 00:00:00 2001 From: Kadukuntla Poornima Date: Wed, 24 Jun 2026 12:31:42 +0000 Subject: [PATCH 2/2] . Change-Id: I68063de5dfc0a3c9ea01c7769febf5a1cc2f0097 --- pkg/modulewriter/packerwriter.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pkg/modulewriter/packerwriter.go b/pkg/modulewriter/packerwriter.go index 1fe03a89c7..75b41a948b 100644 --- a/pkg/modulewriter/packerwriter.go +++ b/pkg/modulewriter/packerwriter.go @@ -114,17 +114,23 @@ func (w PackerWriter) restoreState(deploymentDir string) error { dest := filepath.Join(deploymentDir, relPath) // Ensure the destination directory exists before writing (it should have been created by writeGroup). - if _, err := os.Stat(filepath.Dir(dest)); err == nil { - bytesRead, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read previous packer manifest %s: %w", path, err) - } - err = os.WriteFile(dest, bytesRead, 0644) - if err != nil { - return fmt.Errorf("failed to write previous packer manifest %s: %w", dest, err) + _, err = os.Stat(filepath.Dir(dest)) + if err != nil { + if os.IsNotExist(err) { + return nil } - logging.Info("Restored packer manifest to %s", dest) + return fmt.Errorf("failed to stat destination directory %s: %w", filepath.Dir(dest), err) + } + + bytesRead, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read previous packer manifest %s: %w", path, err) + } + err = os.WriteFile(dest, bytesRead, 0644) + if err != nil { + return fmt.Errorf("failed to write previous packer manifest %s: %w", dest, err) } + logging.Info("Restored packer manifest to %s", dest) return nil })