github.com/openshift/installer@v1.4.17/pkg/asset/ignition/node.go (about) 1 package ignition 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 "github.com/clarketm/json" 8 ignutil "github.com/coreos/ignition/v2/config/util" 9 igntypes "github.com/coreos/ignition/v2/config/v3_2/types" 10 "github.com/vincent-petithory/dataurl" 11 "k8s.io/apimachinery/pkg/runtime" 12 13 "github.com/openshift/installer/pkg/asset" 14 ) 15 16 // Marshal is a helper function to use the marshaler function from "github.com/clarketm/json". 17 // It supports zero values of structs with the omittempty annotation. 18 // In effect this excludes empty pointer struct fields from the marshaled data, 19 // instead of inserting nil values into them. 20 // This is necessary for ignition configs to pass openAPI validation on fields 21 // that are not supposed to contain nil pointers, but e.g. strings. 22 // It can be used as a dropin replacement for "encoding/json".Marshal 23 func Marshal(input interface{}) ([]byte, error) { 24 return json.Marshal(input) 25 } 26 27 // FilesFromAsset creates ignition files for each of the files in the specified 28 // asset. 29 func FilesFromAsset(pathPrefix string, username string, mode int, asset asset.WritableAsset) []igntypes.File { 30 var files []igntypes.File 31 for _, f := range asset.Files() { 32 files = append(files, FileFromBytes(filepath.Join(pathPrefix, f.Filename), username, mode, f.Data)) 33 } 34 return files 35 } 36 37 // FileFromString creates an ignition-config file with the given contents. 38 func FileFromString(path string, username string, mode int, contents string) igntypes.File { 39 return FileFromBytes(path, username, mode, []byte(contents)) 40 } 41 42 // FileFromBytes creates an ignition-config file with the given contents. 43 func FileFromBytes(path string, username string, mode int, contents []byte) igntypes.File { 44 return igntypes.File{ 45 Node: igntypes.Node{ 46 Path: path, 47 User: igntypes.NodeUser{ 48 Name: &username, 49 }, 50 Overwrite: ignutil.BoolToPtr(true), 51 }, 52 FileEmbedded1: igntypes.FileEmbedded1{ 53 Mode: &mode, 54 Contents: igntypes.Resource{ 55 Source: ignutil.StrToPtr(dataurl.EncodeBytes(contents)), 56 }, 57 }, 58 } 59 } 60 61 // ConvertToRawExtension converts and ignition config to a RawExtension containing the ignition as raw bytes 62 func ConvertToRawExtension(config igntypes.Config) (runtime.RawExtension, error) { 63 rawIgnConfig, err := json.Marshal(config) 64 if err != nil { 65 return runtime.RawExtension{}, fmt.Errorf("failed to marshal Ignition config: %v", err) 66 } 67 68 return runtime.RawExtension{ 69 Raw: rawIgnConfig, 70 }, nil 71 } 72 73 // ConvertToAppendix converts the contents of an ignition file to an appendix. 74 // In ignition config spec v2 the `Append` boolean value was used to denote whether 75 // the `Contents` field was an appendix or not. It was also permitted to define 76 // multiple file configs (appendix or not) that would be merged/overwritten 77 // sequentially in the order of the json data, which made them non-deterministic. 78 // In spec v3 this has changed with only one config allowed for each file config, 79 // and `Append` now being a list of objects that are being appended to `Contents`, 80 // with the `Contents` field itself never being an appendix. 81 // This function moves an ignition file's `Contents` object into the `Append` list. 82 // Since the resulting ignition file of this function has an empty `Contents` field, 83 // `Overwrite` must be set to false, per the spec. 84 // The output is an ignition file config that will write a new file with only the 85 // appendix contents in the case of a file not already existing on disk, 86 // or append the appendix contents to a file already existing. 87 func ConvertToAppendix(file *igntypes.File) { 88 file.Append = []igntypes.Resource{ 89 file.Contents, 90 } 91 file.Contents = igntypes.Resource{} 92 file.Overwrite = ignutil.BoolToPtr(false) 93 }