1
0
mirror of https://github.com/rancher/os.git synced 2025-09-18 16:27:31 +00:00

make cloud-config the configuration mechanism for RancherOS

This commit is contained in:
Ivan Mikushin
2015-07-29 11:52:15 +05:00
parent 5d93d51fc5
commit 7ad60c07bd
24 changed files with 919 additions and 917 deletions

View File

@@ -48,86 +48,51 @@ const (
datasourceInterval = 100 * time.Millisecond
datasourceMaxInterval = 30 * time.Second
datasourceTimeout = 5 * time.Minute
sshKeyName = "rancheros-cloud-config"
baseConfigDir = "/var/lib/rancher/conf/cloud-config.d"
)
var (
baseConfigDir string
outputDir string
outputFile string
metaDataFile string
scriptFile string
rancherYml string
save bool
execute bool
network bool
sshKeyName string
flags *flag.FlagSet
save bool
execute bool
network bool
flags *flag.FlagSet
)
func init() {
flags = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
flags.StringVar(&baseConfigDir, "base-config-dir", "/var/lib/rancher/conf/cloud-config.d", "base cloud config")
flags.StringVar(&outputDir, "dir", "/var/lib/rancher/conf", "working directory")
flags.StringVar(&outputFile, "file", "cloud-config-processed.yml", "output cloud config file name")
flags.StringVar(&metaDataFile, "metadata", "metadata", "output metdata file name")
flags.StringVar(&scriptFile, "script-file", "cloud-config-script", "output cloud config script file name")
flags.StringVar(&rancherYml, "rancher", "cloud-config-rancher.yml", "output cloud config rancher file name")
flags.StringVar(&sshKeyName, "ssh-key-name", "rancheros-cloud-config", "SSH key name")
flags.BoolVar(&network, "network", true, "use network based datasources")
flags.BoolVar(&save, "save", false, "save cloud config and exit")
flags.BoolVar(&execute, "execute", false, "execute saved cloud config")
}
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
scriptOutput := path.Join(outputDir, scriptFile)
cloudConfigOutput := path.Join(outputDir, outputFile)
rancherYmlOutput := path.Join(outputDir, rancherYml)
metaDataOutput := path.Join(outputDir, metaDataFile)
os.Remove(scriptOutput)
os.Remove(cloudConfigOutput)
os.Remove(rancherYmlOutput)
os.Remove(metaDataOutput)
os.Remove(rancherConfig.CloudConfigScriptFile)
os.Remove(rancherConfig.CloudConfigFile)
os.Remove(rancherConfig.MetaDataFile)
if len(scriptBytes) > 0 {
log.Infof("Writing to %s", scriptOutput)
if err := ioutil.WriteFile(scriptOutput, scriptBytes, 500); err != nil {
log.Errorf("Error while writing file %s: %v", scriptOutput, err)
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile)
if err := ioutil.WriteFile(rancherConfig.CloudConfigScriptFile, scriptBytes, 500); err != nil {
log.Errorf("Error while writing file %s: %v", rancherConfig.CloudConfigScriptFile, err)
return err
}
}
cloudConfigBytes = append([]byte("#cloud-config\n"), cloudConfigBytes...)
log.Infof("Writing to %s", cloudConfigOutput)
if err := ioutil.WriteFile(cloudConfigOutput, cloudConfigBytes, 500); err != nil {
log.Errorf("Error while writing file %s: %v", cloudConfigOutput, err)
if err := ioutil.WriteFile(rancherConfig.CloudConfigFile, cloudConfigBytes, 400); err != nil {
return err
}
ccData := make(map[string]interface{})
if err := yaml.Unmarshal(cloudConfigBytes, ccData); err != nil {
return err
}
if rancher, ok := ccData["rancher"]; ok {
bytes, err := yaml.Marshal(rancher)
if err != nil {
return err
}
if err = ioutil.WriteFile(rancherYmlOutput, bytes, 400); err != nil {
return err
}
}
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigFile, string(cloudConfigBytes))
metaDataBytes, err := yaml.Marshal(metadata)
if err != nil {
return err
}
if err = ioutil.WriteFile(metaDataOutput, metaDataBytes, 400); err != nil {
if err = ioutil.WriteFile(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
return err
}
log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
return nil
}
@@ -258,24 +223,22 @@ func saveCloudConfig() error {
}
func getSaveCloudConfig() (*config.CloudConfig, error) {
cloudConfig := path.Join(outputDir, outputFile)
ds := file.NewDatasource(cloudConfig)
ds := file.NewDatasource(rancherConfig.CloudConfigFile)
if !ds.IsAvailable() {
log.Infof("%s does not exist", cloudConfig)
log.Infof("%s does not exist", rancherConfig.CloudConfigFile)
return nil, nil
}
ccBytes, err := ds.FetchUserdata()
if err != nil {
log.Errorf("Failed to read user-data from %s: %v", cloudConfig, err)
log.Errorf("Failed to read user-data from %s: %v", rancherConfig.CloudConfigFile, err)
return nil, err
}
var cc config.CloudConfig
err = yaml.Unmarshal(ccBytes, &cc)
if err != nil {
log.Errorf("Failed to unmarshall user-data from %s: %v", cloudConfig, err)
log.Errorf("Failed to unmarshall user-data from %s: %v", rancherConfig.CloudConfigFile, err)
return nil, err
}
@@ -290,7 +253,7 @@ func executeCloudConfig() error {
var metadata datasource.Metadata
metaDataBytes, err := ioutil.ReadFile(path.Join(outputDir, metaDataFile))
metaDataBytes, err := ioutil.ReadFile(rancherConfig.MetaDataFile)
if err != nil {
return err
}
@@ -338,6 +301,8 @@ func executeCloudConfig() error {
func Main() {
flags.Parse(rancherConfig.FilterGlobalConfig(os.Args[1:]))
log.Infof("Running cloud-init: save=%v, execute=%v", save, execute)
if save {
err := saveCloudConfig()
if err != nil {
@@ -376,10 +341,10 @@ func mergeConfigs(cc *config.CloudConfig, md datasource.Metadata) (out config.Cl
// getDatasources creates a slice of possible Datasources for cloudinit based
// on the different source command-line flags.
func getDatasources(cfg *rancherConfig.Config) []datasource.Datasource {
func getDatasources(cfg *rancherConfig.CloudConfig) []datasource.Datasource {
dss := make([]datasource.Datasource, 0, 5)
for _, ds := range cfg.CloudInit.Datasources {
for _, ds := range cfg.Rancher.CloudInit.Datasources {
parts := strings.SplitN(ds, ":", 2)
switch parts[0] {

View File

@@ -76,16 +76,16 @@ func configSubcommands() []cli.Command {
}
}
func imagesFromConfig(cfg *config.Config) []string {
func imagesFromConfig(cfg *config.CloudConfig) []string {
imagesMap := map[string]int{}
for _, service := range cfg.BootstrapContainers {
for _, service := range cfg.Rancher.BootstrapContainers {
imagesMap[service.Image] = 1
}
for _, service := range cfg.Autoformat {
for _, service := range cfg.Rancher.Autoformat {
imagesMap[service.Image] = 1
}
for _, service := range cfg.SystemContainers {
for _, service := range cfg.Rancher.Services {
imagesMap[service.Image] = 1
}
@@ -165,12 +165,12 @@ func configGet(c *cli.Context) {
cfg, err := config.LoadConfig()
if err != nil {
log.Fatal(err)
log.Panicln(err)
}
val, err := cfg.Get(arg)
if err != nil {
log.Fatal(err)
log.WithFields(log.Fields{"cfg": cfg, "arg": arg, "val": val}).Panicln(err)
}
printYaml := false
@@ -192,50 +192,6 @@ func configGet(c *cli.Context) {
}
}
func getOrSetVal(args string, data map[interface{}]interface{}, value interface{}) interface{} {
parts := strings.Split(args, ".")
for i, part := range parts {
val, ok := data[part]
last := i+1 == len(parts)
// Reached end, set the value
if last && value != nil {
if s, ok := value.(string); ok {
value = config.DummyMarshall(s)
}
data[part] = value
return value
}
// Missing intermediate key, create key
if !last && value != nil && !ok {
newData := map[interface{}]interface{}{}
data[part] = newData
data = newData
continue
}
if !ok {
break
}
if last {
return val
}
newData, ok := val.(map[interface{}]interface{})
if !ok {
break
}
data = newData
}
return ""
}
func merge(c *cli.Context) {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {

View File

@@ -20,8 +20,8 @@ func envAction(c *cli.Context) {
args := c.Args()
osEnv := os.Environ()
envMap := make(map[string]string, len(cfg.Environment)+len(osEnv))
for k, v := range cfg.Environment {
envMap := make(map[string]string, len(cfg.Rancher.Environment)+len(osEnv))
for k, v := range cfg.Rancher.Environment {
envMap[k] = v
}
for k, v := range util.KVPairs2Map(osEnv) {

View File

@@ -249,5 +249,5 @@ func getUpgradeUrl() (string, error) {
return "", err
}
return cfg.Upgrade.Url, nil
return cfg.Rancher.Upgrade.Url, nil
}

View File

@@ -2,7 +2,7 @@ package control
import (
"fmt"
"log"
log "github.com/Sirupsen/logrus"
"strings"
"github.com/codegangsta/cli"
@@ -44,16 +44,16 @@ func disable(c *cli.Context) {
}
for _, service := range c.Args() {
if _, ok := cfg.ServicesInclude[service]; !ok {
if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
continue
}
cfg.ServicesInclude[service] = false
cfg.Rancher.ServicesInclude[service] = false
changed = true
}
if changed {
if err = cfg.Set("services_include", cfg.ServicesInclude); err != nil {
if err = cfg.Set("rancher.services_include", cfg.Rancher.ServicesInclude); err != nil {
log.Fatal(err)
}
}
@@ -67,15 +67,15 @@ func del(c *cli.Context) {
}
for _, service := range c.Args() {
if _, ok := cfg.ServicesInclude[service]; !ok {
if _, ok := cfg.Rancher.ServicesInclude[service]; !ok {
continue
}
delete(cfg.ServicesInclude, service)
delete(cfg.Rancher.ServicesInclude, service)
changed = true
}
if changed {
if err = cfg.Set("services_include", cfg.ServicesInclude); err != nil {
if err = cfg.Set("rancher.services_include", cfg.Rancher.ServicesInclude); err != nil {
log.Fatal(err)
}
}
@@ -89,20 +89,20 @@ func enable(c *cli.Context) {
}
for _, service := range c.Args() {
if val, ok := cfg.ServicesInclude[service]; !ok || !val {
if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val {
if strings.HasPrefix(service, "/") && !strings.HasPrefix(service, "/var/lib/rancher/conf") {
log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf")
}
if _, err := docker.LoadServiceResource(service, true, cfg); err != nil {
log.Fatalf("could not load service %s", service)
}
cfg.ServicesInclude[service] = true
cfg.Rancher.ServicesInclude[service] = true
changed = true
}
}
if changed {
if err = cfg.Set("services_include", cfg.ServicesInclude); err != nil {
if err := cfg.Set("rancher.services_include", cfg.Rancher.ServicesInclude); err != nil {
log.Fatal(err)
}
}
@@ -115,11 +115,11 @@ func list(c *cli.Context) {
}
clone := make(map[string]bool)
for service, enabled := range cfg.ServicesInclude {
for service, enabled := range cfg.Rancher.ServicesInclude {
clone[service] = enabled
}
services, err := util.GetServices(cfg.Repositories.ToArray())
services, err := util.GetServices(cfg.Rancher.Repositories.ToArray())
if err != nil {
log.Fatalf("Failed to get services: %v", err)
}

View File

@@ -44,12 +44,12 @@ func tlsConfCommands() []cli.Command {
}
}
func writeCerts(generateServer bool, hostname []string, cfg *config.Config, certPath, keyPath, caCertPath, caKeyPath string) error {
func writeCerts(generateServer bool, hostname []string, cfg *config.CloudConfig, certPath, keyPath, caCertPath, caKeyPath string) error {
if !generateServer {
return machineUtil.GenerateCert([]string{""}, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
}
if cfg.UserDocker.ServerKey == "" || cfg.UserDocker.ServerCert == "" {
if cfg.Rancher.UserDocker.ServerKey == "" || cfg.Rancher.UserDocker.ServerCert == "" {
err := machineUtil.GenerateCert(hostname, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
if err != nil {
return err
@@ -65,26 +65,28 @@ func writeCerts(generateServer bool, hostname []string, cfg *config.Config, cert
return err
}
return cfg.SetConfig(&config.Config{
UserDocker: config.DockerConfig{
CAKey: cfg.UserDocker.CAKey,
CACert: cfg.UserDocker.CACert,
ServerCert: string(cert),
ServerKey: string(key),
return cfg.SetConfig(&config.CloudConfig{
Rancher: config.RancherConfig{
UserDocker: config.DockerConfig{
CAKey: cfg.Rancher.UserDocker.CAKey,
CACert: cfg.Rancher.UserDocker.CACert,
ServerCert: string(cert),
ServerKey: string(key),
},
},
})
}
if err := ioutil.WriteFile(certPath, []byte(cfg.UserDocker.ServerCert), 0400); err != nil {
if err := ioutil.WriteFile(certPath, []byte(cfg.Rancher.UserDocker.ServerCert), 0400); err != nil {
return err
}
return ioutil.WriteFile(keyPath, []byte(cfg.UserDocker.ServerKey), 0400)
return ioutil.WriteFile(keyPath, []byte(cfg.Rancher.UserDocker.ServerKey), 0400)
}
func writeCaCerts(cfg *config.Config, caCertPath, caKeyPath string) error {
if cfg.UserDocker.CACert == "" {
func writeCaCerts(cfg *config.CloudConfig, caCertPath, caKeyPath string) error {
if cfg.Rancher.UserDocker.CACert == "" {
if err := machineUtil.GenerateCACertificate(caCertPath, caKeyPath, NAME, BITS); err != nil {
return err
}
@@ -99,10 +101,12 @@ func writeCaCerts(cfg *config.Config, caCertPath, caKeyPath string) error {
return err
}
err = cfg.SetConfig(&config.Config{
UserDocker: config.DockerConfig{
CAKey: string(caKey),
CACert: string(caCert),
err = cfg.SetConfig(&config.CloudConfig{
Rancher: config.RancherConfig{
UserDocker: config.DockerConfig{
CAKey: string(caKey),
CACert: string(caCert),
},
},
})
if err != nil {
@@ -112,11 +116,11 @@ func writeCaCerts(cfg *config.Config, caCertPath, caKeyPath string) error {
return nil
}
if err := ioutil.WriteFile(caCertPath, []byte(cfg.UserDocker.CACert), 0400); err != nil {
if err := ioutil.WriteFile(caCertPath, []byte(cfg.Rancher.UserDocker.CACert), 0400); err != nil {
return err
}
return ioutil.WriteFile(caKeyPath, []byte(cfg.UserDocker.CAKey), 0400)
return ioutil.WriteFile(caKeyPath, []byte(cfg.Rancher.UserDocker.CAKey), 0400)
}
func tlsConfCreate(c *cli.Context) {

View File

@@ -20,14 +20,14 @@ import (
func Main() {
args := os.Args
if len(args) > 1 {
fmt.Println("call " + args[0] + " to load network config from rancher.yml config file")
fmt.Println("call " + args[0] + " to load network config from cloud-config.yml")
return
}
cfg, err := config.LoadConfig()
if err != nil {
log.Fatal(err)
}
ApplyNetworkConfigs(&cfg.Network)
ApplyNetworkConfigs(&cfg.Rancher.Network)
}
func createInterfaces(netCfg *config.NetworkConfig) error {

View File

@@ -68,7 +68,7 @@ func run(c *cli.Context) {
var wg sync.WaitGroup
for _, line := range strings.Split(string(input), "\n") {
if strings.TrimSpace(line) == "" {
if strings.TrimSpace(line) == "" || strings.Index(strings.TrimSpace(line), "#") == 0 {
continue
}
wg.Add(1)