This repository has been archived by the owner on Oct 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 659
/
cloudinit.go
170 lines (146 loc) · 4.67 KB
/
cloudinit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package cloudinit
import (
"io/ioutil"
"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)
}
exoscale, err := onlyExoscale()
if err != nil {
log.Error(err)
}
if exoscale {
cfg.Rancher.CloudInit.Datasources = append([]string{"exoscale"}, cfg.Rancher.CloudInit.Datasources...)
}
proxmox, err := onlyProxmox()
if err != nil {
log.Error(err)
}
if proxmox {
cfg.Rancher.CloudInit.Datasources = append([]string{"proxmox"}, cfg.Rancher.CloudInit.Datasources...)
}
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
}
func onlyExoscale() (bool, error) {
f, err := ioutil.ReadFile("/sys/class/dmi/id/product_name")
if err != nil {
return false, err
}
return strings.HasPrefix(string(f), "Exoscale"), nil
}
func onlyProxmox() (bool, error) {
f, err := ioutil.ReadFile("/sys/class/dmi/id/product_name")
if err != nil {
return false, err
}
return strings.Contains(string(f), "Proxmox"), nil
}