123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package cloudinit
- import (
- "path/filepath"
- "strings"
- "github.com/rancher/os/config"
- "github.com/rancher/os/pkg/compose"
- "github.com/rancher/os/pkg/init/docker"
- "github.com/rancher/os/pkg/log"
- "github.com/rancher/os/pkg/sysinit"
- "github.com/rancher/os/pkg/util"
- )
- func CloudInit(cfg *config.CloudConfig) (*config.CloudConfig, error) {
- stateConfig := config.LoadConfigWithPrefix(config.StateDir)
- cfg.Rancher.CloudInit.Datasources = stateConfig.Rancher.CloudInit.Datasources
- hypervisor := util.GetHypervisor()
- if hypervisor == "" {
- log.Infof("ros init: No Detected Hypervisor")
- } else {
- log.Infof("ros init: Detected Hypervisor: %s", hypervisor)
- }
- if hypervisor == "vmware" {
- // add vmware to the end - we don't want to over-ride an choices the user has made
- cfg.Rancher.CloudInit.Datasources = append(cfg.Rancher.CloudInit.Datasources, hypervisor)
- }
- if len(cfg.Rancher.CloudInit.Datasources) == 0 {
- log.Info("No specific datasources, ignore cloudinit")
- return cfg, nil
- }
- if onlyConfigDrive(cfg.Rancher.CloudInit.Datasources) {
- configDev := util.ResolveDevice("LABEL=config-2")
- if configDev == "" {
- // Check v9fs: https://www.kernel.org/doc/Documentation/filesystems/9p.txt
- matches, _ := filepath.Glob("/sys/bus/virtio/drivers/9pnet_virtio/virtio*/mount_tag")
- if len(matches) == 0 {
- log.Info("Configdrive was enabled but has no configdrive device or filesystem, ignore cloudinit")
- return cfg, nil
- }
- }
- }
- if err := config.Set("rancher.cloud_init.datasources", cfg.Rancher.CloudInit.Datasources); err != nil {
- log.Error(err)
- }
- if stateConfig.Rancher.Network.DHCPTimeout > 0 {
- cfg.Rancher.Network.DHCPTimeout = stateConfig.Rancher.Network.DHCPTimeout
- if err := config.Set("rancher.network.dhcp_timeout", stateConfig.Rancher.Network.DHCPTimeout); err != nil {
- log.Error(err)
- }
- }
- if len(stateConfig.Rancher.Network.WifiNetworks) > 0 {
- cfg.Rancher.Network.WifiNetworks = stateConfig.Rancher.Network.WifiNetworks
- if err := config.Set("rancher.network.wifi_networks", stateConfig.Rancher.Network.WifiNetworks); err != nil {
- log.Error(err)
- }
- }
- if len(stateConfig.Rancher.Network.Interfaces) > 0 {
- // DO also uses static networking, but this IP may change if:
- // 1. not using Floating IP
- // 2. creating a droplet with a snapshot, the snapshot cached the previous IP
- if onlyDigitalOcean(cfg.Rancher.CloudInit.Datasources) {
- log.Info("Do not use the previous network settings on DigitalOcean")
- } else {
- cfg.Rancher.Network = stateConfig.Rancher.Network
- if err := config.Set("rancher.network", stateConfig.Rancher.Network); err != nil {
- log.Error(err)
- }
- }
- }
- log.Infof("init, runCloudInitServices(%v)", cfg.Rancher.CloudInit.Datasources)
- if err := runCloudInitServices(cfg); err != nil {
- log.Error(err)
- }
- // It'd be nice to push to rsyslog before this, but we don't have network
- log.AddRSyslogHook()
- return config.LoadConfig(), nil
- }
- func runCloudInitServices(cfg *config.CloudConfig) error {
- c, err := docker.Start(cfg)
- if err != nil {
- return err
- }
- defer docker.Stop(c)
- _, err = config.ChainCfgFuncs(cfg,
- []config.CfgFuncData{
- {"cloudinit loadImages", sysinit.LoadBootstrapImages},
- {"cloudinit Services", runCloudInitServiceSet},
- })
- return err
- }
- func runCloudInitServiceSet(cfg *config.CloudConfig) (*config.CloudConfig, error) {
- log.Info("Running cloud-init services")
- _, err := compose.RunServiceSet("cloud-init", cfg, cfg.Rancher.CloudInitServices)
- return cfg, err
- }
- func onlyConfigDrive(datasources []string) bool {
- if len(datasources) != 1 {
- return false
- }
- for _, ds := range datasources {
- parts := strings.SplitN(ds, ":", 2)
- if parts[0] == "configdrive" {
- return true
- }
- }
- return false
- }
- func onlyDigitalOcean(datasources []string) bool {
- if len(datasources) != 1 {
- return false
- }
- for _, ds := range datasources {
- parts := strings.SplitN(ds, ":", 2)
- if parts[0] == "digitalocean" {
- return true
- }
- }
- return false
- }
|