github.com/openshift/installer@v1.4.17/pkg/asset/imagebased/configimage/configiso.go (about) 1 package configimage 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 "path/filepath" 9 10 "github.com/openshift/assisted-image-service/pkg/isoeditor" 11 "github.com/openshift/installer/pkg/asset" 12 "github.com/openshift/installer/pkg/types/imagebased" 13 ) 14 15 const ( 16 configImageFilename = "imagebasedconfig.iso" 17 configImageLabel = imagebased.BlockDeviceLabel 18 19 clusterConfigurationDir = "cluster-configuration" 20 extraManifestsDir = "extra-manifests" 21 ) 22 23 var ( 24 manifestsDir = filepath.Join(clusterConfigurationDir, "manifests") 25 ) 26 27 // ConfigImage is an asset that generates a configuration ISO that can be used to 28 // configure image-based installer provisioned hosts. 29 type ConfigImage struct { 30 tmpPath string 31 } 32 33 var _ asset.WritableAsset = (*ConfigImage)(nil) 34 35 // Dependencies returns the assets on which the Config asset depends. 36 func (ci *ConfigImage) Dependencies() []asset.Asset { 37 return []asset.Asset{ 38 &ClusterConfiguration{}, 39 &ImageDigestSources{}, 40 &ExtraManifests{}, 41 } 42 } 43 44 // Generate generates the configuration image file. 45 func (ci *ConfigImage) Generate(_ context.Context, dependencies asset.Parents) error { 46 // Save the image to a temp file 47 tmpPath, err := os.MkdirTemp("", "imagebased") 48 if err != nil { 49 return fmt.Errorf("could not create temp directory: %w", err) 50 } 51 ci.tmpPath = tmpPath 52 53 dirs := []string{ 54 clusterConfigurationDir, 55 manifestsDir, 56 extraManifestsDir, 57 } 58 for _, dir := range dirs { 59 if err := os.MkdirAll(filepath.Join(ci.tmpPath, dir), 0755); err != nil { 60 return fmt.Errorf("could not create %s directory: %w", dir, err) 61 } 62 } 63 64 createFile := func(file *asset.File) error { 65 f, err := os.Create(filepath.Join(ci.tmpPath, file.Filename)) 66 if err != nil { 67 return fmt.Errorf("could not create %s: %w", file.Filename, err) 68 } 69 defer f.Close() 70 71 if _, err := f.Write(file.Data); err != nil { 72 return fmt.Errorf("could not write %s: %w", file.Filename, err) 73 } 74 return nil 75 } 76 77 for _, a := range []asset.WritableAsset{ 78 &ClusterConfiguration{}, 79 &ImageDigestSources{}, 80 &ExtraManifests{}, 81 } { 82 dependencies.Get(a) 83 84 for _, file := range a.Files() { 85 if err := createFile(file); err != nil { 86 return err 87 } 88 } 89 } 90 91 return nil 92 } 93 94 // PersistToFile writes the ISO image in the assets folder. 95 func (ci *ConfigImage) PersistToFile(directory string) error { 96 defer os.RemoveAll(ci.tmpPath) 97 98 // If the tmpPath is not set then it means that either one of the Config 99 // dependencies or the asset itself failed for some reason 100 if ci.tmpPath == "" { 101 return errors.New("cannot generate config image due to configuration errors") 102 } 103 104 configImageFile := filepath.Join(directory, configImageFilename) 105 106 // Remove symlink if it exists 107 os.Remove(configImageFile) 108 109 err := isoeditor.Create(configImageFile, ci.tmpPath, configImageLabel) 110 if err != nil { 111 return err 112 } 113 114 return nil 115 } 116 117 // Name returns the human-friendly name of the asset. 118 func (ci *ConfigImage) Name() string { 119 return "Image-based Installer Config ISO" 120 } 121 122 // Load returns the ISO from disk. 123 func (ci *ConfigImage) Load(f asset.FileFetcher) (bool, error) { 124 // The ISO will not be needed by another asset so load is noop. 125 // This is implemented because it is required by WritableAsset 126 return false, nil 127 } 128 129 // Files returns the files generated by the asset. 130 func (ci *ConfigImage) Files() []*asset.File { 131 // Return empty array because File will never be loaded. 132 return []*asset.File{} 133 }