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  }