Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OEM: IONOS Cloud Images #29

Open
wants to merge 1 commit into
base: flatcar-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion coreos-cloudinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/flatcar/coreos-cloudinit/datasource"
"github.com/flatcar/coreos-cloudinit/datasource/configdrive"
"github.com/flatcar/coreos-cloudinit/datasource/file"
"github.com/flatcar/coreos-cloudinit/datasource/ionoscloud"
"github.com/flatcar/coreos-cloudinit/datasource/metadata/cloudsigma"
"github.com/flatcar/coreos-cloudinit/datasource/metadata/digitalocean"
"github.com/flatcar/coreos-cloudinit/datasource/metadata/ec2"
Expand Down Expand Up @@ -66,6 +67,7 @@ var (
cloudSigmaMetadataService bool
digitalOceanMetadataService string
packetMetadataService string
ionosCloudSeed string
url string
procCmdLine bool
vmware bool
Expand Down Expand Up @@ -96,6 +98,7 @@ func init() {
flag.BoolVar(&flags.sources.procCmdLine, "from-proc-cmdline", false, fmt.Sprintf("Parse %s for '%s=<url>', using the cloud-config served by an HTTP GET to <url>", proc_cmdline.ProcCmdlineLocation, proc_cmdline.ProcCmdlineCloudConfigFlag))
flag.BoolVar(&flags.sources.vmware, "from-vmware-guestinfo", false, "Read data from VMware guestinfo")
flag.StringVar(&flags.sources.ovfEnv, "from-vmware-ovf-env", "", "Read data from OVF Environment")
flag.StringVar(&flags.sources.ionosCloudSeed, "from-ionoscloud-seed", "", "Read data from IONOS Cloud injected cloud-init seed files")
flag.StringVar(&flags.oem, "oem", "", "Use the settings specific to the provided OEM")
flag.StringVar(&flags.convertNetconf, "convert-netconf", "", "Read the network config provided in cloud-drive and translate it from the specified format into networkd unit files")
flag.StringVar(&flags.workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data")
Expand Down Expand Up @@ -134,6 +137,10 @@ var (
"from-vmware-guestinfo": "true",
"convert-netconf": "vmware",
},
"ionoscloud": {
"from-ionoscloud-seed": "/var/lib/cloud/seed/nocloud/",
"convert-netconf": "debian",
},
}
)

Expand Down Expand Up @@ -178,7 +185,7 @@ func main() {

dss := getDatasources()
if len(dss) == 0 {
fmt.Println("Provide at least one of --from-file, --from-configdrive, --from-ec2-metadata, --from-gce-metadata, --from-cloudsigma-metadata, --from-packet-metadata, --from-digitalocean-metadata, --from-vmware-guestinfo, --from-waagent, --from-url or --from-proc-cmdline")
fmt.Println("Provide at least one of --from-file, --from-configdrive, --from-ec2-metadata, --from-gce-metadata, --from-cloudsigma-metadata, --from-packet-metadata, --from-digitalocean-metadata, --from-ionoscloud-seed, --from-vmware-guestinfo, --from-waagent, --from-url or --from-proc-cmdline")
os.Exit(2)
}

Expand Down Expand Up @@ -369,6 +376,9 @@ func getDatasources() []datasource.Datasource {
if flags.sources.ovfEnv != "" {
dss = append(dss, vmware.NewDatasource(flags.sources.ovfEnv))
}
if flags.sources.ionosCloudSeed != "" {
dss = append(dss, ionoscloud.NewDatasource(flags.sources.ionosCloudSeed))
}
return dss
}

Expand Down
74 changes: 74 additions & 0 deletions datasource/ionoscloud/ionoscloud.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package ionoscloud

import (
"log"
"os"
"path"

"gopkg.in/yaml.v3"

"github.com/flatcar/coreos-cloudinit/datasource"
)

const (
networkconfig = "/etc/cloud/cloud.cfg.d/99_custom_networking.cfg"
)

type ionoscloud struct {
seed string
readFile func(filename string) ([]byte, error)
}

func NewDatasource(seed string) *ionoscloud {
return &ionoscloud{seed, os.ReadFile}
}

func (ic *ionoscloud) IsAvailable() bool {
_, err := os.Stat(ic.seed)
return !os.IsNotExist(err)
}

func (ic *ionoscloud) AvailabilityChanges() bool {
return true
}

func (ic *ionoscloud) ConfigRoot() string {
return ic.seed
}

func (ic *ionoscloud) FetchMetadata() (metadata datasource.Metadata, err error) {
var data []byte
var m struct {
DSMode string `json:"dsmode"`
SSHPublicKeys map[string]string `json:"public_keys"`
}

if data, err = ic.tryReadFile(path.Join(ic.seed, "meta-data")); err != nil || len(data) == 0 {
return
}
if err = yaml.Unmarshal([]byte(data), &m); err != nil {
return
}

metadata.SSHPublicKeys = m.SSHPublicKeys
metadata.NetworkConfig, _ = ic.tryReadFile(networkconfig)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would catch the error here.

Suggested change
metadata.NetworkConfig, _ = ic.tryReadFile(networkconfig)
metadata.NetworkConfig, err = ic.tryReadFile(networkconfig)


return
}

func (ic *ionoscloud) FetchUserdata() ([]byte, error) {
return ic.tryReadFile(path.Join(ic.seed, "user-data"))
}

func (ic *ionoscloud) Type() string {
return "ionoscloud"
}

func (ic *ionoscloud) tryReadFile(filename string) ([]byte, error) {
log.Printf("Attempting to read from %q\n", filename)
data, err := os.ReadFile(filename)
if os.IsNotExist(err) {
err = nil
}
return data, err
}
4 changes: 3 additions & 1 deletion units/user-configdrive.service
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ Before=user-config.target
After=enable-oem-cloudinit.service oem-cloudinit.service

# Skip on clouds that are covered by flatcar/init:systemd/system/oem-cloudinit.service
ConditionKernelCommandLine=!flatcar.oem.id=digitalocean
ConditionKernelCommandLine=!coreos.oem.id=digitalocean
ConditionKernelCommandLine=!flatcar.oem.id=digitalocean
ConditionKernelCommandLine=!coreos.oem.id=openstack
ConditionKernelCommandLine=!flatcar.oem.id=openstack
ConditionKernelCommandLine=!coreos.oem.id=ionoscloud
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for old systems (backward compatibility) - we can just use flatcar.oem.id here.

Suggested change
ConditionKernelCommandLine=!coreos.oem.id=ionoscloud

ConditionKernelCommandLine=!flatcar.oem.id=ionoscloud
[Service]
Type=oneshot
ExecCondition=/usr/bin/bash -c "if [ -f '/etc/.ignition-result.json' ] && /usr/bin/jq -e '.userConfigProvided == true' /etc/.ignition-result.json; then exit 1; fi"
Expand Down