diff --git a/.gitignore b/.gitignore index de67df5e..ed88a340 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ # Go workspace file go.work + +# IDE +.idea \ No newline at end of file diff --git a/pkg/build/build.go b/pkg/build/build.go index d1e43a59..1e76cb97 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -3,6 +3,7 @@ package build import ( _ "embed" "fmt" + "io" "os" "path/filepath" "text/template" @@ -50,6 +51,11 @@ func (b *Builder) Build() error { return fmt.Errorf("generating combustion script: %w", err) } + err = b.copyRPMs() + if err != nil { + return fmt.Errorf("copying RPMs over: %w", err) + } + switch b.imageConfig.Image.ImageType { case config.ImageTypeISO: err = b.buildIsoImage() @@ -202,3 +208,24 @@ func (b *Builder) generateBaseImageFilename() string { filename := filepath.Join(b.buildConfig.ImageConfigDir, "images", b.imageConfig.Image.BaseImage) return filename } + +func copyFile(sourcePath string, destPath string) error { + sourceFile, err := os.Open(sourcePath) + if err != nil { + return fmt.Errorf("opening file from source path: %w", err) + } + defer sourceFile.Close() + + destFile, err := os.Create(destPath) + if err != nil { + return fmt.Errorf("creating file at dest path: %w", err) + } + defer destFile.Close() + + _, err = io.Copy(destFile, sourceFile) + if err != nil { + return fmt.Errorf("copying file from source path to dest path: %w", err) + } + + return nil +} diff --git a/pkg/build/rpm.go b/pkg/build/rpm.go new file mode 100644 index 00000000..48e37d44 --- /dev/null +++ b/pkg/build/rpm.go @@ -0,0 +1,58 @@ +package build + +import ( + "fmt" + "os" + "path/filepath" +) + +func (b *Builder) getRPMFileNames(rpmSourceDir string) ([]string, error) { + var rpmFileNames []string + + rpms, err := os.ReadDir(rpmSourceDir) + if err != nil { + return nil, fmt.Errorf("reading rpm source dir: %w", err) + } + + for _, rpmFile := range rpms { + if filepath.Ext(rpmFile.Name()) == ".rpm" { + rpmFileNames = append(rpmFileNames, rpmFile.Name()) + } + } + + if len(rpmFileNames) == 0 { + return nil, fmt.Errorf("no rpms found") + } + + return rpmFileNames, nil +} + +func (b *Builder) copyRPMs() error { + rpmSourceDir := filepath.Join(b.buildConfig.ImageConfigDir, "rpms") + // Only proceed with copying the RPMs if the directory exists + _, err := os.Stat(rpmSourceDir) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return fmt.Errorf("checking for rpm directory at %s: %w", rpmSourceDir, err) + } + rpmDestDir := b.combustionDir + + rpmFileNames, err := b.getRPMFileNames(rpmSourceDir) + if err != nil { + return fmt.Errorf("getting rpm file names: %w", err) + } + + for _, rpm := range rpmFileNames { + sourcePath := filepath.Join(rpmSourceDir, rpm) + destPath := filepath.Join(rpmDestDir, rpm) + + err = copyFile(sourcePath, destPath) + if err != nil { + return fmt.Errorf("copying file %s: %w", sourcePath, err) + } + } + + return nil +} diff --git a/pkg/build/rpm_test.go b/pkg/build/rpm_test.go new file mode 100644 index 00000000..b5420247 --- /dev/null +++ b/pkg/build/rpm_test.go @@ -0,0 +1,125 @@ +package build + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/suse-edge/edge-image-builder/pkg/config" +) + +func TestGetRPMFileNames(t *testing.T) { + // Setup + bc := config.BuildConfig{ + ImageConfigDir: "../config/testdata", + } + builder := New(nil, &bc) + err := builder.prepareBuildDir() + require.NoError(t, err) + defer os.Remove(builder.eibBuildDir) + + rpmSourceDir := filepath.Join(builder.buildConfig.ImageConfigDir, "rpms") + + file1Path := filepath.Join(rpmSourceDir, "rpm1.rpm") + defer os.Remove(file1Path) + file1, err := os.Create(file1Path) + require.NoError(t, err) + + file2Path := filepath.Join(rpmSourceDir, "rpm2.rpm") + defer os.Remove(file2Path) + file2, err := os.Create(file2Path) + require.NoError(t, err) + + // Test + rpmFileNames, err := builder.getRPMFileNames(rpmSourceDir) + + // Verify + require.NoError(t, err) + + assert.Contains(t, rpmFileNames, "rpm1.rpm") + assert.Contains(t, rpmFileNames, "rpm2.rpm") + + // Cleanup + assert.NoError(t, file1.Close()) + assert.NoError(t, file2.Close()) +} + +func TestCopyRPMs(t *testing.T) { + // Setup + bc := config.BuildConfig{ + ImageConfigDir: "../config/testdata", + } + builder := New(nil, &bc) + err := builder.prepareBuildDir() + require.NoError(t, err) + defer os.Remove(builder.eibBuildDir) + + rpmSourceDir := filepath.Join(builder.buildConfig.ImageConfigDir, "rpms") + rpmDestDir := builder.combustionDir + + file1Path := filepath.Join(rpmSourceDir, "rpm1.rpm") + defer os.Remove(file1Path) + file1, err := os.Create(file1Path) + require.NoError(t, err) + + file2Path := filepath.Join(rpmSourceDir, "rpm2.rpm") + defer os.Remove(file2Path) + file2, err := os.Create(file2Path) + require.NoError(t, err) + + // Test + err = builder.copyRPMs() + + // Verify + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(rpmDestDir, "rpm1.rpm")) + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(rpmDestDir, "rpm2.rpm")) + require.NoError(t, err) + + // Cleanup + assert.NoError(t, file1.Close()) + assert.NoError(t, file2.Close()) +} + +func TestGetRPMFileNamesNoRPMs(t *testing.T) { + // Setup + bc := config.BuildConfig{ + ImageConfigDir: "../config/testdata", + } + builder := New(nil, &bc) + err := builder.prepareBuildDir() + require.NoError(t, err) + defer os.Remove(builder.eibBuildDir) + + rpmSourceDir := filepath.Join(builder.buildConfig.ImageConfigDir, "rpms") + + // Test + rpmFileNames, err := builder.getRPMFileNames(rpmSourceDir) + + // Verify + require.ErrorContains(t, err, "no rpms found") + + assert.Empty(t, rpmFileNames) +} + +func TestCopyRPMsNoRPMDir(t *testing.T) { + // Setup + bc := config.BuildConfig{ + ImageConfigDir: "../config/ThisDirDoesNotExist", + } + builder := New(nil, &bc) + err := builder.prepareBuildDir() + require.NoError(t, err) + defer os.Remove(builder.eibBuildDir) + + // Test + err = builder.copyRPMs() + + // Verify + require.NoError(t, err) +} diff --git a/pkg/config/testdata/rpms/.gitkeep b/pkg/config/testdata/rpms/.gitkeep new file mode 100644 index 00000000..e69de29b