summaryrefslogtreecommitdiff
path: root/pkg/machine/ignition.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine/ignition.go')
-rw-r--r--pkg/machine/ignition.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
new file mode 100644
index 000000000..ff79d5afb
--- /dev/null
+++ b/pkg/machine/ignition.go
@@ -0,0 +1,151 @@
+package machine
+
+import (
+ "encoding/json"
+ "io/ioutil"
+)
+
+/*
+ If this file gets too nuts, we can perhaps use existing go code
+ to create ignition files. At this point, the file is so simple
+ that I chose to use structs and not import any code as I was
+ concerned (unsubstantiated) about too much bloat coming in.
+
+ https://github.com/openshift/machine-config-operator/blob/master/pkg/server/server.go
+*/
+
+// Convenience function to convert int to ptr
+func intToPtr(i int) *int {
+ return &i
+}
+
+// Convenience function to convert string to ptr
+func strToPtr(s string) *string {
+ return &s
+}
+
+// Convenience function to convert bool to ptr
+func boolToPtr(b bool) *bool {
+ return &b
+}
+
+func getNodeUsr(usrName string) NodeUser {
+ return NodeUser{Name: &usrName}
+}
+
+func getNodeGrp(grpName string) NodeGroup {
+ return NodeGroup{Name: &grpName}
+}
+
+// NewIgnitionFile
+func NewIgnitionFile(name, key, writePath string) error {
+ if len(name) < 1 {
+ name = DefaultIgnitionUserName
+ }
+ ignVersion := Ignition{
+ Version: "3.2.0",
+ }
+
+ ignPassword := Passwd{
+ Users: []PasswdUser{{
+ Name: name,
+ SSHAuthorizedKeys: []SSHAuthorizedKey{SSHAuthorizedKey(key)},
+ }},
+ }
+
+ ignStorage := Storage{
+ Directories: getDirs(name),
+ Files: getFiles(name),
+ Links: getLinks(name),
+ }
+ ignSystemd := Systemd{
+ Units: []Unit{
+ {
+ Enabled: boolToPtr(true),
+ Name: "podman.socket",
+ }}}
+
+ ignConfig := Config{
+ Ignition: ignVersion,
+ Passwd: ignPassword,
+ Storage: ignStorage,
+ Systemd: ignSystemd,
+ }
+ b, err := json.Marshal(ignConfig)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(writePath, b, 0644)
+}
+
+func getDirs(usrName string) []Directory {
+ // Ignition has a bug/feature? where if you make a series of dirs
+ // in one swoop, then the leading dirs are creates as root.
+ newDirs := []string{
+ "/home/" + usrName + "/.config",
+ "/home/" + usrName + "/.config/systemd",
+ "/home/" + usrName + "/.config/systemd/user",
+ "/home/" + usrName + "/.config/systemd/user/default.target.wants",
+ }
+ var (
+ dirs = make([]Directory, len(newDirs))
+ )
+ for i, d := range newDirs {
+ newDir := Directory{
+ Node: Node{
+ Group: getNodeGrp(usrName),
+ Path: d,
+ User: getNodeUsr(usrName),
+ },
+ DirectoryEmbedded1: DirectoryEmbedded1{Mode: intToPtr(493)},
+ }
+ dirs[i] = newDir
+ }
+ return dirs
+}
+
+func getFiles(usrName string) []File {
+ var (
+ files []File
+ )
+ // Add a fake systemd service to get the user socket rolling
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp(usrName),
+ Path: "/home/" + usrName + "/.config/systemd/user/linger-example.service",
+ User: getNodeUsr(usrName),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: strToPtr("data:,%5BUnit%5D%0ADescription%3DA%20systemd%20user%20unit%20demo%0AAfter%3Dnetwork-online.target%0AWants%3Dnetwork-online.target%20podman.socket%0A%5BService%5D%0AExecStart%3D%2Fusr%2Fbin%2Fsleep%20infinity%0A"),
+ },
+ Mode: intToPtr(484),
+ },
+ })
+
+ // Add a file into linger
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp(usrName),
+ Path: "/var/lib/systemd/linger/core",
+ User: getNodeUsr(usrName),
+ },
+ FileEmbedded1: FileEmbedded1{Mode: intToPtr(420)},
+ })
+ return files
+}
+
+func getLinks(usrName string) []Link {
+ return []Link{{
+ Node: Node{
+ Group: getNodeGrp(usrName),
+ Path: "/home/" + usrName + "/.config/systemd/user/default.target.wants/linger-example.service",
+ User: getNodeUsr(usrName),
+ },
+ LinkEmbedded1: LinkEmbedded1{
+ Hard: boolToPtr(false),
+ Target: "/home/" + usrName + "/.config/systemd/user/linger-example.service",
+ },
+ }}
+}