From 9be836df310fb1321038d56d19554646029a0780 Mon Sep 17 00:00:00 2001 From: Thom May Date: Fri, 12 Dec 2014 16:53:11 +0000 Subject: [PATCH 01/56] Create an environment file for flannel Rather than using a systemd overlay, allow docker to load the environment file. This is due to coreos/coreos-overlay#1002 --- initialize/config.go | 2 +- system/env.go | 24 ++++++++++++----- system/flannel.go | 28 ++++++++++++-------- system/flannel_test.go | 60 ++++++++++++++++++++++++++---------------- 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/initialize/config.go b/initialize/config.go index 3e9c64e..99e18c1 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -113,6 +113,7 @@ func Apply(cfg config.CloudConfig, env *Environment) error { system.OEM{OEM: cfg.Coreos.OEM}, system.Update{Update: cfg.Coreos.Update, ReadConfig: system.DefaultReadConfig}, system.EtcHosts{EtcHosts: cfg.ManageEtcHosts}, + system.Flannel{Flannel: cfg.Coreos.Flannel}, } { f, err := ccf.File() if err != nil { @@ -132,7 +133,6 @@ func Apply(cfg config.CloudConfig, env *Environment) error { system.Etcd{Etcd: cfg.Coreos.Etcd}, system.Fleet{Fleet: cfg.Coreos.Fleet}, system.Locksmith{Locksmith: cfg.Coreos.Locksmith}, - system.Flannel{Flannel: cfg.Coreos.Flannel}, system.Update{Update: cfg.Coreos.Update, ReadConfig: system.DefaultReadConfig}, } { units = append(units, ccu.Units()...) diff --git a/system/env.go b/system/env.go index 993d583..9e1fc65 100644 --- a/system/env.go +++ b/system/env.go @@ -23,22 +23,32 @@ import ( "github.com/coreos/coreos-cloudinit/config" ) -// dropinContents generates the contents for a drop-in unit given the config. +// serviceContents generates the contents for a drop-in unit given the config. // The argument must be a struct from the 'config' package. func serviceContents(e interface{}) string { + vars := getEnvVars(e) + if len(vars) == 0 { + return "" + } + + out := "[Service]\n" + for _, v := range vars { + out += fmt.Sprintf("Environment=\"%s\"\n", v) + } + return out +} + +func getEnvVars(e interface{}) []string { et := reflect.TypeOf(e) ev := reflect.ValueOf(e) - var out string + vars := []string{} for i := 0; i < et.NumField(); i++ { if val := ev.Field(i).Interface(); !config.IsZero(val) { key := et.Field(i).Tag.Get("env") - out += fmt.Sprintf("Environment=\"%s=%v\"\n", key, val) + vars = append(vars, fmt.Sprintf("%s=%v", key, val)) } } - if out == "" { - return "" - } - return "[Service]\n" + out + return vars } diff --git a/system/flannel.go b/system/flannel.go index 3e97f18..5dfbfac 100644 --- a/system/flannel.go +++ b/system/flannel.go @@ -1,6 +1,9 @@ package system import ( + "path" + "strings" + "github.com/coreos/coreos-cloudinit/config" ) @@ -10,15 +13,18 @@ type Flannel struct { config.Flannel } -// Units generates a Unit file drop-in for flannel, if any flannel options were -// configured in cloud-config -func (fl Flannel) Units() []Unit { - return []Unit{{config.Unit{ - Name: "flanneld.service", - Runtime: true, - DropIns: []config.UnitDropIn{{ - Name: "20-cloudinit.conf", - Content: serviceContents(fl.Flannel), - }}, - }}} +func (fl Flannel) envVars() string { + return strings.Join(getEnvVars(fl.Flannel), "\n") +} + +func (fl Flannel) File() (*File, error) { + vars := fl.envVars() + if vars == "" { + return nil, nil + } + return &File{config.File{ + Path: path.Join("run", "flannel", "options.env"), + RawFilePermissions: "0644", + Content: vars, + }}, nil } diff --git a/system/flannel_test.go b/system/flannel_test.go index 2e20c46..4eec6b9 100644 --- a/system/flannel_test.go +++ b/system/flannel_test.go @@ -7,40 +7,56 @@ import ( "github.com/coreos/coreos-cloudinit/config" ) -func TestFlannelUnits(t *testing.T) { +func TestFlannelEnvVars(t *testing.T) { for _, tt := range []struct { - config config.Flannel - units []Unit + config config.Flannel + contents string }{ { config.Flannel{}, - []Unit{{config.Unit{ - Name: "flanneld.service", - Runtime: true, - DropIns: []config.UnitDropIn{{Name: "20-cloudinit.conf"}}, - }}}, + "", }, { config.Flannel{ EtcdEndpoint: "http://12.34.56.78:4001", EtcdPrefix: "/coreos.com/network/tenant1", }, - []Unit{{config.Unit{ - Name: "flanneld.service", - Runtime: true, - DropIns: []config.UnitDropIn{{ - Name: "20-cloudinit.conf", - Content: `[Service] -Environment="FLANNELD_ETCD_ENDPOINT=http://12.34.56.78:4001" -Environment="FLANNELD_ETCD_PREFIX=/coreos.com/network/tenant1" -`, - }}, - }}}, + `FLANNELD_ETCD_ENDPOINT=http://12.34.56.78:4001 +FLANNELD_ETCD_PREFIX=/coreos.com/network/tenant1`, }, } { - units := Flannel{tt.config}.Units() - if !reflect.DeepEqual(units, tt.units) { - t.Errorf("bad units (%q): want %v, got %v", tt.config, tt.units, units) + out := Flannel{tt.config}.envVars() + if out != tt.contents { + t.Errorf("bad contents (%+v): want %q, got %q", tt, tt.contents, out) + } + } +} + +func TestFlannelFile(t *testing.T) { + for _, tt := range []struct { + config config.Flannel + file *File + }{ + { + config.Flannel{}, + nil, + }, + { + config.Flannel{ + EtcdEndpoint: "http://12.34.56.78:4001", + EtcdPrefix: "/coreos.com/network/tenant1", + }, + &File{config.File{ + Path: "run/flannel/options.env", + RawFilePermissions: "0644", + Content: `FLANNELD_ETCD_ENDPOINT=http://12.34.56.78:4001 +FLANNELD_ETCD_PREFIX=/coreos.com/network/tenant1`, + }}, + }, + } { + file, _ := Flannel{tt.config}.File() + if !reflect.DeepEqual(tt.file, file) { + t.Errorf("bad units (%q): want %#v, got %#v", tt.config, tt.file, file) } } } From 182241c8d3564c50d5f3c9f759386ae07fe5fdda Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sat, 20 Dec 2014 17:47:17 -0800 Subject: [PATCH 02/56] config: clean up and remove some tests Small modification to make these align with our test-table-style tests. Also removed TestCloudConfigInvalidKeys since it hasn't been a useful test since d3294bcb86b85e59bc79687b589d1bb64c24d996. --- config/config_test.go | 46 +++++++++++-------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index 29171ad..68a42cc 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -23,8 +23,9 @@ import ( ) func TestIsZero(t *testing.T) { - for _, tt := range []struct { - c interface{} + tests := []struct { + c interface{} + empty bool }{ {struct{}{}, true}, @@ -34,7 +35,9 @@ func TestIsZero(t *testing.T) { {struct{ A string }{A: "hello"}, false}, {struct{ A int }{}, true}, {struct{ A int }{A: 1}, false}, - } { + } + + for _, tt := range tests { if empty := IsZero(tt.c); tt.empty != empty { t.Errorf("bad result (%q): want %t, got %t", tt.c, tt.empty, empty) } @@ -42,8 +45,9 @@ func TestIsZero(t *testing.T) { } func TestAssertStructValid(t *testing.T) { - for _, tt := range []struct { - c interface{} + tests := []struct { + c interface{} + err error }{ {struct{}{}, nil}, @@ -71,41 +75,15 @@ func TestAssertStructValid(t *testing.T) { {struct { A, b int `valid:"1,2"` }{A: 9, b: 2}, &ErrorValid{Value: "9", Field: "A", Valid: []string{"1", "2"}}}, - } { + } + + for _, tt := range tests { if err := AssertStructValid(tt.c); !reflect.DeepEqual(tt.err, err) { t.Errorf("bad result (%q): want %q, got %q", tt.c, tt.err, err) } } } -func TestCloudConfigInvalidKeys(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Fatalf("panic while instantiating CloudConfig with nil keys: %v", r) - } - }() - - for _, tt := range []struct { - contents string - }{ - {"coreos:"}, - {"ssh_authorized_keys:"}, - {"ssh_authorized_keys:\n -"}, - {"ssh_authorized_keys:\n - 0:"}, - {"write_files:"}, - {"write_files:\n -"}, - {"write_files:\n - 0:"}, - {"users:"}, - {"users:\n -"}, - {"users:\n - 0:"}, - } { - _, err := NewCloudConfig(tt.contents) - if err != nil { - t.Fatalf("error instantiating CloudConfig with invalid keys: %v", err) - } - } -} - func TestCloudConfigUnknownKeys(t *testing.T) { contents := ` coreos: From 057ab3736452bd0bad244bb4130f9ceac9f15e5c Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sun, 21 Dec 2014 12:14:23 -0800 Subject: [PATCH 03/56] config: seperate the CoreOS type from CloudConfig Renamed Coreos to CoreOS while I was at it. --- config/config.go | 20 +++++++++++--------- config/config_test.go | 12 ++++++------ initialize/config.go | 16 ++++++++-------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/config/config.go b/config/config.go index 9278ecc..1cdad17 100644 --- a/config/config.go +++ b/config/config.go @@ -29,15 +29,7 @@ import ( // used for internal use) have the YAML tag '-' so that they aren't marshalled. type CloudConfig struct { SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` - Coreos struct { - Etcd Etcd `yaml:"etcd"` - Flannel Flannel `yaml:"flannel"` - Fleet Fleet `yaml:"fleet"` - Locksmith Locksmith `yaml:"locksmith"` - OEM OEM `yaml:"oem"` - Update Update `yaml:"update"` - Units []Unit `yaml:"units"` - } `yaml:"coreos"` + CoreOS CoreOS `yaml:"coreos"` WriteFiles []File `yaml:"write_files"` Hostname string `yaml:"hostname"` Users []User `yaml:"users"` @@ -46,6 +38,16 @@ type CloudConfig struct { NetworkConfig string `yaml:"-"` } +type CoreOS struct { + Etcd Etcd `yaml:"etcd"` + Flannel Flannel `yaml:"flannel"` + Fleet Fleet `yaml:"fleet"` + Locksmith Locksmith `yaml:"locksmith"` + OEM OEM `yaml:"oem"` + Update Update `yaml:"update"` + Units []Unit `yaml:"units"` +} + func IsCloudConfig(userdata string) bool { header := strings.SplitN(userdata, "\n", 2)[0] diff --git a/config/config_test.go b/config/config_test.go index 68a42cc..7cc6756 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -114,7 +114,7 @@ hostname: if cfg.Hostname != "foo" { t.Fatalf("hostname not correctly set when invalid keys are present") } - if cfg.Coreos.Etcd.Discovery != "https://discovery.etcd.io/827c73219eeb2fa5530027c37bf18877" { + if cfg.CoreOS.Etcd.Discovery != "https://discovery.etcd.io/827c73219eeb2fa5530027c37bf18877" { t.Fatalf("etcd section not correctly set when invalid keys are present") } if len(cfg.WriteFiles) < 1 || cfg.WriteFiles[0].Content != "fun" || cfg.WriteFiles[0].Path != "/var/party" { @@ -220,10 +220,10 @@ hostname: trontastic } } - if len(cfg.Coreos.Units) != 1 { + if len(cfg.CoreOS.Units) != 1 { t.Error("Failed to parse correct number of units") } else { - u := cfg.Coreos.Units[0] + u := cfg.CoreOS.Units[0] expect := `[Match] Name=eth47 @@ -241,14 +241,14 @@ Address=10.209.171.177/19 } } - if cfg.Coreos.OEM.ID != "rackspace" { - t.Errorf("Failed parsing coreos.oem. Expected ID 'rackspace', got %q.", cfg.Coreos.OEM.ID) + if cfg.CoreOS.OEM.ID != "rackspace" { + t.Errorf("Failed parsing coreos.oem. Expected ID 'rackspace', got %q.", cfg.CoreOS.OEM.ID) } if cfg.Hostname != "trontastic" { t.Errorf("Failed to parse hostname") } - if cfg.Coreos.Update.RebootStrategy != "reboot" { + if cfg.CoreOS.Update.RebootStrategy != "reboot" { t.Errorf("Failed to parse locksmith strategy") } diff --git a/initialize/config.go b/initialize/config.go index 99e18c1..034ba97 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -110,10 +110,10 @@ func Apply(cfg config.CloudConfig, env *Environment) error { } for _, ccf := range []CloudConfigFile{ - system.OEM{OEM: cfg.Coreos.OEM}, - system.Update{Update: cfg.Coreos.Update, ReadConfig: system.DefaultReadConfig}, + system.OEM{OEM: cfg.CoreOS.OEM}, + system.Update{Update: cfg.CoreOS.Update, ReadConfig: system.DefaultReadConfig}, system.EtcHosts{EtcHosts: cfg.ManageEtcHosts}, - system.Flannel{Flannel: cfg.Coreos.Flannel}, + system.Flannel{Flannel: cfg.CoreOS.Flannel}, } { f, err := ccf.File() if err != nil { @@ -125,15 +125,15 @@ func Apply(cfg config.CloudConfig, env *Environment) error { } var units []system.Unit - for _, u := range cfg.Coreos.Units { + for _, u := range cfg.CoreOS.Units { units = append(units, system.Unit{Unit: u}) } for _, ccu := range []CloudConfigUnit{ - system.Etcd{Etcd: cfg.Coreos.Etcd}, - system.Fleet{Fleet: cfg.Coreos.Fleet}, - system.Locksmith{Locksmith: cfg.Coreos.Locksmith}, - system.Update{Update: cfg.Coreos.Update, ReadConfig: system.DefaultReadConfig}, + system.Etcd{Etcd: cfg.CoreOS.Etcd}, + system.Fleet{Fleet: cfg.CoreOS.Fleet}, + system.Locksmith{Locksmith: cfg.CoreOS.Locksmith}, + system.Update{Update: cfg.CoreOS.Update, ReadConfig: system.DefaultReadConfig}, } { units = append(units, ccu.Units()...) } From 4ed1d03c976b3fad35a87d1c10c503df6b079f7e Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 24 Dec 2014 13:16:47 -0800 Subject: [PATCH 04/56] godeps: bump github.com/coreos/yaml --- Godeps/Godeps.json | 2 +- .../src/github.com/coreos/yaml/README.md | 3 +++ .../src/github.com/coreos/yaml/decode.go | 17 +++++++++++------ .../src/github.com/coreos/yaml/decode_test.go | 19 ++++++++++++++++++- .../src/github.com/coreos/yaml/encode_test.go | 2 +- .../src/github.com/coreos/yaml/yaml.go | 13 ++++++++++++- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ee26a08..77a58e9 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -15,7 +15,7 @@ }, { "ImportPath": "github.com/coreos/yaml", - "Rev": "9f9df34309c04878acc86042b16630b0f696e1de" + "Rev": "6b16a5714269b2f70720a45406b1babd947a17ef" }, { "ImportPath": "github.com/dotcloud/docker/pkg/netlink", diff --git a/Godeps/_workspace/src/github.com/coreos/yaml/README.md b/Godeps/_workspace/src/github.com/coreos/yaml/README.md index af07056..4427005 100644 --- a/Godeps/_workspace/src/github.com/coreos/yaml/README.md +++ b/Godeps/_workspace/src/github.com/coreos/yaml/README.md @@ -1,3 +1,6 @@ +Note: This is a fork of https://github.com/go-yaml/yaml. The following README +doesn't necessarily apply to this fork. + # YAML support for the Go language Introduction diff --git a/Godeps/_workspace/src/github.com/coreos/yaml/decode.go b/Godeps/_workspace/src/github.com/coreos/yaml/decode.go index a098626..e219d4b 100644 --- a/Godeps/_workspace/src/github.com/coreos/yaml/decode.go +++ b/Godeps/_workspace/src/github.com/coreos/yaml/decode.go @@ -30,13 +30,15 @@ type node struct { // Parser, produces a node tree out of a libyaml event stream. type parser struct { - parser yaml_parser_t - event yaml_event_t - doc *node + parser yaml_parser_t + event yaml_event_t + doc *node + transform transformString } -func newParser(b []byte) *parser { - p := parser{} +func newParser(b []byte, t transformString) *parser { + p := parser{transform: t} + if !yaml_parser_initialize(&p.parser) { panic("Failed to initialize YAML emitter") } @@ -175,7 +177,10 @@ func (p *parser) mapping() *node { p.anchor(n, p.event.anchor) p.skip() for p.event.typ != yaml_MAPPING_END_EVENT { - n.children = append(n.children, p.parse(), p.parse()) + key := p.parse() + key.value = p.transform(key.value) + value := p.parse() + n.children = append(n.children, key, value) } p.skip() return n diff --git a/Godeps/_workspace/src/github.com/coreos/yaml/decode_test.go b/Godeps/_workspace/src/github.com/coreos/yaml/decode_test.go index ef3d37f..349bee7 100644 --- a/Godeps/_workspace/src/github.com/coreos/yaml/decode_test.go +++ b/Godeps/_workspace/src/github.com/coreos/yaml/decode_test.go @@ -1,8 +1,8 @@ package yaml_test import ( + "github.com/coreos/yaml" . "gopkg.in/check.v1" - "gopkg.in/yaml.v1" "math" "reflect" "strings" @@ -557,6 +557,23 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) { c.Assert(m["ghi"].value, Equals, 3) } +func (s *S) TestUnmarshalWithTransform(c *C) { + data := `{a_b: 1, c-d: 2, e-f_g: 3, h_i-j: 4}` + expect := map[string]int{ + "a_b": 1, + "c_d": 2, + "e_f_g": 3, + "h_i_j": 4, + } + m := map[string]int{} + yaml.UnmarshalMappingKeyTransform = func(i string) string { + return strings.Replace(i, "-", "_", -1) + } + err := yaml.Unmarshal([]byte(data), m) + c.Assert(err, IsNil) + c.Assert(m, DeepEquals, expect) +} + // From http://yaml.org/type/merge.html var mergeTests = ` anchors: diff --git a/Godeps/_workspace/src/github.com/coreos/yaml/encode_test.go b/Godeps/_workspace/src/github.com/coreos/yaml/encode_test.go index c9febc2..2cd0ea7 100644 --- a/Godeps/_workspace/src/github.com/coreos/yaml/encode_test.go +++ b/Godeps/_workspace/src/github.com/coreos/yaml/encode_test.go @@ -7,8 +7,8 @@ import ( "strings" "time" + "github.com/coreos/yaml" . "gopkg.in/check.v1" - "gopkg.in/yaml.v1" ) var marshalIntTest = 123 diff --git a/Godeps/_workspace/src/github.com/coreos/yaml/yaml.go b/Godeps/_workspace/src/github.com/coreos/yaml/yaml.go index f1c390e..16e1365 100644 --- a/Godeps/_workspace/src/github.com/coreos/yaml/yaml.go +++ b/Godeps/_workspace/src/github.com/coreos/yaml/yaml.go @@ -84,7 +84,7 @@ type Getter interface { func Unmarshal(in []byte, out interface{}) (err error) { defer handleErr(&err) d := newDecoder() - p := newParser(in) + p := newParser(in, UnmarshalMappingKeyTransform) defer p.destroy() node := p.parse() if node != nil { @@ -146,6 +146,17 @@ func Marshal(in interface{}) (out []byte, err error) { return } +// UnmarshalMappingKeyTransform is a string transformation that is applied to +// each mapping key in a YAML document before it is unmarshalled. By default, +// UnmarshalMappingKeyTransform is an identity transform (no modification). +var UnmarshalMappingKeyTransform transformString = identityTransform + +type transformString func(in string) (out string) + +func identityTransform(in string) (out string) { + return in +} + // -------------------------------------------------------------------------- // Maintain a mapping of keys to structure field indexes From 248536a5cd9e2c21b8ce42fb16c5cb0993bdac10 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sat, 20 Dec 2014 17:57:15 -0800 Subject: [PATCH 05/56] config: use a YAML transform to normalize keys This removes the problematic two-pass unmarshalling. --- config/config.go | 41 +++--------------- config/config_test.go | 98 ++++++++++++++++--------------------------- 2 files changed, 41 insertions(+), 98 deletions(-) diff --git a/config/config.go b/config/config.go index 1cdad17..9a80ff3 100644 --- a/config/config.go +++ b/config/config.go @@ -63,15 +63,12 @@ func IsCloudConfig(userdata string) bool { // string of YAML), returning any error encountered. It will ignore unknown // fields but log encountering them. func NewCloudConfig(contents string) (*CloudConfig, error) { + yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { + return strings.Replace(nameIn, "-", "_", -1) + } var cfg CloudConfig - ncontents, err := normalizeConfig(contents) - if err != nil { - return &cfg, err - } - if err = yaml.Unmarshal(ncontents, &cfg); err != nil { - return &cfg, err - } - return &cfg, nil + err := yaml.Unmarshal([]byte(contents), &cfg) + return &cfg, err } func (cc CloudConfig) String() string { @@ -159,31 +156,3 @@ func isZero(v reflect.Value) bool { func isFieldExported(f reflect.StructField) bool { return f.PkgPath == "" } - -func normalizeConfig(config string) ([]byte, error) { - var cfg map[interface{}]interface{} - if err := yaml.Unmarshal([]byte(config), &cfg); err != nil { - return nil, err - } - return yaml.Marshal(normalizeKeys(cfg)) -} - -func normalizeKeys(m map[interface{}]interface{}) map[interface{}]interface{} { - for k, v := range m { - if m, ok := m[k].(map[interface{}]interface{}); ok { - normalizeKeys(m) - } - - if s, ok := m[k].([]interface{}); ok { - for _, e := range s { - if m, ok := e.(map[interface{}]interface{}); ok { - normalizeKeys(m) - } - } - } - - delete(m, k) - m[strings.Replace(fmt.Sprint(k), "-", "_", -1)] = v - } - return m -} diff --git a/config/config_test.go b/config/config_test.go index 7cc6756..b1516be 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -22,6 +22,42 @@ import ( "testing" ) +func TestNewCloudConfig(t *testing.T) { + tests := []struct { + contents string + + config CloudConfig + }{ + {}, + { + contents: "#cloud-config\nwrite_files:\n - path: underscore", + config: CloudConfig{WriteFiles: []File{File{Path: "underscore"}}}, + }, + { + contents: "#cloud-config\nwrite-files:\n - path: hyphen", + config: CloudConfig{WriteFiles: []File{File{Path: "hyphen"}}}, + }, + { + contents: "#cloud-config\ncoreos:\n update:\n reboot-strategy: off", + config: CloudConfig{CoreOS: CoreOS{Update: Update{RebootStrategy: "off"}}}, + }, + { + contents: "#cloud-config\ncoreos:\n update:\n reboot-strategy: false", + config: CloudConfig{CoreOS: CoreOS{Update: Update{RebootStrategy: "false"}}}, + }, + } + + for i, tt := range tests { + config, err := NewCloudConfig(tt.contents) + if err != nil { + t.Errorf("bad error (test case #%d): want %v, got %s", i, nil, err) + } + if !reflect.DeepEqual(&tt.config, config) { + t.Errorf("bad config (test case #%d): want %#v, got %#v", i, tt.config, config) + } + } +} + func TestIsZero(t *testing.T) { tests := []struct { c interface{} @@ -251,40 +287,6 @@ Address=10.209.171.177/19 if cfg.CoreOS.Update.RebootStrategy != "reboot" { t.Errorf("Failed to parse locksmith strategy") } - - contents = ` -coreos: -write_files: - - path: /home/me/notes - permissions: 0744 -` - cfg, err = NewCloudConfig(contents) - if err != nil { - t.Fatalf("Encountered unexpected error :%v", err) - } - - if len(cfg.WriteFiles) != 1 { - t.Error("Failed to parse correct number of write_files") - } else { - wf := cfg.WriteFiles[0] - if wf.Content != "" { - t.Errorf("WriteFile has incorrect contents '%s'", wf.Content) - } - if wf.Encoding != "" { - t.Errorf("WriteFile has incorrect encoding %s", wf.Encoding) - } - // Verify that the normalization of the config converted 0744 to its decimal - // representation, 484. - if wf.RawFilePermissions != "484" { - t.Errorf("WriteFile has incorrect permissions %s", wf.RawFilePermissions) - } - if wf.Path != "/home/me/notes" { - t.Errorf("WriteFile has incorrect path %s", wf.Path) - } - if wf.Owner != "" { - t.Errorf("WriteFile has incorrect owner %s", wf.Owner) - } - } } // Assert that our interface conversion doesn't panic @@ -451,31 +453,3 @@ users: t.Errorf("ssh import url is %q, expected 'https://token:x-auth-token@github.enterprise.com/api/v3/polvi/keys'", user.SSHImportURL) } } - -func TestNormalizeKeys(t *testing.T) { - for _, tt := range []struct { - in string - out string - }{ - {"my_key_name: the-value\n", "my_key_name: the-value\n"}, - {"my-key_name: the-value\n", "my_key_name: the-value\n"}, - {"my-key-name: the-value\n", "my_key_name: the-value\n"}, - - {"a:\n- key_name: the-value\n", "a:\n- key_name: the-value\n"}, - {"a:\n- key-name: the-value\n", "a:\n- key_name: the-value\n"}, - - {"a:\n b:\n - key_name: the-value\n", "a:\n b:\n - key_name: the-value\n"}, - {"a:\n b:\n - key-name: the-value\n", "a:\n b:\n - key_name: the-value\n"}, - - {"coreos:\n update:\n reboot-strategy: off\n", "coreos:\n update:\n reboot_strategy: false\n"}, - {"coreos:\n update:\n reboot-strategy: 'off'\n", "coreos:\n update:\n reboot_strategy: \"off\"\n"}, - } { - out, err := normalizeConfig(tt.in) - if err != nil { - t.Fatalf("bad error (%q): want nil, got %s", tt.in, err) - } - if string(out) != tt.out { - t.Fatalf("bad normalization (%q): want %q, got %q", tt.in, tt.out, out) - } - } -} From 40d943fb7a345559ac3d493fffd2caed9216bd2c Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sat, 20 Dec 2014 18:04:45 -0800 Subject: [PATCH 06/56] reboot-strategy: remove the 'false' value Since we no longer do a two-stage unmarshal, the 'false' value will no longer be necessary. --- config/update.go | 2 +- system/update.go | 2 +- system/update_test.go | 19 +------------------ 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/config/update.go b/config/update.go index 723f244..a42a3e1 100644 --- a/config/update.go +++ b/config/update.go @@ -17,7 +17,7 @@ package config type Update struct { - RebootStrategy string `yaml:"reboot_strategy" env:"REBOOT_STRATEGY" valid:"best-effort,etcd-lock,reboot,off,false"` + RebootStrategy string `yaml:"reboot_strategy" env:"REBOOT_STRATEGY" valid:"best-effort,etcd-lock,reboot,off"` Group string `yaml:"group" env:"GROUP"` Server string `yaml:"server" env:"SERVER"` } diff --git a/system/update.go b/system/update.go index bd745da..dd21515 100644 --- a/system/update.go +++ b/system/update.go @@ -126,7 +126,7 @@ func (uc Update) Units() []Unit { Runtime: true, }} - if uc.Update.RebootStrategy == "false" || uc.Update.RebootStrategy == "off" { + if uc.Update.RebootStrategy == "off" { ls.Command = "stop" ls.Mask = true } diff --git a/system/update_test.go b/system/update_test.go index 4ebf70b..822add0 100644 --- a/system/update_test.go +++ b/system/update_test.go @@ -71,15 +71,6 @@ func TestUpdateUnits(t *testing.T) { Runtime: true, }}}, }, - { - config: config.Update{RebootStrategy: "false"}, - units: []Unit{{config.Unit{ - Name: "locksmithd.service", - Command: "stop", - Runtime: true, - Mask: true, - }}}, - }, { config: config.Update{RebootStrategy: "off"}, units: []Unit{{config.Unit{ @@ -109,7 +100,7 @@ func TestUpdateFile(t *testing.T) { }, { config: config.Update{RebootStrategy: "wizzlewazzle"}, - err: &config.ErrorValid{Value: "wizzlewazzle", Field: "RebootStrategy", Valid: []string{"best-effort", "etcd-lock", "reboot", "off", "false"}}, + err: &config.ErrorValid{Value: "wizzlewazzle", Field: "RebootStrategy", Valid: []string{"best-effort", "etcd-lock", "reboot", "off"}}, }, { config: config.Update{Group: "master", Server: "http://foo.com"}, @@ -143,14 +134,6 @@ func TestUpdateFile(t *testing.T) { RawFilePermissions: "0644", }}, }, - { - config: config.Update{RebootStrategy: "false"}, - file: &File{config.File{ - Content: "REBOOT_STRATEGY=false\n", - Path: "etc/coreos/update.conf", - RawFilePermissions: "0644", - }}, - }, { config: config.Update{RebootStrategy: "off"}, file: &File{config.File{ From af8e5905758066b683ebdbbe600ab2d8e08b8bb3 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sat, 20 Dec 2014 23:26:05 -0800 Subject: [PATCH 07/56] config: change valid tag to use regexp A regular expression is much more useful than a list of strings. --- config/config.go | 14 ++++++------- config/config_test.go | 48 ++++++++++++++++++++++++++++++++++--------- config/file.go | 2 +- config/file_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++ config/unit.go | 2 +- config/unit_test.go | 46 +++++++++++++++++++++++++++++++++++++++++ config/update.go | 2 +- config/update_test.go | 43 ++++++++++++++++++++++++++++++++++++++ system/update_test.go | 2 +- 9 files changed, 186 insertions(+), 21 deletions(-) create mode 100644 config/file_test.go create mode 100644 config/unit_test.go create mode 100644 config/update_test.go diff --git a/config/config.go b/config/config.go index 9a80ff3..33eaef9 100644 --- a/config/config.go +++ b/config/config.go @@ -19,6 +19,7 @@ package config import ( "fmt" "reflect" + "regexp" "strings" "github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/coreos/yaml" @@ -91,7 +92,7 @@ func IsZero(c interface{}) bool { type ErrorValid struct { Value string - Valid []string + Valid string Field string } @@ -125,16 +126,15 @@ func AssertValid(value reflect.Value, valid string) *ErrorValid { if valid == "" || isZero(value) { return nil } + vs := fmt.Sprintf("%v", value.Interface()) - valids := strings.Split(valid, ",") - for _, valid := range valids { - if vs == valid { - return nil - } + if m, _ := regexp.MatchString(valid, vs); m { + return nil } + return &ErrorValid{ Value: vs, - Valid: valids, + Valid: valid, } } diff --git a/config/config_test.go b/config/config_test.go index b1516be..f4b7bc4 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -18,6 +18,7 @@ package config import ( "reflect" + "regexp" "strings" "testing" ) @@ -88,29 +89,29 @@ func TestAssertStructValid(t *testing.T) { }{ {struct{}{}, nil}, {struct { - A, b string `valid:"1,2"` + A, b string `valid:"^1|2$"` }{}, nil}, {struct { - A, b string `valid:"1,2"` + A, b string `valid:"^1|2$"` }{A: "1", b: "2"}, nil}, {struct { - A, b string `valid:"1,2"` + A, b string `valid:"^1|2$"` }{A: "1", b: "hello"}, nil}, {struct { - A, b string `valid:"1,2"` - }{A: "hello", b: "2"}, &ErrorValid{Value: "hello", Field: "A", Valid: []string{"1", "2"}}}, + A, b string `valid:"^1|2$"` + }{A: "hello", b: "2"}, &ErrorValid{Value: "hello", Field: "A", Valid: "^1|2$"}}, {struct { - A, b int `valid:"1,2"` + A, b int `valid:"^1|2$"` }{}, nil}, {struct { - A, b int `valid:"1,2"` + A, b int `valid:"^1|2$"` }{A: 1, b: 2}, nil}, {struct { - A, b int `valid:"1,2"` + A, b int `valid:"^1|2$"` }{A: 1, b: 9}, nil}, {struct { - A, b int `valid:"1,2"` - }{A: 9, b: 2}, &ErrorValid{Value: "9", Field: "A", Valid: []string{"1", "2"}}}, + A, b int `valid:"^1|2$"` + }{A: 9, b: 2}, &ErrorValid{Value: "9", Field: "A", Valid: "^1|2$"}}, } for _, tt := range tests { @@ -120,6 +121,33 @@ func TestAssertStructValid(t *testing.T) { } } +func TestConfigCompile(t *testing.T) { + tests := []interface{}{ + Etcd{}, + File{}, + Flannel{}, + Fleet{}, + Locksmith{}, + OEM{}, + Unit{}, + Update{}, + } + + for _, tt := range tests { + ttt := reflect.TypeOf(tt) + for i := 0; i < ttt.NumField(); i++ { + ft := ttt.Field(i) + if !isFieldExported(ft) { + continue + } + + if _, err := regexp.Compile(ft.Tag.Get("valid")); err != nil { + t.Errorf("bad regexp(%s.%s): want %v, got %s", ttt.Name(), ft.Name, nil, err) + } + } + } +} + func TestCloudConfigUnknownKeys(t *testing.T) { contents := ` coreos: diff --git a/config/file.go b/config/file.go index 26dbc99..04f12c2 100644 --- a/config/file.go +++ b/config/file.go @@ -17,7 +17,7 @@ package config type File struct { - Encoding string `yaml:"encoding" valid:"base64,b64,gz,gzip,gz+base64,gzip+base64,gz+b64,gzip+b64"` + Encoding string `yaml:"encoding" valid:"^(base64|b64|gz|gzip|gz\\+base64|gzip\\+base64|gz\\+b64|gzip\\+b64)$"` Content string `yaml:"content"` Owner string `yaml:"owner"` Path string `yaml:"path"` diff --git a/config/file_test.go b/config/file_test.go new file mode 100644 index 0000000..a1e03e2 --- /dev/null +++ b/config/file_test.go @@ -0,0 +1,48 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package config + +import ( + "testing" +) + +func TestEncodingValid(t *testing.T) { + tests := []struct { + value string + + isValid bool + }{ + {value: "base64", isValid: true}, + {value: "b64", isValid: true}, + {value: "gz", isValid: true}, + {value: "gzip", isValid: true}, + {value: "gz+base64", isValid: true}, + {value: "gzip+base64", isValid: true}, + {value: "gz+b64", isValid: true}, + {value: "gzip+b64", isValid: true}, + {value: "gzzzzbase64", isValid: false}, + {value: "gzipppbase64", isValid: false}, + {value: "unknown", isValid: false}, + } + + for _, tt := range tests { + isValid := (nil == AssertStructValid(File{Encoding: tt.value})) + if tt.isValid != isValid { + t.Errorf("bad assert (%s): want %t, got %t", tt.value, tt.isValid, isValid) + } + } +} diff --git a/config/unit.go b/config/unit.go index 3a09bbb..a86bc8c 100644 --- a/config/unit.go +++ b/config/unit.go @@ -22,7 +22,7 @@ type Unit struct { Enable bool `yaml:"enable"` Runtime bool `yaml:"runtime"` Content string `yaml:"content"` - Command string `yaml:"command" valid:"start,stop,restart,reload,try-restart,reload-or-restart,reload-or-try-restart"` + Command string `yaml:"command" valid:"^(start|stop|restart|reload|try-restart|reload-or-restart|reload-or-try-restart)$"` DropIns []UnitDropIn `yaml:"drop_ins"` } diff --git a/config/unit_test.go b/config/unit_test.go new file mode 100644 index 0000000..d94dd8b --- /dev/null +++ b/config/unit_test.go @@ -0,0 +1,46 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package config + +import ( + "testing" +) + +func TestCommandValid(t *testing.T) { + tests := []struct { + value string + + isValid bool + }{ + {value: "start", isValid: true}, + {value: "stop", isValid: true}, + {value: "restart", isValid: true}, + {value: "reload", isValid: true}, + {value: "try-restart", isValid: true}, + {value: "reload-or-restart", isValid: true}, + {value: "reload-or-try-restart", isValid: true}, + {value: "tryrestart", isValid: false}, + {value: "unknown", isValid: false}, + } + + for _, tt := range tests { + isValid := (nil == AssertStructValid(Unit{Command: tt.value})) + if tt.isValid != isValid { + t.Errorf("bad assert (%s): want %t, got %t", tt.value, tt.isValid, isValid) + } + } +} diff --git a/config/update.go b/config/update.go index a42a3e1..147085d 100644 --- a/config/update.go +++ b/config/update.go @@ -17,7 +17,7 @@ package config type Update struct { - RebootStrategy string `yaml:"reboot_strategy" env:"REBOOT_STRATEGY" valid:"best-effort,etcd-lock,reboot,off"` + RebootStrategy string `yaml:"reboot_strategy" env:"REBOOT_STRATEGY" valid:"^(best-effort|etcd-lock|reboot|off)$"` Group string `yaml:"group" env:"GROUP"` Server string `yaml:"server" env:"SERVER"` } diff --git a/config/update_test.go b/config/update_test.go new file mode 100644 index 0000000..2b0851e --- /dev/null +++ b/config/update_test.go @@ -0,0 +1,43 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package config + +import ( + "testing" +) + +func TestRebootStrategyValid(t *testing.T) { + tests := []struct { + value string + + isValid bool + }{ + {value: "best-effort", isValid: true}, + {value: "etcd-lock", isValid: true}, + {value: "reboot", isValid: true}, + {value: "off", isValid: true}, + {value: "besteffort", isValid: false}, + {value: "unknown", isValid: false}, + } + + for _, tt := range tests { + isValid := (nil == AssertStructValid(Update{RebootStrategy: tt.value})) + if tt.isValid != isValid { + t.Errorf("bad assert (%s): want %t, got %t", tt.value, tt.isValid, isValid) + } + } +} diff --git a/system/update_test.go b/system/update_test.go index 822add0..deeb66f 100644 --- a/system/update_test.go +++ b/system/update_test.go @@ -100,7 +100,7 @@ func TestUpdateFile(t *testing.T) { }, { config: config.Update{RebootStrategy: "wizzlewazzle"}, - err: &config.ErrorValid{Value: "wizzlewazzle", Field: "RebootStrategy", Valid: []string{"best-effort", "etcd-lock", "reboot", "off"}}, + err: &config.ErrorValid{Value: "wizzlewazzle", Field: "RebootStrategy", Valid: "^(best-effort|etcd-lock|reboot|off)$"}, }, { config: config.Update{Group: "master", Server: "http://foo.com"}, From 0e70d4f01f7e75841984dbacd509737de242c766 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sun, 21 Dec 2014 11:14:03 -0800 Subject: [PATCH 08/56] config: add validity check for file permissions --- config/file.go | 2 +- config/file_test.go | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/config/file.go b/config/file.go index 04f12c2..76b5827 100644 --- a/config/file.go +++ b/config/file.go @@ -21,5 +21,5 @@ type File struct { Content string `yaml:"content"` Owner string `yaml:"owner"` Path string `yaml:"path"` - RawFilePermissions string `yaml:"permissions"` + RawFilePermissions string `yaml:"permissions" valid:"^0?[0-7]{3,4}$"` } diff --git a/config/file_test.go b/config/file_test.go index a1e03e2..e3f0871 100644 --- a/config/file_test.go +++ b/config/file_test.go @@ -46,3 +46,26 @@ func TestEncodingValid(t *testing.T) { } } } + +func TestRawFilePermissionsValid(t *testing.T) { + tests := []struct { + value string + + isValid bool + }{ + {value: "744", isValid: true}, + {value: "0744", isValid: true}, + {value: "1744", isValid: true}, + {value: "01744", isValid: true}, + {value: "11744", isValid: false}, + {value: "rwxr--r--", isValid: false}, + {value: "800", isValid: false}, + } + + for _, tt := range tests { + isValid := (nil == AssertStructValid(File{RawFilePermissions: tt.value})) + if tt.isValid != isValid { + t.Errorf("bad assert (%s): want %t, got %t", tt.value, tt.isValid, isValid) + } + } +} From 54a64454b979c128b641beb8843a726baa4117ef Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sun, 21 Dec 2014 11:24:10 -0800 Subject: [PATCH 09/56] validate: fix printing for non-string values --- config/validate/rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/validate/rules.go b/config/validate/rules.go index 7651819..6da2772 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -76,7 +76,7 @@ func checkValidity(cfg node, report *Report) { func checkNodeValidity(n, g node, r *Report) { if err := config.AssertValid(n.Value, g.field.Tag.Get("valid")); err != nil { - r.Error(n.line, fmt.Sprintf("invalid value %v", n.Value)) + r.Error(n.line, fmt.Sprintf("invalid value %v", n.Value.Interface())) } switch g.Kind() { case reflect.Struct: From 5527f097787f159a7715fb8767d027b1008e36d2 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Sun, 21 Dec 2014 11:16:42 -0800 Subject: [PATCH 10/56] config: fix parsing of file permissions These reintroduces the braindead '744' syntax for file permissions. Even though this number isn't octal, it is assumed by convention to be. In order to pull this off, coerceNodes() was introduced to try to counteract the type inferrencing that occurs during the yaml unmarshalling. The config is unmarshalled twice: once into an empty interface and once into the CloudConfig structure. The two resulting node structures are combined together. The nodes from the CloudConfig process replace those from the interface{} when the types of the two nodes are compatible. For example, with the input `0744`, yaml interprets that as the integer 484 giving us the nodes '0744'(string) and 484(int). Because the types string and int are compatible, we opt to take the string node instead of the integer. --- config/config_test.go | 16 ++++++++ config/validate/validate.go | 66 +++++++++++++++++++++++++++----- config/validate/validate_test.go | 25 ++++++++++++ system/file.go | 2 +- system/file_test.go | 2 +- 5 files changed, 100 insertions(+), 11 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index f4b7bc4..0eaa4de 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -46,6 +46,22 @@ func TestNewCloudConfig(t *testing.T) { contents: "#cloud-config\ncoreos:\n update:\n reboot-strategy: false", config: CloudConfig{CoreOS: CoreOS{Update: Update{RebootStrategy: "false"}}}, }, + { + contents: "#cloud-config\nwrite_files:\n - permissions: 0744", + config: CloudConfig{WriteFiles: []File{File{RawFilePermissions: "0744"}}}, + }, + { + contents: "#cloud-config\nwrite_files:\n - permissions: 744", + config: CloudConfig{WriteFiles: []File{File{RawFilePermissions: "744"}}}, + }, + { + contents: "#cloud-config\nwrite_files:\n - permissions: '0744'", + config: CloudConfig{WriteFiles: []File{File{RawFilePermissions: "0744"}}}, + }, + { + contents: "#cloud-config\nwrite_files:\n - permissions: '744'", + config: CloudConfig{WriteFiles: []File{File{RawFilePermissions: "744"}}}, + }, } for i, tt := range tests { diff --git a/config/validate/validate.go b/config/validate/validate.go index 26ad0b5..02a2baa 100644 --- a/config/validate/validate.go +++ b/config/validate/validate.go @@ -65,7 +65,6 @@ func validateCloudConfig(config []byte, rules []rule) (report Report, err error) return report, err } - c = normalizeNodeNames(c, &report) for _, r := range rules { r(c, &report) } @@ -75,30 +74,79 @@ func validateCloudConfig(config []byte, rules []rule) (report Report, err error) // parseCloudConfig parses the provided config into a node structure and logs // any parsing issues into the provided report. Unrecoverable errors are // returned as an error. -func parseCloudConfig(config []byte, report *Report) (n node, err error) { - var raw map[interface{}]interface{} - if err := yaml.Unmarshal(config, &raw); err != nil { +func parseCloudConfig(cfg []byte, report *Report) (node, error) { + yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { + return nameIn + } + // unmarshal the config into an implicitly-typed form. The yaml library + // will implicitly convert types into their normalized form + // (e.g. 0744 -> 484, off -> false). + var weak map[interface{}]interface{} + if err := yaml.Unmarshal(cfg, &weak); err != nil { matches := yamlLineError.FindStringSubmatch(err.Error()) if len(matches) == 3 { line, err := strconv.Atoi(matches[1]) if err != nil { - return n, err + return node{}, err } msg := matches[2] report.Error(line, msg) - return n, nil + return node{}, nil } matches = yamlError.FindStringSubmatch(err.Error()) if len(matches) == 2 { report.Error(1, matches[1]) - return n, nil + return node{}, nil } - return n, errors.New("couldn't parse yaml error") + return node{}, errors.New("couldn't parse yaml error") + } + w := NewNode(weak, NewContext(cfg)) + w = normalizeNodeNames(w, report) + + // unmarshal the config into the explicitly-typed form. + yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { + return strings.Replace(nameIn, "-", "_", -1) + } + var strong config.CloudConfig + if err := yaml.Unmarshal([]byte(cfg), &strong); err != nil { + return node{}, err + } + s := NewNode(strong, NewContext(cfg)) + + // coerceNodes weak nodes and strong nodes. strong nodes replace weak nodes + // if they are compatible types (this happens when the yaml library + // converts the input). + // (e.g. weak 484 is replaced by strong 0744, weak 4 is not replaced by + // strong false) + return coerceNodes(w, s), nil +} + +// coerceNodes recursively evaluates two nodes, returning a new node containing +// either the weak or strong node's value and its recursively processed +// children. The strong node's value is used if the two nodes are leafs, are +// both valid, and are compatible types (defined by isCompatible()). The weak +// node is returned in all other cases. coerceNodes is used to counteract the +// effects of yaml's automatic type conversion. The weak node is the one +// resulting from unmarshalling into an empty interface{} (the type is +// inferred). The strong node is the one resulting from unmarshalling into a +// struct. If the two nodes are of compatible types, the yaml library correctly +// parsed the value into the strongly typed unmarshalling. In this case, we +// prefer the strong node because its actually the type we are expecting. +func coerceNodes(w, s node) node { + n := w + n.children = nil + if len(w.children) == 0 && len(s.children) == 0 && + w.IsValid() && s.IsValid() && + isCompatible(w.Kind(), s.Kind()) { + n.Value = s.Value } - return NewNode(raw, NewContext(config)), nil + for _, cw := range w.children { + n.children = append(n.children, coerceNodes(cw, s.Child(cw.name))) + } + return n } // normalizeNodeNames replaces all occurences of '-' with '_' within key names diff --git a/config/validate/validate_test.go b/config/validate/validate_test.go index b390eda..328878b 100644 --- a/config/validate/validate_test.go +++ b/config/validate/validate_test.go @@ -65,6 +65,31 @@ func TestValidateCloudConfig(t *testing.T) { rules: []rule{func(_ node, _ *Report) { panic("something happened") }}, err: errors.New("something happened"), }, + { + config: "write_files:\n - permissions: 0744", + rules: Rules, + }, + { + config: "write_files:\n - permissions: '0744'", + rules: Rules, + }, + { + config: "write_files:\n - permissions: 744", + rules: Rules, + }, + { + config: "write_files:\n - permissions: '744'", + rules: Rules, + }, + { + config: "coreos:\n update:\n reboot-strategy: off", + rules: Rules, + }, + { + config: "coreos:\n update:\n reboot-strategy: false", + rules: Rules, + report: Report{entries: []Entry{{entryError, "invalid value false", 3}}}, + }, } for _, tt := range tests { diff --git a/system/file.go b/system/file.go index 312caf4..22118c1 100644 --- a/system/file.go +++ b/system/file.go @@ -43,7 +43,7 @@ func (f *File) Permissions() (os.FileMode, error) { } // Parse string representation of file mode as integer - perm, err := strconv.ParseInt(f.RawFilePermissions, 0, 32) + perm, err := strconv.ParseInt(f.RawFilePermissions, 8, 32) if err != nil { return 0, fmt.Errorf("Unable to parse file permissions %q as integer", f.RawFilePermissions) } diff --git a/system/file_test.go b/system/file_test.go index 8bd441b..eb6f947 100644 --- a/system/file_test.go +++ b/system/file_test.go @@ -97,7 +97,7 @@ func TestDecimalFilePermissions(t *testing.T) { wf := File{config.File{ Path: fn, - RawFilePermissions: "484", // Decimal representation of 0744 + RawFilePermissions: "744", }} path, err := WriteFile(&wf, dir) From c8e864fef505e6445fbf3c085439445e77b6b6f4 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 30 Dec 2014 16:51:24 +0100 Subject: [PATCH 11/56] coreos-cloudinit: bump to v1.1.0 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 7bde360..95b1809 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.0.2+git" + version = "1.1.0" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 54c62cbb70322d939be95fdf34eb85167feca702 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 30 Dec 2014 16:52:10 +0100 Subject: [PATCH 12/56] coreos-cloudinit: bump to v1.1.0+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 95b1809..e877cc5 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.1.0" + version = "1.1.0+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 13e4b7713015a255c55a7c0d058a8586977f890f Mon Sep 17 00:00:00 2001 From: Kevin Yung Date: Fri, 2 Jan 2015 11:38:37 +1100 Subject: [PATCH 13/56] ec2: allow spaces seperated hostname in metadata AWS hostname metadata will return space seperated hostname and domain names when DHCPOptionSet is using multiple domain names. This patch will cater for this scenario. --- datasource/metadata/ec2/metadata.go | 2 +- datasource/metadata/ec2/metadata_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/datasource/metadata/ec2/metadata.go b/datasource/metadata/ec2/metadata.go index 039c994..85e973e 100644 --- a/datasource/metadata/ec2/metadata.go +++ b/datasource/metadata/ec2/metadata.go @@ -69,7 +69,7 @@ func (ms metadataService) FetchMetadata() ([]byte, error) { } if hostname, err := ms.fetchAttribute(fmt.Sprintf("%s/hostname", ms.MetadataUrl())); err == nil { - attrs["hostname"] = hostname + attrs["hostname"] = strings.Split(hostname, " ")[0] } else if _, ok := err.(pkg.ErrNotFound); !ok { return nil, err } diff --git a/datasource/metadata/ec2/metadata_test.go b/datasource/metadata/ec2/metadata_test.go index a2a30c3..5f4a538 100644 --- a/datasource/metadata/ec2/metadata_test.go +++ b/datasource/metadata/ec2/metadata_test.go @@ -173,6 +173,20 @@ func TestFetchMetadata(t *testing.T) { }, expect: []byte(`{"hostname":"host","local-ipv4":"1.2.3.4","network_config":{"content_path":"path"},"public-ipv4":"5.6.7.8","public_keys":{"test1":"key"}}`), }, + { + root: "/", + metadataPath: "2009-04-04/meta-data", + resources: map[string]string{ + "/2009-04-04/meta-data/hostname": "host domain another_domain", + "/2009-04-04/meta-data/local-ipv4": "1.2.3.4", + "/2009-04-04/meta-data/public-ipv4": "5.6.7.8", + "/2009-04-04/meta-data/public-keys": "0=test1\n", + "/2009-04-04/meta-data/public-keys/0": "openssh-key", + "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", + "/2009-04-04/meta-data/network_config/content_path": "path", + }, + expect: []byte(`{"hostname":"host","local-ipv4":"1.2.3.4","network_config":{"content_path":"path"},"public-ipv4":"5.6.7.8","public_keys":{"test1":"key"}}`), + }, { clientErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")}, expectErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")}, From 58f0dadaf9524b143b93fd95662dcaa0c45713e0 Mon Sep 17 00:00:00 2001 From: Eugene Yakubovich Date: Tue, 13 Jan 2015 15:49:33 -0800 Subject: [PATCH 14/56] config: document and update flannel config values Fixes #297 --- Documentation/cloud-config.md | 12 ++++++++++-- config/flannel.go | 13 ++++++++----- system/flannel_test.go | 12 ++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index 79f93f9..f08d795 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -109,7 +109,7 @@ flanneld. For example, the following cloud-config... coreos: flannel: - etcd-prefix: /coreos.com/network2 + etcd_prefix: /coreos.com/network2 ``` ...will generate a systemd unit drop-in like so: @@ -119,7 +119,15 @@ coreos: Environment="FLANNELD_ETCD_PREFIX=/coreos.com/network2" ``` -For the complete list of flannel configuraion parameters, see the [flannel documentation][flannel-readme]. +List of flannel configuration parameters: +- **etcd_endpoints**: Comma separated list of etcd endpoints +- **etcd_cafile**: Path to CA file used for TLS communication with etcd +- **etcd_certfile**: Path to certificate file used for TLS communication with etcd +- **etcd_keyfile**: Path to private key file used for TLS communication with etcd +- **etcd_prefix**: Etcd prefix path to be used for flannel keys +- **ip_masq**: Install IP masquerade rules for traffic outside of flannel subnet +- **subnet_file**: Path to flannel subnet file to write out +- **interface**: Interface (name or IP) that should be used for inter-host communication [flannel-readme]: https://github.com/coreos/flannel/blob/master/README.md diff --git a/config/flannel.go b/config/flannel.go index d7f4d0d..bc8af2d 100644 --- a/config/flannel.go +++ b/config/flannel.go @@ -1,9 +1,12 @@ package config type Flannel struct { - EtcdEndpoint string `yaml:"etcd_endpoint" env:"FLANNELD_ETCD_ENDPOINT"` - EtcdPrefix string `yaml:"etcd_prefix" env:"FLANNELD_ETCD_PREFIX"` - IPMasq string `yaml:"ip_masq" env:"FLANNELD_IP_MASQ"` - SubnetFile string `yaml:"subnet_file" env:"FLANNELD_SUBNET_FILE"` - Iface string `yaml:"interface" env:"FLANNELD_IFACE"` + EtcdEndpoints string `yaml:"etcd_endpoints" env:"FLANNELD_ETCD_ENDPOINTS"` + EtcdCAFile string `yaml:"etcd_cafile" env:"FLANNELD_ETCD_CAFILE"` + EtcdCertFile string `yaml:"etcd_certfile" env:"FLANNELD_ETCD_CERTFILE"` + EtcdKeyFile string `yaml:"etcd_keyfile" env:"FLANNELD_ETCD_KEYFILE"` + EtcdPrefix string `yaml:"etcd_prefix" env:"FLANNELD_ETCD_PREFIX"` + IPMasq string `yaml:"ip_masq" env:"FLANNELD_IP_MASQ"` + SubnetFile string `yaml:"subnet_file" env:"FLANNELD_SUBNET_FILE"` + Iface string `yaml:"interface" env:"FLANNELD_IFACE"` } diff --git a/system/flannel_test.go b/system/flannel_test.go index 4eec6b9..7531e80 100644 --- a/system/flannel_test.go +++ b/system/flannel_test.go @@ -18,10 +18,10 @@ func TestFlannelEnvVars(t *testing.T) { }, { config.Flannel{ - EtcdEndpoint: "http://12.34.56.78:4001", - EtcdPrefix: "/coreos.com/network/tenant1", + EtcdEndpoints: "http://12.34.56.78:4001", + EtcdPrefix: "/coreos.com/network/tenant1", }, - `FLANNELD_ETCD_ENDPOINT=http://12.34.56.78:4001 + `FLANNELD_ETCD_ENDPOINTS=http://12.34.56.78:4001 FLANNELD_ETCD_PREFIX=/coreos.com/network/tenant1`, }, } { @@ -43,13 +43,13 @@ func TestFlannelFile(t *testing.T) { }, { config.Flannel{ - EtcdEndpoint: "http://12.34.56.78:4001", - EtcdPrefix: "/coreos.com/network/tenant1", + EtcdEndpoints: "http://12.34.56.78:4001", + EtcdPrefix: "/coreos.com/network/tenant1", }, &File{config.File{ Path: "run/flannel/options.env", RawFilePermissions: "0644", - Content: `FLANNELD_ETCD_ENDPOINT=http://12.34.56.78:4001 + Content: `FLANNELD_ETCD_ENDPOINTS=http://12.34.56.78:4001 FLANNELD_ETCD_PREFIX=/coreos.com/network/tenant1`, }}, }, From fc77ba6355f62741909f471546e326009e2bafbd Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 14 Jan 2015 17:54:01 -0800 Subject: [PATCH 15/56] validate: allow promotion of int to float64 --- config/validate/rules.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/validate/rules.go b/config/validate/rules.go index 6da2772..e1e6ad5 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -107,7 +107,9 @@ func isCompatible(n, g reflect.Kind) bool { return n == reflect.String || n == reflect.Int || n == reflect.Float64 || n == reflect.Bool case reflect.Struct: return n == reflect.Struct || n == reflect.Map - case reflect.Bool, reflect.Slice, reflect.Int, reflect.Float64: + case reflect.Float64: + return n == reflect.Float64 || n == reflect.Int + case reflect.Bool, reflect.Slice, reflect.Int: return n == g default: panic(fmt.Sprintf("isCompatible(): unhandled kind %s", g)) From bdbd1930eda31eae6e999c92fab679ae6cd8dfbd Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 12 Jan 2015 12:25:28 -0800 Subject: [PATCH 16/56] config/validate: add rule for file paths --- config/validate/rules.go | 51 ++++++++++++++++++++++++----------- config/validate/rules_test.go | 37 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/config/validate/rules.go b/config/validate/rules.go index e1e6ad5..459877d 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -18,7 +18,9 @@ package validate import ( "fmt" + "path" "reflect" + "strings" "github.com/coreos/coreos-cloudinit/config" ) @@ -29,6 +31,7 @@ type rule func(config node, report *Report) var Rules []rule = []rule{ checkStructure, checkValidity, + checkWriteFiles, } // checkStructure compares the provided config to the empty config.CloudConfig @@ -67,6 +70,24 @@ func checkNodeStructure(n, g node, r *Report) { } } +// isCompatible determines if the type of kind n can be converted to the type +// of kind g in the context of YAML. This is not an exhaustive list, but its +// enough for the purposes of cloud-config validation. +func isCompatible(n, g reflect.Kind) bool { + switch g { + case reflect.String: + return n == reflect.String || n == reflect.Int || n == reflect.Float64 || n == reflect.Bool + case reflect.Struct: + return n == reflect.Struct || n == reflect.Map + case reflect.Float64: + return n == reflect.Float64 || n == reflect.Int + case reflect.Bool, reflect.Slice, reflect.Int: + return n == g + default: + panic(fmt.Sprintf("isCompatible(): unhandled kind %s", g)) + } +} + // checkValidity checks the value of every node in the provided config by // running config.AssertValid() on it. func checkValidity(cfg node, report *Report) { @@ -98,20 +119,20 @@ func checkNodeValidity(n, g node, r *Report) { } } -// isCompatible determines if the type of kind n can be converted to the type -// of kind g in the context of YAML. This is not an exhaustive list, but its -// enough for the purposes of cloud-config validation. -func isCompatible(n, g reflect.Kind) bool { - switch g { - case reflect.String: - return n == reflect.String || n == reflect.Int || n == reflect.Float64 || n == reflect.Bool - case reflect.Struct: - return n == reflect.Struct || n == reflect.Map - case reflect.Float64: - return n == reflect.Float64 || n == reflect.Int - case reflect.Bool, reflect.Slice, reflect.Int: - return n == g - default: - panic(fmt.Sprintf("isCompatible(): unhandled kind %s", g)) +// checkWriteFiles checks to make sure that the target file can actually be +// written. Note that this check is approximate (it only checks to see if the file +// is under /usr). +func checkWriteFiles(cfg node, report *Report) { + for _, f := range cfg.Child("write_files").children { + c := f.Child("path") + if !c.IsValid() { + continue + } + + d := path.Dir(c.String()) + switch { + case strings.HasPrefix(d, "/usr"): + report.Error(c.line, "file cannot be written to a read-only filesystem") + } } } diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index ab6d157..55f4387 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -249,3 +249,40 @@ func TestCheckValidity(t *testing.T) { } } } + +func TestCheckWriteFiles(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "write_files:\n - path: /valid", + }, + { + config: "write_files:\n - path: /tmp/usr/valid", + }, + { + config: "write_files:\n - path: /usr/invalid", + entries: []Entry{{entryError, "file cannot be written to a read-only filesystem", 2}}, + }, + { + config: "write-files:\n - path: /tmp/../usr/invalid", + entries: []Entry{{entryError, "file cannot be written to a read-only filesystem", 2}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkWriteFiles(n, &r) + + if e := r.Entries(); !reflect.DeepEqual(tt.entries, e) { + t.Errorf("bad report (%d, %q): want %#v, got %#v", i, tt.config, tt.entries, e) + } + } +} From 571903cec62ecefa2230e85ede5a5e48061b7443 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 12 Jan 2015 15:43:58 -0800 Subject: [PATCH 17/56] config/validate: add rule for etcd discovery token --- config/validate/rules.go | 14 ++++++++++++++ config/validate/rules_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/config/validate/rules.go b/config/validate/rules.go index 459877d..416e6ec 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -18,6 +18,7 @@ package validate import ( "fmt" + "net/url" "path" "reflect" "strings" @@ -29,11 +30,24 @@ type rule func(config node, report *Report) // Rules contains all of the validation rules. var Rules []rule = []rule{ + checkDiscoveryUrl, checkStructure, checkValidity, checkWriteFiles, } +// checkDiscoveryUrl verifies that the string is a valid url. +func checkDiscoveryUrl(cfg node, report *Report) { + c := cfg.Child("coreos").Child("etcd").Child("discovery") + if !c.IsValid() { + return + } + + if _, err := url.ParseRequestURI(c.String()); err != nil { + report.Warning(c.line, "discovery URL is not valid") + } +} + // checkStructure compares the provided config to the empty config.CloudConfig // structure. Each node is checked to make sure that it exists in the known // structure and that its type is compatible. diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index 55f4387..c767dff 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -21,6 +21,39 @@ import ( "testing" ) +func TestCheckDiscoveryUrl(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "coreos:\n etcd:\n discovery: https://discovery.etcd.io/00000000000000000000000000000000", + }, + { + config: "coreos:\n etcd:\n discovery: http://custom.domain/mytoken", + }, + { + config: "coreos:\n etcd:\n discovery: disco", + entries: []Entry{{entryWarning, "discovery URL is not valid", 3}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkDiscoveryUrl(n, &r) + + if e := r.Entries(); !reflect.DeepEqual(tt.entries, e) { + t.Errorf("bad report (%d, %q): want %#v, got %#v", i, tt.config, tt.entries, e) + } + } +} + func TestCheckStructure(t *testing.T) { tests := []struct { config string From f61c08c246ea5c756d0bb5068c0ae4af112b17b6 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 12 Jan 2015 16:09:21 -0800 Subject: [PATCH 18/56] config/validate: add rule for coreos.write_files --- config/validate/rules.go | 10 ++++++++++ config/validate/rules_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/config/validate/rules.go b/config/validate/rules.go index 416e6ec..f8397dc 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -34,6 +34,7 @@ var Rules []rule = []rule{ checkStructure, checkValidity, checkWriteFiles, + checkWriteFilesUnderCoreos, } // checkDiscoveryUrl verifies that the string is a valid url. @@ -150,3 +151,12 @@ func checkWriteFiles(cfg node, report *Report) { } } } + +// checkWriteFilesUnderCoreos checks to see if the 'write_files' node is a +// child of 'coreos' (it shouldn't be). +func checkWriteFilesUnderCoreos(cfg node, report *Report) { + c := cfg.Child("coreos").Child("write_files") + if c.IsValid() { + report.Info(c.line, "write_files doesn't belong under coreos") + } +} diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index c767dff..d37c181 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -319,3 +319,37 @@ func TestCheckWriteFiles(t *testing.T) { } } } + +func TestCheckWriteFilesUnderCoreos(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "write_files:\n - path: /hi", + }, + { + config: "coreos:\n write_files:\n - path: /hi", + entries: []Entry{{entryInfo, "write_files doesn't belong under coreos", 2}}, + }, + { + config: "coreos:\n write-files:\n - path: /hyphen", + entries: []Entry{{entryInfo, "write_files doesn't belong under coreos", 2}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkWriteFilesUnderCoreos(n, &r) + + if e := r.Entries(); !reflect.DeepEqual(tt.entries, e) { + t.Errorf("bad report (%d, %q): want %#v, got %#v", i, tt.config, tt.entries, e) + } + } +} From 3c93938f8a80ea269baa727322d4da012c77730c Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 13 Jan 2015 16:24:59 -0800 Subject: [PATCH 19/56] decode: refactor file decoding into config package --- config/decode.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ system/file.go | 54 +--------------------------------------------- 2 files changed, 57 insertions(+), 53 deletions(-) create mode 100644 config/decode.go diff --git a/config/decode.go b/config/decode.go new file mode 100644 index 0000000..f5847aa --- /dev/null +++ b/config/decode.go @@ -0,0 +1,56 @@ +package config + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "fmt" +) + +func DecodeBase64Content(content string) ([]byte, error) { + output, err := base64.StdEncoding.DecodeString(content) + + if err != nil { + return nil, fmt.Errorf("Unable to decode base64: %q", err) + } + + return output, nil +} + +func DecodeGzipContent(content string) ([]byte, error) { + gzr, err := gzip.NewReader(bytes.NewReader([]byte(content))) + + if err != nil { + return nil, fmt.Errorf("Unable to decode gzip: %q", err) + } + defer gzr.Close() + + buf := new(bytes.Buffer) + buf.ReadFrom(gzr) + + return buf.Bytes(), nil +} + +func DecodeContent(content string, encoding string) ([]byte, error) { + switch encoding { + case "": + return []byte(content), nil + + case "b64", "base64": + return DecodeBase64Content(content) + + case "gz", "gzip": + return DecodeGzipContent(content) + + case "gz+base64", "gzip+base64", "gz+b64", "gzip+b64": + gz, err := DecodeBase64Content(content) + + if err != nil { + return nil, err + } + + return DecodeGzipContent(string(gz)) + } + + return nil, fmt.Errorf("Unsupported encoding %q", encoding) +} diff --git a/system/file.go b/system/file.go index 22118c1..9454498 100644 --- a/system/file.go +++ b/system/file.go @@ -17,9 +17,6 @@ package system import ( - "bytes" - "compress/gzip" - "encoding/base64" "fmt" "io/ioutil" "log" @@ -50,61 +47,12 @@ func (f *File) Permissions() (os.FileMode, error) { return os.FileMode(perm), nil } -func DecodeBase64Content(content string) ([]byte, error) { - output, err := base64.StdEncoding.DecodeString(content) - - if err != nil { - return nil, fmt.Errorf("Unable to decode base64: %v", err) - } - - return output, nil -} - -func DecodeGzipContent(content string) ([]byte, error) { - gzr, err := gzip.NewReader(bytes.NewReader([]byte(content))) - - if err != nil { - return nil, fmt.Errorf("Unable to decode gzip: %v", err) - } - defer gzr.Close() - - buf := new(bytes.Buffer) - buf.ReadFrom(gzr) - - return buf.Bytes(), nil -} - -func DecodeContent(content string, encoding string) ([]byte, error) { - switch encoding { - case "": - return []byte(content), nil - - case "b64", "base64": - return DecodeBase64Content(content) - - case "gz", "gzip": - return DecodeGzipContent(content) - - case "gz+base64", "gzip+base64", "gz+b64", "gzip+b64": - gz, err := DecodeBase64Content(content) - - if err != nil { - return nil, err - } - - return DecodeGzipContent(string(gz)) - } - - return nil, fmt.Errorf("Unsupported encoding %s", encoding) - -} - func WriteFile(f *File, root string) (string, error) { fullpath := path.Join(root, f.Path) dir := path.Dir(fullpath) log.Printf("Writing file to %q", fullpath) - content, err := DecodeContent(f.Content, f.Encoding) + content, err := config.DecodeContent(f.Content, f.Encoding) if err != nil { return "", fmt.Errorf("Unable to decode %s (%v)", f.Path, err) From 551cbb1e5d765b9e87a5440d3dfebe4ddfd25300 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 13 Jan 2015 16:28:47 -0800 Subject: [PATCH 20/56] config/validate: add rule for file encoding --- config/validate/rules.go | 17 +++++++++++++ config/validate/rules_test.go | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/config/validate/rules.go b/config/validate/rules.go index f8397dc..abce8aa 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -31,6 +31,7 @@ type rule func(config node, report *Report) // Rules contains all of the validation rules. var Rules []rule = []rule{ checkDiscoveryUrl, + checkEncoding, checkStructure, checkValidity, checkWriteFiles, @@ -49,6 +50,22 @@ func checkDiscoveryUrl(cfg node, report *Report) { } } +// checkEncoding validates that, for each file under 'write_files', the +// content can be decoded given the specified encoding. +func checkEncoding(cfg node, report *Report) { + for _, f := range cfg.Child("write_files").children { + e := f.Child("encoding") + if !e.IsValid() { + continue + } + + c := f.Child("contents") + if _, err := config.DecodeContent(c.String(), e.String()); err != nil { + report.Error(c.line, fmt.Sprintf("contents cannot be decoded as %q", e.String())) + } + } +} + // checkStructure compares the provided config to the empty config.CloudConfig // structure. Each node is checked to make sure that it exists in the known // structure and that its type is compatible. diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index d37c181..85dffae 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -54,6 +54,52 @@ func TestCheckDiscoveryUrl(t *testing.T) { } } +func TestCheckEncoding(t *testing.T) { + tests := []struct { + config string + + entries []Entry + }{ + {}, + { + config: "write_files:\n - encoding: base64\n contents: aGVsbG8K", + }, + { + config: "write_files:\n - contents: !!binary aGVsbG8K", + }, + { + config: "write_files:\n - encoding: base64\n contents: !!binary aGVsbG8K", + entries: []Entry{{entryError, `contents cannot be decoded as "base64"`, 3}}, + }, + { + config: "write_files:\n - encoding: base64\n contents: !!binary YUdWc2JHOEsK", + }, + { + config: "write_files:\n - encoding: gzip\n contents: !!binary H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + }, + { + config: "write_files:\n - encoding: gzip+base64\n contents: H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + }, + { + config: "write_files:\n - encoding: custom\n contents: hello", + entries: []Entry{{entryError, `contents cannot be decoded as "custom"`, 3}}, + }, + } + + for i, tt := range tests { + r := Report{} + n, err := parseCloudConfig([]byte(tt.config), &r) + if err != nil { + panic(err) + } + checkEncoding(n, &r) + + if e := r.Entries(); !reflect.DeepEqual(tt.entries, e) { + t.Errorf("bad report (%d, %q): want %#v, got %#v", i, tt.config, tt.entries, e) + } + } +} + func TestCheckStructure(t *testing.T) { tests := []struct { config string From e9529ede44a71b34a7dd65bdfaaf9956d3f936cf Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 20 Jan 2015 13:45:52 -0800 Subject: [PATCH 21/56] config: add support for multiple github users --- config/user.go | 27 ++++++++++++++------------- initialize/config.go | 6 ++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/config/user.go b/config/user.go index 44e959c..2bd22aa 100644 --- a/config/user.go +++ b/config/user.go @@ -17,17 +17,18 @@ package config type User struct { - Name string `yaml:"name"` - PasswordHash string `yaml:"passwd"` - SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` - SSHImportGithubUser string `yaml:"coreos_ssh_import_github"` - SSHImportURL string `yaml:"coreos_ssh_import_url"` - GECOS string `yaml:"gecos"` - Homedir string `yaml:"homedir"` - NoCreateHome bool `yaml:"no_create_home"` - PrimaryGroup string `yaml:"primary_group"` - Groups []string `yaml:"groups"` - NoUserGroup bool `yaml:"no_user_group"` - System bool `yaml:"system"` - NoLogInit bool `yaml:"no_log_init"` + Name string `yaml:"name"` + PasswordHash string `yaml:"passwd"` + SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` + SSHImportGithubUser string `yaml:"coreos_ssh_import_github"` + SSHImportGithubUsers []string `yaml:"coreos_ssh_import_github_users"` + SSHImportURL string `yaml:"coreos_ssh_import_url"` + GECOS string `yaml:"gecos"` + Homedir string `yaml:"homedir"` + NoCreateHome bool `yaml:"no_create_home"` + PrimaryGroup string `yaml:"primary_group"` + Groups []string `yaml:"groups"` + NoUserGroup bool `yaml:"no_user_group"` + System bool `yaml:"system"` + NoLogInit bool `yaml:"no_log_init"` } diff --git a/initialize/config.go b/initialize/config.go index 034ba97..c9b2069 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -87,6 +87,12 @@ func Apply(cfg config.CloudConfig, env *Environment) error { return err } } + for _, u := range user.SSHImportGithubUsers { + log.Printf("Authorizing github user %s SSH keys for CoreOS user '%s'", u, user.Name) + if err := SSHImportGithubUser(user.Name, u); err != nil { + return err + } + } if user.SSHImportURL != "" { log.Printf("Authorizing SSH keys for CoreOS user '%s' from '%s'", user.Name, user.SSHImportURL) if err := SSHImportKeysFromURL(user.Name, user.SSHImportURL); err != nil { From c3c4b86a3bcc249511a97806540eaa54f37595d2 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 20 Jan 2015 14:42:18 -0800 Subject: [PATCH 22/56] coreos-cloudinit: bump to v1.2.0 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index e877cc5..17e4314 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.1.0+git" + version = "1.2.0" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From a9c132a7062abfe66f877b9c5fd82e58919575ce Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 20 Jan 2015 14:42:48 -0800 Subject: [PATCH 23/56] coreos-cloudinit: bump to v1.2.0+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 17e4314..b4264fc 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.2.0" + version = "1.2.0+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From a548b557ede5cde9322c2f3c1e0838630da93b57 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 21 Jan 2015 14:26:55 -0800 Subject: [PATCH 24/56] doc: add coreos-ssh-import-github-users --- Documentation/cloud-config.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index f08d795..1ab4216 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -291,6 +291,7 @@ All but the `passwd` and `ssh-authorized-keys` fields will be ignored if the use - **no-user-group**: Boolean. Skip default group creation. - **ssh-authorized-keys**: List of public SSH keys to authorize for this user - **coreos-ssh-import-github**: Authorize SSH keys from Github user +- **coreos-ssh-import-github-users**: Authorize SSH keys from a list of Github users - **coreos-ssh-import-url**: Authorize SSH keys imported from a url endpoint. - **system**: Create the user as a system user. No home directory will be created. - **no-log-init**: Boolean. Skip initialization of lastlog and faillog databases. From ae3676096cabaaa5a65c4976ba31983833fb09ee Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 21 Jan 2015 14:29:25 -0800 Subject: [PATCH 25/56] coreos-cloudinit: bump to v1.2.1 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index b4264fc..30ffd53 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.2.0+git" + version = "1.2.1" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 58b4de8093fd4d1849b09b1a4317b885493e95ff Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 21 Jan 2015 14:29:51 -0800 Subject: [PATCH 26/56] coreos-cloudinit: bump to v1.2.1+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 30ffd53..cdfb260 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -40,7 +40,7 @@ import ( ) const ( - version = "1.2.1" + version = "1.2.1+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From be68a8e5cc445dda0916f94f03d1dfc46a447061 Mon Sep 17 00:00:00 2001 From: Jonathan Boulle Date: Sat, 24 Jan 2015 19:32:33 -0800 Subject: [PATCH 27/56] *: switch to line comments for copyright Build tags are not compatible with block comments. Also adds copyright header to a few places it was missing. --- config/config.go | 28 +++++++++---------- config/config_test.go | 28 +++++++++---------- config/etc_hosts.go | 28 +++++++++---------- config/etcd.go | 28 +++++++++---------- config/file.go | 28 +++++++++---------- config/flannel.go | 14 ++++++++++ config/fleet.go | 28 +++++++++---------- config/locksmith.go | 14 ++++++++++ config/oem.go | 28 +++++++++---------- config/script.go | 28 +++++++++---------- config/unit.go | 28 +++++++++---------- config/update.go | 28 +++++++++---------- config/user.go | 28 +++++++++---------- config/validate/context.go | 28 +++++++++---------- config/validate/context_test.go | 28 +++++++++---------- config/validate/node.go | 28 +++++++++---------- config/validate/node_test.go | 28 +++++++++---------- config/validate/report.go | 28 +++++++++---------- config/validate/report_test.go | 28 +++++++++---------- config/validate/rules.go | 28 +++++++++---------- config/validate/rules_test.go | 28 +++++++++---------- config/validate/validate.go | 28 +++++++++---------- config/validate/validate_test.go | 28 +++++++++---------- coreos-cloudinit.go | 28 +++++++++---------- coreos-cloudinit_test.go | 28 +++++++++---------- datasource/configdrive/configdrive.go | 28 +++++++++---------- datasource/configdrive/configdrive_test.go | 28 +++++++++---------- datasource/datasource.go | 28 +++++++++---------- datasource/file/file.go | 28 +++++++++---------- .../metadata/cloudsigma/server_context.go | 28 +++++++++---------- .../cloudsigma/server_context_test.go | 28 +++++++++---------- datasource/metadata/digitalocean/metadata.go | 28 +++++++++---------- .../metadata/digitalocean/metadata_test.go | 28 +++++++++---------- datasource/metadata/ec2/metadata.go | 28 +++++++++---------- datasource/metadata/ec2/metadata_test.go | 28 +++++++++---------- datasource/metadata/metadata.go | 28 +++++++++---------- datasource/metadata/metadata_test.go | 28 +++++++++---------- datasource/metadata/test/test.go | 28 +++++++++---------- datasource/proc_cmdline/proc_cmdline.go | 28 +++++++++---------- datasource/proc_cmdline/proc_cmdline_test.go | 28 +++++++++---------- datasource/url/url.go | 28 +++++++++---------- datasource/waagent/waagent.go | 28 +++++++++---------- datasource/waagent/waagent_test.go | 28 +++++++++---------- initialize/config.go | 28 +++++++++---------- initialize/config_test.go | 28 +++++++++---------- initialize/env.go | 28 +++++++++---------- initialize/env_test.go | 28 +++++++++---------- initialize/github.go | 28 +++++++++---------- initialize/meta_data.go | 28 +++++++++---------- initialize/meta_data_test.go | 28 +++++++++---------- initialize/ssh_keys.go | 28 +++++++++---------- initialize/ssh_keys_test.go | 28 +++++++++---------- initialize/user_data.go | 28 +++++++++---------- initialize/user_data_test.go | 28 +++++++++---------- initialize/workspace.go | 28 +++++++++---------- network/debian.go | 28 +++++++++---------- network/debian_test.go | 28 +++++++++---------- network/digitalocean.go | 28 +++++++++---------- network/digitalocean_test.go | 28 +++++++++---------- network/interface.go | 28 +++++++++---------- network/interface_test.go | 28 +++++++++---------- network/stanza.go | 28 +++++++++---------- network/stanza_test.go | 28 +++++++++---------- pkg/http_client.go | 28 +++++++++---------- pkg/http_client_test.go | 28 +++++++++---------- system/env.go | 28 +++++++++---------- system/env_file.go | 28 +++++++++---------- system/env_file_test.go | 28 +++++++++---------- system/env_test.go | 14 ++++++++++ system/etc_hosts.go | 28 +++++++++---------- system/etc_hosts_test.go | 28 +++++++++---------- system/etcd.go | 28 +++++++++---------- system/etcd_test.go | 28 +++++++++---------- system/file.go | 28 +++++++++---------- system/file_test.go | 28 +++++++++---------- system/flannel.go | 14 ++++++++++ system/flannel_test.go | 14 ++++++++++ system/fleet.go | 28 +++++++++---------- system/fleet_test.go | 28 +++++++++---------- system/locksmith.go | 28 +++++++++---------- system/locksmith_test.go | 28 +++++++++---------- system/networkd.go | 28 +++++++++---------- system/oem.go | 28 +++++++++---------- system/oem_test.go | 28 +++++++++---------- system/ssh_key.go | 28 +++++++++---------- system/systemd.go | 28 +++++++++---------- system/systemd_test.go | 28 +++++++++---------- system/unit.go | 28 +++++++++---------- system/unit_test.go | 28 +++++++++---------- system/update.go | 28 +++++++++---------- system/update_test.go | 28 +++++++++---------- system/user.go | 28 +++++++++---------- 92 files changed, 1201 insertions(+), 1305 deletions(-) diff --git a/config/config.go b/config/config.go index 9278ecc..13086a6 100644 --- a/config/config.go +++ b/config/config.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/config_test.go b/config/config_test.go index 29171ad..47064e9 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/etc_hosts.go b/config/etc_hosts.go index e32539b..ba22bb6 100644 --- a/config/etc_hosts.go +++ b/config/etc_hosts.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/etcd.go b/config/etcd.go index dfc9559..44ff452 100644 --- a/config/etcd.go +++ b/config/etcd.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/file.go b/config/file.go index 26dbc99..0a983f1 100644 --- a/config/file.go +++ b/config/file.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/flannel.go b/config/flannel.go index d7f4d0d..9915b2d 100644 --- a/config/flannel.go +++ b/config/flannel.go @@ -1,3 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package config type Flannel struct { diff --git a/config/fleet.go b/config/fleet.go index c1c6749..534ccb4 100644 --- a/config/fleet.go +++ b/config/fleet.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/locksmith.go b/config/locksmith.go index 86280b8..6bf8f85 100644 --- a/config/locksmith.go +++ b/config/locksmith.go @@ -1,3 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package config type Locksmith struct { diff --git a/config/oem.go b/config/oem.go index a76ee9f..21ce668 100644 --- a/config/oem.go +++ b/config/oem.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/script.go b/config/script.go index 64f05c8..4a8fa83 100644 --- a/config/script.go +++ b/config/script.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/unit.go b/config/unit.go index 3a09bbb..069d406 100644 --- a/config/unit.go +++ b/config/unit.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/update.go b/config/update.go index 723f244..707d732 100644 --- a/config/update.go +++ b/config/update.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/user.go b/config/user.go index 44e959c..282e82c 100644 --- a/config/user.go +++ b/config/user.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config diff --git a/config/validate/context.go b/config/validate/context.go index 2328ac0..53083a4 100644 --- a/config/validate/context.go +++ b/config/validate/context.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/context_test.go b/config/validate/context_test.go index bea8a6b..335b423 100644 --- a/config/validate/context_test.go +++ b/config/validate/context_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/node.go b/config/validate/node.go index 2df801b..892be45 100644 --- a/config/validate/node.go +++ b/config/validate/node.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/node_test.go b/config/validate/node_test.go index 8cda6f3..1a347c1 100644 --- a/config/validate/node_test.go +++ b/config/validate/node_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/report.go b/config/validate/report.go index b518504..2eff7d9 100644 --- a/config/validate/report.go +++ b/config/validate/report.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/report_test.go b/config/validate/report_test.go index c5fdb85..ba64006 100644 --- a/config/validate/report_test.go +++ b/config/validate/report_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/rules.go b/config/validate/rules.go index 7651819..cb68294 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index ab6d157..673108d 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/validate.go b/config/validate/validate.go index 26ad0b5..31f1bbf 100644 --- a/config/validate/validate.go +++ b/config/validate/validate.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/config/validate/validate_test.go b/config/validate/validate_test.go index b390eda..a67c2f1 100644 --- a/config/validate/validate_test.go +++ b/config/validate/validate_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package validate diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 7bde360..dac9f57 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package main diff --git a/coreos-cloudinit_test.go b/coreos-cloudinit_test.go index d3a4fee..3d7f366 100644 --- a/coreos-cloudinit_test.go +++ b/coreos-cloudinit_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package main diff --git a/datasource/configdrive/configdrive.go b/datasource/configdrive/configdrive.go index 3e2b11c..533e47d 100644 --- a/datasource/configdrive/configdrive.go +++ b/datasource/configdrive/configdrive.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package configdrive diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index 9d9c3b2..5d72a19 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package configdrive diff --git a/datasource/datasource.go b/datasource/datasource.go index 410f6f0..7a95f18 100644 --- a/datasource/datasource.go +++ b/datasource/datasource.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package datasource diff --git a/datasource/file/file.go b/datasource/file/file.go index cd58237..c2db2ff 100644 --- a/datasource/file/file.go +++ b/datasource/file/file.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package file diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index b6fc4d2..59bcc37 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package cloudsigma diff --git a/datasource/metadata/cloudsigma/server_context_test.go b/datasource/metadata/cloudsigma/server_context_test.go index 815ba1a..b234294 100644 --- a/datasource/metadata/cloudsigma/server_context_test.go +++ b/datasource/metadata/cloudsigma/server_context_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package cloudsigma diff --git a/datasource/metadata/digitalocean/metadata.go b/datasource/metadata/digitalocean/metadata.go index 6b63f9a..14f9c3e 100644 --- a/datasource/metadata/digitalocean/metadata.go +++ b/datasource/metadata/digitalocean/metadata.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package digitalocean diff --git a/datasource/metadata/digitalocean/metadata_test.go b/datasource/metadata/digitalocean/metadata_test.go index 1845aed..4b967c2 100644 --- a/datasource/metadata/digitalocean/metadata_test.go +++ b/datasource/metadata/digitalocean/metadata_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package digitalocean diff --git a/datasource/metadata/ec2/metadata.go b/datasource/metadata/ec2/metadata.go index 039c994..1180cfb 100644 --- a/datasource/metadata/ec2/metadata.go +++ b/datasource/metadata/ec2/metadata.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package ec2 diff --git a/datasource/metadata/ec2/metadata_test.go b/datasource/metadata/ec2/metadata_test.go index a2a30c3..c895e68 100644 --- a/datasource/metadata/ec2/metadata_test.go +++ b/datasource/metadata/ec2/metadata_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package ec2 diff --git a/datasource/metadata/metadata.go b/datasource/metadata/metadata.go index 99042f4..b29cb34 100644 --- a/datasource/metadata/metadata.go +++ b/datasource/metadata/metadata.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package metadata diff --git a/datasource/metadata/metadata_test.go b/datasource/metadata/metadata_test.go index de8ff60..9d6b4b2 100644 --- a/datasource/metadata/metadata_test.go +++ b/datasource/metadata/metadata_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package metadata diff --git a/datasource/metadata/test/test.go b/datasource/metadata/test/test.go index 0294aae..3be08f3 100644 --- a/datasource/metadata/test/test.go +++ b/datasource/metadata/test/test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package test diff --git a/datasource/proc_cmdline/proc_cmdline.go b/datasource/proc_cmdline/proc_cmdline.go index feaa356..5b05acf 100644 --- a/datasource/proc_cmdline/proc_cmdline.go +++ b/datasource/proc_cmdline/proc_cmdline.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package proc_cmdline diff --git a/datasource/proc_cmdline/proc_cmdline_test.go b/datasource/proc_cmdline/proc_cmdline_test.go index d302c39..a024581 100644 --- a/datasource/proc_cmdline/proc_cmdline_test.go +++ b/datasource/proc_cmdline/proc_cmdline_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package proc_cmdline diff --git a/datasource/url/url.go b/datasource/url/url.go index 120f177..68c110c 100644 --- a/datasource/url/url.go +++ b/datasource/url/url.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package url diff --git a/datasource/waagent/waagent.go b/datasource/waagent/waagent.go index aaefaec..eccde3c 100644 --- a/datasource/waagent/waagent.go +++ b/datasource/waagent/waagent.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package waagent diff --git a/datasource/waagent/waagent_test.go b/datasource/waagent/waagent_test.go index 0667fe8..464d551 100644 --- a/datasource/waagent/waagent_test.go +++ b/datasource/waagent/waagent_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package waagent diff --git a/initialize/config.go b/initialize/config.go index 3e9c64e..f94c1ba 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/config_test.go b/initialize/config_test.go index 8f7dda5..33be737 100644 --- a/initialize/config_test.go +++ b/initialize/config_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/env.go b/initialize/env.go index 9113a46..0c6e0bb 100644 --- a/initialize/env.go +++ b/initialize/env.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/env_test.go b/initialize/env_test.go index e48dd10..f21aa97 100644 --- a/initialize/env_test.go +++ b/initialize/env_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/github.go b/initialize/github.go index c881069..2f7755f 100644 --- a/initialize/github.go +++ b/initialize/github.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/meta_data.go b/initialize/meta_data.go index a4159a1..1140e16 100644 --- a/initialize/meta_data.go +++ b/initialize/meta_data.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/meta_data_test.go b/initialize/meta_data_test.go index 50cef2e..fd5b856 100644 --- a/initialize/meta_data_test.go +++ b/initialize/meta_data_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/ssh_keys.go b/initialize/ssh_keys.go index b5e12c5..17b0c4a 100644 --- a/initialize/ssh_keys.go +++ b/initialize/ssh_keys.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/ssh_keys_test.go b/initialize/ssh_keys_test.go index f2c0fea..8639579 100644 --- a/initialize/ssh_keys_test.go +++ b/initialize/ssh_keys_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/user_data.go b/initialize/user_data.go index b2b71be..170efaa 100644 --- a/initialize/user_data.go +++ b/initialize/user_data.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/user_data_test.go b/initialize/user_data_test.go index f5c68f0..1d88369 100644 --- a/initialize/user_data_test.go +++ b/initialize/user_data_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/initialize/workspace.go b/initialize/workspace.go index b9d8fc8..540dcf4 100644 --- a/initialize/workspace.go +++ b/initialize/workspace.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package initialize diff --git a/network/debian.go b/network/debian.go index 59ca20d..eeccd74 100644 --- a/network/debian.go +++ b/network/debian.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/debian_test.go b/network/debian_test.go index 41e80de..8cf284b 100644 --- a/network/debian_test.go +++ b/network/debian_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/digitalocean.go b/network/digitalocean.go index 9ad1eb1..e1e9108 100644 --- a/network/digitalocean.go +++ b/network/digitalocean.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/digitalocean_test.go b/network/digitalocean_test.go index ef85360..b4ba476 100644 --- a/network/digitalocean_test.go +++ b/network/digitalocean_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/interface.go b/network/interface.go index 4e82810..877cb9e 100644 --- a/network/interface.go +++ b/network/interface.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/interface_test.go b/network/interface_test.go index ec41f9f..df6eea3 100644 --- a/network/interface_test.go +++ b/network/interface_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/stanza.go b/network/stanza.go index 7eef7c4..88bca81 100644 --- a/network/stanza.go +++ b/network/stanza.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/network/stanza_test.go b/network/stanza_test.go index 38cf1ea..9f47638 100644 --- a/network/stanza_test.go +++ b/network/stanza_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package network diff --git a/pkg/http_client.go b/pkg/http_client.go index 25e78ce..5d275ec 100644 --- a/pkg/http_client.go +++ b/pkg/http_client.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package pkg diff --git a/pkg/http_client_test.go b/pkg/http_client_test.go index 5197264..d581d94 100644 --- a/pkg/http_client_test.go +++ b/pkg/http_client_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package pkg diff --git a/system/env.go b/system/env.go index 993d583..745e8f4 100644 --- a/system/env.go +++ b/system/env.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/env_file.go b/system/env_file.go index 02edaf0..6b2c926 100644 --- a/system/env_file.go +++ b/system/env_file.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/env_file_test.go b/system/env_file_test.go index 728995e..5ec0364 100644 --- a/system/env_file_test.go +++ b/system/env_file_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/env_test.go b/system/env_test.go index 7a02ca2..9d62aed 100644 --- a/system/env_test.go +++ b/system/env_test.go @@ -1,3 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package system import ( diff --git a/system/etc_hosts.go b/system/etc_hosts.go index 1995c8d..7208c16 100644 --- a/system/etc_hosts.go +++ b/system/etc_hosts.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/etc_hosts_test.go b/system/etc_hosts_test.go index d38eee0..e5efd7c 100644 --- a/system/etc_hosts_test.go +++ b/system/etc_hosts_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/etcd.go b/system/etcd.go index 0e898b1..0c7faf4 100644 --- a/system/etcd.go +++ b/system/etcd.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/etcd_test.go b/system/etcd_test.go index a161abc..5fc17f0 100644 --- a/system/etcd_test.go +++ b/system/etcd_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/file.go b/system/file.go index 312caf4..f7c4dc7 100644 --- a/system/file.go +++ b/system/file.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/file_test.go b/system/file_test.go index 8bd441b..6510944 100644 --- a/system/file_test.go +++ b/system/file_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/flannel.go b/system/flannel.go index 3e97f18..84a2efe 100644 --- a/system/flannel.go +++ b/system/flannel.go @@ -1,3 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package system import ( diff --git a/system/flannel_test.go b/system/flannel_test.go index 2e20c46..87b93d7 100644 --- a/system/flannel_test.go +++ b/system/flannel_test.go @@ -1,3 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package system import ( diff --git a/system/fleet.go b/system/fleet.go index 84cb378..2d12d81 100644 --- a/system/fleet.go +++ b/system/fleet.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/fleet_test.go b/system/fleet_test.go index f3e3284..dfe7c3f 100644 --- a/system/fleet_test.go +++ b/system/fleet_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/locksmith.go b/system/locksmith.go index 24a3946..6095e5f 100644 --- a/system/locksmith.go +++ b/system/locksmith.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/locksmith_test.go b/system/locksmith_test.go index 1403eb4..6d7d988 100644 --- a/system/locksmith_test.go +++ b/system/locksmith_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/networkd.go b/system/networkd.go index dac2d81..c9e06ab 100644 --- a/system/networkd.go +++ b/system/networkd.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/oem.go b/system/oem.go index 0c10347..b77e9c8 100644 --- a/system/oem.go +++ b/system/oem.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/oem_test.go b/system/oem_test.go index a940afc..3866120 100644 --- a/system/oem_test.go +++ b/system/oem_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/ssh_key.go b/system/ssh_key.go index fd7a82e..9811422 100644 --- a/system/ssh_key.go +++ b/system/ssh_key.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/systemd.go b/system/systemd.go index f9651b1..a5f643e 100644 --- a/system/systemd.go +++ b/system/systemd.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/systemd_test.go b/system/systemd_test.go index 2794c88..82052ab 100644 --- a/system/systemd_test.go +++ b/system/systemd_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/unit.go b/system/unit.go index e7152ec..22d006d 100644 --- a/system/unit.go +++ b/system/unit.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/unit_test.go b/system/unit_test.go index 10cb883..c995b59 100644 --- a/system/unit_test.go +++ b/system/unit_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/update.go b/system/update.go index bd745da..252911e 100644 --- a/system/update.go +++ b/system/update.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/update_test.go b/system/update_test.go index 4ebf70b..1ab6726 100644 --- a/system/update_test.go +++ b/system/update_test.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system diff --git a/system/user.go b/system/user.go index c8eba07..2f5d85d 100644 --- a/system/user.go +++ b/system/user.go @@ -1,18 +1,16 @@ -/* - Copyright 2014 CoreOS, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package system From be62a1df6669b3c222f3bb303c8a82aefb3addb5 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Thu, 22 Jan 2015 19:30:04 -0800 Subject: [PATCH 28/56] test: DRY out MockFilesystem --- datasource/configdrive/configdrive_test.go | 64 ++++++++++------------ datasource/test/test.go | 28 ++++++++++ datasource/waagent/waagent_test.go | 36 +++++------- 3 files changed, 70 insertions(+), 58 deletions(-) create mode 100644 datasource/test/test.go diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index 5d72a19..fa42209 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -15,83 +15,75 @@ package configdrive import ( - "os" "testing" + + "github.com/coreos/coreos-cloudinit/datasource/test" ) -type mockFilesystem []string - -func (m mockFilesystem) readFile(filename string) ([]byte, error) { - for _, file := range m { - if file == filename { - return []byte(filename), nil - } - } - return nil, os.ErrNotExist -} - func TestFetchMetadata(t *testing.T) { for _, tt := range []struct { - root string - filename string - files mockFilesystem + root string + files test.MockFilesystem + + metadata string }{ { "/", + test.MockFilesystem{}, "", - mockFilesystem{}, }, { "/", - "/openstack/latest/meta_data.json", - mockFilesystem([]string{"/openstack/latest/meta_data.json"}), + test.MockFilesystem{"/openstack/latest/meta_data.json": "metadata"}, + "metadata", }, { "/media/configdrive", - "/media/configdrive/openstack/latest/meta_data.json", - mockFilesystem([]string{"/media/configdrive/openstack/latest/meta_data.json"}), + test.MockFilesystem{"/media/configdrive/openstack/latest/meta_data.json": "metadata"}, + "metadata", }, } { - cd := configDrive{tt.root, tt.files.readFile} - filename, err := cd.FetchMetadata() + cd := configDrive{tt.root, tt.files.ReadFile} + metadata, err := cd.FetchMetadata() if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) } - if string(filename) != tt.filename { - t.Fatalf("bad path for %q: want %q, got %q", tt, tt.filename, filename) + if string(metadata) != tt.metadata { + t.Fatalf("bad path for %q: want %q, got %q", tt, tt.metadata, metadata) } } } func TestFetchUserdata(t *testing.T) { for _, tt := range []struct { - root string - filename string - files mockFilesystem + root string + files test.MockFilesystem + + userdata string }{ { "/", + test.MockFilesystem{}, "", - mockFilesystem{}, }, { "/", - "/openstack/latest/user_data", - mockFilesystem([]string{"/openstack/latest/user_data"}), + test.MockFilesystem{"/openstack/latest/user_data": "userdata"}, + "userdata", }, { "/media/configdrive", - "/media/configdrive/openstack/latest/user_data", - mockFilesystem([]string{"/media/configdrive/openstack/latest/user_data"}), + test.MockFilesystem{"/media/configdrive/openstack/latest/user_data": "userdata"}, + "userdata", }, } { - cd := configDrive{tt.root, tt.files.readFile} - filename, err := cd.FetchUserdata() + cd := configDrive{tt.root, tt.files.ReadFile} + userdata, err := cd.FetchUserdata() if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) } - if string(filename) != tt.filename { - t.Fatalf("bad path for %q: want %q, got %q", tt, tt.filename, filename) + if string(userdata) != tt.userdata { + t.Fatalf("bad path for %q: want %q, got %q", tt, tt.userdata, userdata) } } } diff --git a/datasource/test/test.go b/datasource/test/test.go new file mode 100644 index 0000000..84696e2 --- /dev/null +++ b/datasource/test/test.go @@ -0,0 +1,28 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "os" +) + +type MockFilesystem map[string]string + +func (m MockFilesystem) ReadFile(filename string) ([]byte, error) { + if contents, ok := m[filename]; ok { + return []byte(contents), nil + } + return nil, os.ErrNotExist +} diff --git a/datasource/waagent/waagent_test.go b/datasource/waagent/waagent_test.go index 464d551..326c6a0 100644 --- a/datasource/waagent/waagent_test.go +++ b/datasource/waagent/waagent_test.go @@ -16,44 +16,36 @@ package waagent import ( "encoding/json" - "os" "reflect" "testing" + + "github.com/coreos/coreos-cloudinit/datasource/test" ) -type mockFilesystem map[string][]byte - -func (m mockFilesystem) readFile(filename string) ([]byte, error) { - if contents := m[filename]; contents != nil { - return contents, nil - } - return nil, os.ErrNotExist -} - func TestFetchMetadata(t *testing.T) { for _, tt := range []struct { root string - files mockFilesystem + files test.MockFilesystem metadata map[string]string }{ { "/", - mockFilesystem{}, + test.MockFilesystem{}, nil, }, { "/", - mockFilesystem{"/SharedConfig.xml": []byte("")}, + test.MockFilesystem{"/SharedConfig.xml": ""}, nil, }, { "/var/lib/waagent", - mockFilesystem{"/var/lib/waagent/SharedConfig.xml": []byte("")}, + test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ""}, nil, }, { "/var/lib/waagent", - mockFilesystem{"/var/lib/waagent/SharedConfig.xml": []byte(` + test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ` @@ -89,14 +81,14 @@ func TestFetchMetadata(t *testing.T) { -`)}, +`}, map[string]string{ "local-ipv4": "100.73.202.64", "public-ipv4": "191.239.39.77", }, }, } { - a := waagent{tt.root, tt.files.readFile} + a := waagent{tt.root, tt.files.ReadFile} metadataBytes, err := a.FetchMetadata() if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) @@ -116,22 +108,22 @@ func TestFetchMetadata(t *testing.T) { func TestFetchUserdata(t *testing.T) { for _, tt := range []struct { root string - files mockFilesystem + files test.MockFilesystem }{ { "/", - mockFilesystem{}, + test.MockFilesystem{}, }, { "/", - mockFilesystem{"/CustomData": []byte{}}, + test.MockFilesystem{"/CustomData": ""}, }, { "/var/lib/waagent/", - mockFilesystem{"/var/lib/waagent/CustomData": []byte{}}, + test.MockFilesystem{"/var/lib/waagent/CustomData": ""}, }, } { - a := waagent{tt.root, tt.files.readFile} + a := waagent{tt.root, tt.files.ReadFile} _, err := a.FetchUserdata() if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) From 944158622999a5cd397a59c12e995dcbe7ea72f4 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 15:01:56 -0800 Subject: [PATCH 29/56] test: check all root golang files --- test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test b/test index 38279e1..b9de140 100755 --- a/test +++ b/test @@ -33,7 +33,7 @@ declare -a TESTPKGS=( ) if [ -z "$PKG" ]; then - GOFMTPATH="${TESTPKGS[*]} coreos-cloudinit.go" + GOFMTPATH="${TESTPKGS[*]} *.go" # prepend repo path to each package TESTPKGS="${TESTPKGS[*]/#/${REPO_PATH}/} ./" else From d4c617fc2383f4d0905a7952ffa297fb6cb561d2 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 13:45:55 -0800 Subject: [PATCH 30/56] config: standardize interface a bit --- config/script.go | 5 +++-- coreos-cloudinit.go | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config/script.go b/config/script.go index 4a8fa83..a81c5fc 100644 --- a/config/script.go +++ b/config/script.go @@ -25,6 +25,7 @@ func IsScript(userdata string) bool { return strings.HasPrefix(header, "#!") } -func NewScript(userdata string) (Script, error) { - return Script(userdata), nil +func NewScript(userdata string) (*Script, error) { + s := Script(userdata) + return &s, nil } diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 58d1d47..50514be 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -220,8 +220,8 @@ func main() { switch t := ud.(type) { case *config.CloudConfig: ccu = t - case config.Script: - script = &t + case *config.Script: + script = t } } From 3e47c09b41c6902646f47a34359b49a13029aec6 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Thu, 22 Jan 2015 17:35:39 -0800 Subject: [PATCH 31/56] datasource: replace metadata map with struct The loosely-typed metadata map is a load of crap. Make it a struct and let the compiler help us out. --- coreos-cloudinit.go | 18 ++--- datasource/configdrive/configdrive.go | 27 ++++++- datasource/configdrive/configdrive_test.go | 34 +++++---- datasource/datasource.go | 16 ++++- datasource/file/file.go | 6 +- .../metadata/cloudsigma/server_context.go | 45 ++++++------ .../cloudsigma/server_context_test.go | 18 ++--- datasource/metadata/digitalocean/metadata.go | 70 +++++++++---------- .../metadata/digitalocean/metadata_test.go | 19 +++-- datasource/metadata/ec2/metadata.go | 41 ++++++----- datasource/metadata/ec2/metadata_test.go | 25 +++++-- datasource/proc_cmdline/proc_cmdline.go | 5 +- datasource/url/url.go | 5 +- datasource/waagent/waagent.go | 31 ++++---- datasource/waagent/waagent_test.go | 40 +++++------ initialize/meta_data.go | 62 ++++++---------- initialize/meta_data_test.go | 62 +++------------- 17 files changed, 248 insertions(+), 276 deletions(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 50514be..5977aae 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -176,21 +176,14 @@ func main() { } fmt.Printf("Fetching meta-data from datasource of type %q\n", ds.Type()) - metadataBytes, err := ds.FetchMetadata() + metadata, err := ds.FetchMetadata() if err != nil { fmt.Printf("Failed fetching meta-data from datasource: %v\n", err) os.Exit(1) } - // Extract IPv4 addresses from metadata if possible - var subs map[string]string - if len(metadataBytes) > 0 { - subs, err = initialize.ExtractIPsFromMetadata(metadataBytes) - if err != nil { - fmt.Printf("Failed extracting IPs from meta-data: %v\n", err) - os.Exit(1) - } - } + // Extract IPv4 addresses from metadata + subs := initialize.ExtractIPsFromMetadata(metadata) // Apply environment to user-data env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, subs) @@ -198,10 +191,7 @@ func main() { var ccm, ccu *config.CloudConfig var script *config.Script - if ccm, err = initialize.ParseMetaData(string(metadataBytes)); err != nil { - fmt.Printf("Failed to parse meta-data: %v\n", err) - os.Exit(1) - } + ccm = initialize.ParseMetaData(metadata) if ccm != nil && flags.convertNetconf != "" { fmt.Printf("Fetching network config from datasource of type %q\n", ds.Type()) diff --git a/datasource/configdrive/configdrive.go b/datasource/configdrive/configdrive.go index 533e47d..4b5b2e7 100644 --- a/datasource/configdrive/configdrive.go +++ b/datasource/configdrive/configdrive.go @@ -15,10 +15,13 @@ package configdrive import ( + "encoding/json" "fmt" "io/ioutil" "os" "path" + + "github.com/coreos/coreos-cloudinit/datasource" ) const ( @@ -47,8 +50,28 @@ func (cd *configDrive) ConfigRoot() string { return cd.openstackRoot() } -func (cd *configDrive) FetchMetadata() ([]byte, error) { - return cd.tryReadFile(path.Join(cd.openstackVersionRoot(), "meta_data.json")) +func (cd *configDrive) FetchMetadata() (metadata datasource.Metadata, err error) { + var data []byte + var m struct { + SSHAuthorizedKeyMap map[string]string `json:"public_keys"` + Hostname string `json:"hostname"` + NetworkConfig struct { + ContentPath string `json:"content_path"` + } `json:"network_config"` + } + + if data, err = cd.tryReadFile(path.Join(cd.openstackVersionRoot(), "meta_data.json")); err != nil { + return + } + if err = json.Unmarshal([]byte(data), &m); err != nil { + return + } + + metadata.SSHPublicKeys = m.SSHAuthorizedKeyMap + metadata.Hostname = m.Hostname + metadata.NetworkConfigPath = m.NetworkConfig.ContentPath + + return } func (cd *configDrive) FetchUserdata() ([]byte, error) { diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index fa42209..f53a5a4 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -15,8 +15,10 @@ package configdrive import ( + "reflect" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/test" ) @@ -25,22 +27,28 @@ func TestFetchMetadata(t *testing.T) { root string files test.MockFilesystem - metadata string + metadata datasource.Metadata }{ { - "/", - test.MockFilesystem{}, - "", + root: "/", + files: test.MockFilesystem{"/openstack/latest/meta_data.json": `{"ignore": "me"}`}, }, { - "/", - test.MockFilesystem{"/openstack/latest/meta_data.json": "metadata"}, - "metadata", + root: "/", + files: test.MockFilesystem{"/openstack/latest/meta_data.json": `{"hostname": "host"}`}, + metadata: datasource.Metadata{Hostname: "host"}, }, { - "/media/configdrive", - test.MockFilesystem{"/media/configdrive/openstack/latest/meta_data.json": "metadata"}, - "metadata", + root: "/media/configdrive", + files: test.MockFilesystem{"/media/configdrive/openstack/latest/meta_data.json": `{"hostname": "host", "network_config": {"content_path": "path"}, "public_keys":{"1": "key1", "2": "key2"}}`}, + metadata: datasource.Metadata{ + Hostname: "host", + NetworkConfigPath: "path", + SSHPublicKeys: map[string]string{ + "1": "key1", + "2": "key2", + }, + }, }, } { cd := configDrive{tt.root, tt.files.ReadFile} @@ -48,8 +56,8 @@ func TestFetchMetadata(t *testing.T) { if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) } - if string(metadata) != tt.metadata { - t.Fatalf("bad path for %q: want %q, got %q", tt, tt.metadata, metadata) + if !reflect.DeepEqual(tt.metadata, metadata) { + t.Fatalf("bad metadata for %q: want %#v, got %#v", tt, tt.metadata, metadata) } } } @@ -83,7 +91,7 @@ func TestFetchUserdata(t *testing.T) { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) } if string(userdata) != tt.userdata { - t.Fatalf("bad path for %q: want %q, got %q", tt, tt.userdata, userdata) + t.Fatalf("bad userdata for %q: want %q, got %q", tt, tt.userdata, userdata) } } } diff --git a/datasource/datasource.go b/datasource/datasource.go index 7a95f18..cf0f2f8 100644 --- a/datasource/datasource.go +++ b/datasource/datasource.go @@ -14,12 +14,26 @@ package datasource +import ( + "net" +) + type Datasource interface { IsAvailable() bool AvailabilityChanges() bool ConfigRoot() string - FetchMetadata() ([]byte, error) + FetchMetadata() (Metadata, error) FetchUserdata() ([]byte, error) FetchNetworkConfig(string) ([]byte, error) Type() string } + +type Metadata struct { + PublicIPv4 net.IP + PublicIPv6 net.IP + PrivateIPv4 net.IP + PrivateIPv6 net.IP + Hostname string + SSHPublicKeys map[string]string + NetworkConfigPath string +} diff --git a/datasource/file/file.go b/datasource/file/file.go index c2db2ff..e4f2424 100644 --- a/datasource/file/file.go +++ b/datasource/file/file.go @@ -17,6 +17,8 @@ package file import ( "io/ioutil" "os" + + "github.com/coreos/coreos-cloudinit/datasource" ) type localFile struct { @@ -40,8 +42,8 @@ func (f *localFile) ConfigRoot() string { return "" } -func (f *localFile) FetchMetadata() ([]byte, error) { - return []byte{}, nil +func (f *localFile) FetchMetadata() (datasource.Metadata, error) { + return datasource.Metadata{}, nil } func (f *localFile) FetchUserdata() ([]byte, error) { diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index 59bcc37..c3d58b8 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -24,6 +24,8 @@ import ( "os" "strings" + "github.com/coreos/coreos-cloudinit/datasource" + "github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/cloudsigma/cepgo" ) @@ -69,7 +71,7 @@ func (_ *serverContextService) Type() string { return "server-context" } -func (scs *serverContextService) FetchMetadata() ([]byte, error) { +func (scs *serverContextService) FetchMetadata() (metadata datasource.Metadata, err error) { var ( inputMetadata struct { Name string `json:"name"` @@ -88,48 +90,41 @@ func (scs *serverContextService) FetchMetadata() ([]byte, error) { } `json:"vlan"` } `json:"nics"` } - outputMetadata struct { - Hostname string `json:"name"` - PublicKeys map[string]string `json:"public_keys"` - LocalIPv4 string `json:"local-ipv4"` - PublicIPv4 string `json:"public-ipv4"` - } + rawMetadata []byte ) - rawMetadata, err := scs.client.FetchRaw("") - if err != nil { - return []byte{}, err + if rawMetadata, err = scs.client.FetchRaw(""); err != nil { + return } - err = json.Unmarshal(rawMetadata, &inputMetadata) - if err != nil { - return []byte{}, err + if err = json.Unmarshal(rawMetadata, &inputMetadata); err != nil { + return } if inputMetadata.Name != "" { - outputMetadata.Hostname = inputMetadata.Name + metadata.Hostname = inputMetadata.Name } else { - outputMetadata.Hostname = inputMetadata.UUID + metadata.Hostname = inputMetadata.UUID } + metadata.SSHPublicKeys = map[string]string{} if key, ok := inputMetadata.Meta["ssh_public_key"]; ok { splitted := strings.Split(key, " ") - outputMetadata.PublicKeys = make(map[string]string) - outputMetadata.PublicKeys[splitted[len(splitted)-1]] = key + metadata.SSHPublicKeys[splitted[len(splitted)-1]] = key } for _, nic := range inputMetadata.Nics { if nic.IPv4Conf.IP.UUID != "" { - outputMetadata.PublicIPv4 = nic.IPv4Conf.IP.UUID + metadata.PublicIPv4 = net.ParseIP(nic.IPv4Conf.IP.UUID) } if nic.VLAN.UUID != "" { if localIP, err := scs.findLocalIP(nic.Mac); err == nil { - outputMetadata.LocalIPv4 = localIP + metadata.PrivateIPv4 = localIP } } } - return json.Marshal(outputMetadata) + return } func (scs *serverContextService) FetchUserdata() ([]byte, error) { @@ -154,14 +149,14 @@ func (scs *serverContextService) FetchNetworkConfig(a string) ([]byte, error) { return nil, nil } -func (scs *serverContextService) findLocalIP(mac string) (string, error) { +func (scs *serverContextService) findLocalIP(mac string) (net.IP, error) { ifaces, err := net.Interfaces() if err != nil { - return "", err + return nil, err } ifaceMac, err := net.ParseMAC(mac) if err != nil { - return "", err + return nil, err } for _, iface := range ifaces { if !bytes.Equal(iface.HardwareAddr, ifaceMac) { @@ -176,12 +171,12 @@ func (scs *serverContextService) findLocalIP(mac string) (string, error) { switch ip := addr.(type) { case *net.IPNet: if ip.IP.To4() != nil { - return ip.IP.To4().String(), nil + return ip.IP.To4(), nil } } } } - return "", errors.New("Local IP not found") + return nil, errors.New("Local IP not found") } func isBase64Encoded(field string, userdata map[string]string) bool { diff --git a/datasource/metadata/cloudsigma/server_context_test.go b/datasource/metadata/cloudsigma/server_context_test.go index b234294..726425b 100644 --- a/datasource/metadata/cloudsigma/server_context_test.go +++ b/datasource/metadata/cloudsigma/server_context_test.go @@ -15,7 +15,7 @@ package cloudsigma import ( - "encoding/json" + "net" "reflect" "testing" ) @@ -44,12 +44,6 @@ func (f *fakeCepgoClient) FetchRaw(key string) ([]byte, error) { } func TestServerContextFetchMetadata(t *testing.T) { - var metadata struct { - Hostname string `json:"name"` - PublicKeys map[string]string `json:"public_keys"` - LocalIPv4 string `json:"local-ipv4"` - PublicIPv4 string `json:"public-ipv4"` - } client := new(fakeCepgoClient) scs := NewServerContextService() scs.client = client @@ -114,24 +108,20 @@ func TestServerContextFetchMetadata(t *testing.T) { "uuid": "20a0059b-041e-4d0c-bcc6-9b2852de48b3" }`) - metadataBytes, err := scs.FetchMetadata() + metadata, err := scs.FetchMetadata() if err != nil { t.Error(err.Error()) } - if err := json.Unmarshal(metadataBytes, &metadata); err != nil { - t.Error(err.Error()) - } - if metadata.Hostname != "coreos" { t.Errorf("Hostname is not 'coreos' but %s instead", metadata.Hostname) } - if metadata.PublicKeys["john@doe"] != "ssh-rsa AAAAB3NzaC1yc2E.../hQ5D5 john@doe" { + if metadata.SSHPublicKeys["john@doe"] != "ssh-rsa AAAAB3NzaC1yc2E.../hQ5D5 john@doe" { t.Error("Public SSH Keys are not being read properly") } - if metadata.PublicIPv4 != "31.171.251.74" { + if !metadata.PublicIPv4.Equal(net.ParseIP("31.171.251.74")) { t.Errorf("Public IP is not 31.171.251.74 but %s instead", metadata.PublicIPv4) } } diff --git a/datasource/metadata/digitalocean/metadata.go b/datasource/metadata/digitalocean/metadata.go index 14f9c3e..194cae0 100644 --- a/datasource/metadata/digitalocean/metadata.go +++ b/datasource/metadata/digitalocean/metadata.go @@ -16,8 +16,10 @@ package digitalocean import ( "encoding/json" + "net" "strconv" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/metadata" ) @@ -68,45 +70,43 @@ func NewDatasource(root string) *metadataService { return &metadataService{MetadataService: metadata.NewDatasource(root, apiVersion, userdataUrl, metadataPath)} } -func (ms *metadataService) FetchMetadata() ([]byte, error) { - data, err := ms.FetchData(ms.MetadataUrl()) - if err != nil || len(data) == 0 { - return []byte{}, err +func (ms *metadataService) FetchMetadata() (metadata datasource.Metadata, err error) { + var data []byte + var m Metadata + + if data, err = ms.FetchData(ms.MetadataUrl()); err != nil || len(data) == 0 { + return + } + if err = json.Unmarshal(data, &m); err != nil { + return } - var metadata Metadata - if err := json.Unmarshal(data, &metadata); err != nil { - return []byte{}, err + ms.interfaces = m.Interfaces + ms.dns = m.DNS + + if len(m.Interfaces.Public) > 0 { + if m.Interfaces.Public[0].IPv4 != nil { + metadata.PublicIPv4 = net.ParseIP(m.Interfaces.Public[0].IPv4.IPAddress) + } + if m.Interfaces.Public[0].IPv6 != nil { + metadata.PublicIPv6 = net.ParseIP(m.Interfaces.Public[0].IPv6.IPAddress) + } + } + if len(m.Interfaces.Private) > 0 { + if m.Interfaces.Private[0].IPv4 != nil { + metadata.PrivateIPv4 = net.ParseIP(m.Interfaces.Private[0].IPv4.IPAddress) + } + if m.Interfaces.Private[0].IPv6 != nil { + metadata.PrivateIPv6 = net.ParseIP(m.Interfaces.Private[0].IPv6.IPAddress) + } + } + metadata.Hostname = m.Hostname + metadata.SSHPublicKeys = map[string]string{} + for i, key := range m.PublicKeys { + metadata.SSHPublicKeys[strconv.Itoa(i)] = key } - ms.interfaces = metadata.Interfaces - ms.dns = metadata.DNS - - attrs := make(map[string]interface{}) - if len(metadata.Interfaces.Public) > 0 { - if metadata.Interfaces.Public[0].IPv4 != nil { - attrs["public-ipv4"] = metadata.Interfaces.Public[0].IPv4.IPAddress - } - if metadata.Interfaces.Public[0].IPv6 != nil { - attrs["public-ipv6"] = metadata.Interfaces.Public[0].IPv6.IPAddress - } - } - if len(metadata.Interfaces.Private) > 0 { - if metadata.Interfaces.Private[0].IPv4 != nil { - attrs["local-ipv4"] = metadata.Interfaces.Private[0].IPv4.IPAddress - } - if metadata.Interfaces.Private[0].IPv6 != nil { - attrs["local-ipv6"] = metadata.Interfaces.Private[0].IPv6.IPAddress - } - } - attrs["hostname"] = metadata.Hostname - keys := make(map[string]string) - for i, key := range metadata.PublicKeys { - keys[strconv.Itoa(i)] = key - } - attrs["public_keys"] = keys - - return json.Marshal(attrs) + return } func (ms metadataService) FetchNetworkConfig(filename string) ([]byte, error) { diff --git a/datasource/metadata/digitalocean/metadata_test.go b/datasource/metadata/digitalocean/metadata_test.go index 4b967c2..aa03b37 100644 --- a/datasource/metadata/digitalocean/metadata_test.go +++ b/datasource/metadata/digitalocean/metadata_test.go @@ -15,10 +15,12 @@ package digitalocean import ( - "bytes" "fmt" + "net" + "reflect" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/metadata" "github.com/coreos/coreos-cloudinit/datasource/metadata/test" "github.com/coreos/coreos-cloudinit/pkg" @@ -36,7 +38,7 @@ func TestFetchMetadata(t *testing.T) { root string metadataPath string resources map[string]string - expect []byte + expect datasource.Metadata clientErr error expectErr error }{ @@ -81,7 +83,14 @@ func TestFetchMetadata(t *testing.T) { } }`, }, - expect: []byte(`{"hostname":"","public-ipv4":"192.168.1.2","public-ipv6":"fe00::","public_keys":{"0":"publickey1","1":"publickey2"}}`), + expect: datasource.Metadata{ + PublicIPv4: net.ParseIP("192.168.1.2"), + PublicIPv6: net.ParseIP("fe00::"), + SSHPublicKeys: map[string]string{ + "0": "publickey1", + "1": "publickey2", + }, + }, }, { clientErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")}, @@ -99,8 +108,8 @@ func TestFetchMetadata(t *testing.T) { if Error(err) != Error(tt.expectErr) { t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err) } - if !bytes.Equal(metadata, tt.expect) { - t.Fatalf("bad fetch (%q): want %q, got %q", tt.resources, tt.expect, metadata) + if !reflect.DeepEqual(tt.expect, metadata) { + t.Fatalf("bad fetch (%q): want %#q, got %#q", tt.resources, tt.expect, metadata) } } } diff --git a/datasource/metadata/ec2/metadata.go b/datasource/metadata/ec2/metadata.go index 9e3735c..ab1417f 100644 --- a/datasource/metadata/ec2/metadata.go +++ b/datasource/metadata/ec2/metadata.go @@ -17,10 +17,11 @@ package ec2 import ( "bufio" "bytes" - "encoding/json" "fmt" + "net" "strings" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/metadata" "github.com/coreos/coreos-cloudinit/pkg" ) @@ -40,59 +41,57 @@ func NewDatasource(root string) *metadataService { return &metadataService{metadata.NewDatasource(root, apiVersion, userdataPath, metadataPath)} } -func (ms metadataService) FetchMetadata() ([]byte, error) { - attrs := make(map[string]interface{}) +func (ms metadataService) FetchMetadata() (datasource.Metadata, error) { + metadata := datasource.Metadata{} + if keynames, err := ms.fetchAttributes(fmt.Sprintf("%s/public-keys", ms.MetadataUrl())); err == nil { keyIDs := make(map[string]string) for _, keyname := range keynames { tokens := strings.SplitN(keyname, "=", 2) if len(tokens) != 2 { - return nil, fmt.Errorf("malformed public key: %q", keyname) + return metadata, fmt.Errorf("malformed public key: %q", keyname) } keyIDs[tokens[1]] = tokens[0] } - keys := make(map[string]string) + metadata.SSHPublicKeys = map[string]string{} for name, id := range keyIDs { sshkey, err := ms.fetchAttribute(fmt.Sprintf("%s/public-keys/%s/openssh-key", ms.MetadataUrl(), id)) if err != nil { - return nil, err + return metadata, err } - keys[name] = sshkey + metadata.SSHPublicKeys[name] = sshkey fmt.Printf("Found SSH key for %q\n", name) } - attrs["public_keys"] = keys } else if _, ok := err.(pkg.ErrNotFound); !ok { - return nil, err + return metadata, err } if hostname, err := ms.fetchAttribute(fmt.Sprintf("%s/hostname", ms.MetadataUrl())); err == nil { - attrs["hostname"] = strings.Split(hostname, " ")[0] + metadata.Hostname = strings.Split(hostname, " ")[0] } else if _, ok := err.(pkg.ErrNotFound); !ok { - return nil, err + return metadata, err } if localAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/local-ipv4", ms.MetadataUrl())); err == nil { - attrs["local-ipv4"] = localAddr + metadata.PrivateIPv4 = net.ParseIP(localAddr) } else if _, ok := err.(pkg.ErrNotFound); !ok { - return nil, err + return metadata, err } if publicAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/public-ipv4", ms.MetadataUrl())); err == nil { - attrs["public-ipv4"] = publicAddr + metadata.PublicIPv4 = net.ParseIP(publicAddr) } else if _, ok := err.(pkg.ErrNotFound); !ok { - return nil, err + return metadata, err } - if content_path, err := ms.fetchAttribute(fmt.Sprintf("%s/network_config/content_path", ms.MetadataUrl())); err == nil { - attrs["network_config"] = map[string]string{ - "content_path": content_path, - } + if contentPath, err := ms.fetchAttribute(fmt.Sprintf("%s/network_config/content_path", ms.MetadataUrl())); err == nil { + metadata.NetworkConfigPath = contentPath } else if _, ok := err.(pkg.ErrNotFound); !ok { - return nil, err + return metadata, err } - return json.Marshal(attrs) + return metadata, nil } func (ms metadataService) Type() string { diff --git a/datasource/metadata/ec2/metadata_test.go b/datasource/metadata/ec2/metadata_test.go index ff78efd..f888175 100644 --- a/datasource/metadata/ec2/metadata_test.go +++ b/datasource/metadata/ec2/metadata_test.go @@ -15,11 +15,12 @@ package ec2 import ( - "bytes" "fmt" + "net" "reflect" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/metadata" "github.com/coreos/coreos-cloudinit/datasource/metadata/test" "github.com/coreos/coreos-cloudinit/pkg" @@ -145,7 +146,7 @@ func TestFetchMetadata(t *testing.T) { root string metadataPath string resources map[string]string - expect []byte + expect datasource.Metadata clientErr error expectErr error }{ @@ -169,7 +170,13 @@ func TestFetchMetadata(t *testing.T) { "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", "/2009-04-04/meta-data/network_config/content_path": "path", }, - expect: []byte(`{"hostname":"host","local-ipv4":"1.2.3.4","network_config":{"content_path":"path"},"public-ipv4":"5.6.7.8","public_keys":{"test1":"key"}}`), + expect: datasource.Metadata{ + Hostname: "host", + PrivateIPv4: net.ParseIP("1.2.3.4"), + PublicIPv4: net.ParseIP("5.6.7.8"), + SSHPublicKeys: map[string]string{"test1": "key"}, + NetworkConfigPath: "path", + }, }, { root: "/", @@ -183,7 +190,13 @@ func TestFetchMetadata(t *testing.T) { "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", "/2009-04-04/meta-data/network_config/content_path": "path", }, - expect: []byte(`{"hostname":"host","local-ipv4":"1.2.3.4","network_config":{"content_path":"path"},"public-ipv4":"5.6.7.8","public_keys":{"test1":"key"}}`), + expect: datasource.Metadata{ + Hostname: "host", + PrivateIPv4: net.ParseIP("1.2.3.4"), + PublicIPv4: net.ParseIP("5.6.7.8"), + SSHPublicKeys: map[string]string{"test1": "key"}, + NetworkConfigPath: "path", + }, }, { clientErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")}, @@ -199,8 +212,8 @@ func TestFetchMetadata(t *testing.T) { if Error(err) != Error(tt.expectErr) { t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err) } - if !bytes.Equal(metadata, tt.expect) { - t.Fatalf("bad fetch (%q): want %q, got %q", tt.resources, tt.expect, metadata) + if !reflect.DeepEqual(tt.expect, metadata) { + t.Fatalf("bad fetch (%q): want %#v, got %#v", tt.resources, tt.expect, metadata) } } } diff --git a/datasource/proc_cmdline/proc_cmdline.go b/datasource/proc_cmdline/proc_cmdline.go index 5b05acf..64e13aa 100644 --- a/datasource/proc_cmdline/proc_cmdline.go +++ b/datasource/proc_cmdline/proc_cmdline.go @@ -20,6 +20,7 @@ import ( "log" "strings" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/pkg" ) @@ -55,8 +56,8 @@ func (c *procCmdline) ConfigRoot() string { return "" } -func (c *procCmdline) FetchMetadata() ([]byte, error) { - return []byte{}, nil +func (c *procCmdline) FetchMetadata() (datasource.Metadata, error) { + return datasource.Metadata{}, nil } func (c *procCmdline) FetchUserdata() ([]byte, error) { diff --git a/datasource/url/url.go b/datasource/url/url.go index 68c110c..aa699bc 100644 --- a/datasource/url/url.go +++ b/datasource/url/url.go @@ -15,6 +15,7 @@ package url import ( + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/pkg" ) @@ -40,8 +41,8 @@ func (f *remoteFile) ConfigRoot() string { return "" } -func (f *remoteFile) FetchMetadata() ([]byte, error) { - return []byte{}, nil +func (f *remoteFile) FetchMetadata() (datasource.Metadata, error) { + return datasource.Metadata{}, nil } func (f *remoteFile) FetchUserdata() ([]byte, error) { diff --git a/datasource/waagent/waagent.go b/datasource/waagent/waagent.go index eccde3c..fdc543b 100644 --- a/datasource/waagent/waagent.go +++ b/datasource/waagent/waagent.go @@ -15,13 +15,14 @@ package waagent import ( - "encoding/json" "encoding/xml" "fmt" "io/ioutil" "net" "os" "path" + + "github.com/coreos/coreos-cloudinit/datasource" ) type waagent struct { @@ -46,13 +47,13 @@ func (a *waagent) ConfigRoot() string { return a.root } -func (a *waagent) FetchMetadata() ([]byte, error) { - metadataBytes, err := a.tryReadFile(path.Join(a.root, "SharedConfig.xml")) - if err != nil { - return nil, err +func (a *waagent) FetchMetadata() (metadata datasource.Metadata, err error) { + var metadataBytes []byte + if metadataBytes, err = a.tryReadFile(path.Join(a.root, "SharedConfig.xml")); err != nil { + return } if len(metadataBytes) == 0 { - return metadataBytes, nil + return } type Instance struct { @@ -74,30 +75,28 @@ func (a *waagent) FetchMetadata() ([]byte, error) { } } - var metadata SharedConfig - if err := xml.Unmarshal(metadataBytes, &metadata); err != nil { - return nil, err + var m SharedConfig + if err = xml.Unmarshal(metadataBytes, &m); err != nil { + return } var instance Instance - for _, i := range metadata.Instances.Instances { - if i.Id == metadata.Incarnation.Instance { + for _, i := range m.Instances.Instances { + if i.Id == m.Incarnation.Instance { instance = i break } } - attrs := map[string]string{ - "local-ipv4": instance.Address, - } + metadata.PrivateIPv4 = net.ParseIP(instance.Address) for _, e := range instance.InputEndpoints.Endpoints { host, _, err := net.SplitHostPort(e.LoadBalancedPublicAddress) if err == nil { - attrs["public-ipv4"] = host + metadata.PublicIPv4 = net.ParseIP(host) break } } - return json.Marshal(attrs) + return } func (a *waagent) FetchUserdata() ([]byte, error) { diff --git a/datasource/waagent/waagent_test.go b/datasource/waagent/waagent_test.go index 326c6a0..1036b03 100644 --- a/datasource/waagent/waagent_test.go +++ b/datasource/waagent/waagent_test.go @@ -15,10 +15,11 @@ package waagent import ( - "encoding/json" + "net" "reflect" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/datasource/test" ) @@ -26,26 +27,23 @@ func TestFetchMetadata(t *testing.T) { for _, tt := range []struct { root string files test.MockFilesystem - metadata map[string]string + metadata datasource.Metadata }{ { - "/", - test.MockFilesystem{}, - nil, + root: "/", + files: test.MockFilesystem{}, }, { - "/", - test.MockFilesystem{"/SharedConfig.xml": ""}, - nil, + root: "/", + files: test.MockFilesystem{"/SharedConfig.xml": ""}, }, { - "/var/lib/waagent", - test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ""}, - nil, + root: "/var/lib/waagent", + files: test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ""}, }, { - "/var/lib/waagent", - test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ` + root: "/var/lib/waagent", + files: test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ` @@ -82,25 +80,19 @@ func TestFetchMetadata(t *testing.T) { `}, - map[string]string{ - "local-ipv4": "100.73.202.64", - "public-ipv4": "191.239.39.77", + metadata: datasource.Metadata{ + PrivateIPv4: net.ParseIP("100.73.202.64"), + PublicIPv4: net.ParseIP("191.239.39.77"), }, }, } { a := waagent{tt.root, tt.files.ReadFile} - metadataBytes, err := a.FetchMetadata() + metadata, err := a.FetchMetadata() if err != nil { t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) } - var metadata map[string]string - if len(metadataBytes) > 0 { - if err := json.Unmarshal(metadataBytes, &metadata); err != nil { - panic(err) - } - } if !reflect.DeepEqual(tt.metadata, metadata) { - t.Fatalf("bad metadata for %q: want %q, got %q", tt, tt.metadata, metadata) + t.Fatalf("bad metadata for %q: want %#v, got %#v", tt, tt.metadata, metadata) } } } diff --git a/initialize/meta_data.go b/initialize/meta_data.go index 1140e16..35a9122 100644 --- a/initialize/meta_data.go +++ b/initialize/meta_data.go @@ -15,68 +15,46 @@ package initialize import ( - "encoding/json" "sort" "github.com/coreos/coreos-cloudinit/config" + "github.com/coreos/coreos-cloudinit/datasource" ) // ParseMetaData parses a JSON blob in the OpenStack metadata service format, // and converts it to a partially hydrated CloudConfig. -func ParseMetaData(contents string) (*config.CloudConfig, error) { - if len(contents) == 0 { - return nil, nil - } - var metadata struct { - SSHAuthorizedKeyMap map[string]string `json:"public_keys"` - Hostname string `json:"hostname"` - NetworkConfig struct { - ContentPath string `json:"content_path"` - } `json:"network_config"` - } - if err := json.Unmarshal([]byte(contents), &metadata); err != nil { - return nil, err - } - +func ParseMetaData(metadata datasource.Metadata) *config.CloudConfig { var cfg config.CloudConfig - if len(metadata.SSHAuthorizedKeyMap) > 0 { - cfg.SSHAuthorizedKeys = make([]string, 0, len(metadata.SSHAuthorizedKeyMap)) - for _, name := range sortedKeys(metadata.SSHAuthorizedKeyMap) { - cfg.SSHAuthorizedKeys = append(cfg.SSHAuthorizedKeys, metadata.SSHAuthorizedKeyMap[name]) + if len(metadata.SSHPublicKeys) > 0 { + cfg.SSHAuthorizedKeys = make([]string, 0, len(metadata.SSHPublicKeys)) + for _, name := range sortedKeys(metadata.SSHPublicKeys) { + cfg.SSHAuthorizedKeys = append(cfg.SSHAuthorizedKeys, metadata.SSHPublicKeys[name]) } } cfg.Hostname = metadata.Hostname - cfg.NetworkConfigPath = metadata.NetworkConfig.ContentPath - return &cfg, nil + cfg.NetworkConfigPath = metadata.NetworkConfigPath + return &cfg } // ExtractIPsFromMetaData parses a JSON blob in the OpenStack metadata service // format and returns a substitution map possibly containing private_ipv4, // public_ipv4, private_ipv6, and public_ipv6 addresses. -func ExtractIPsFromMetadata(contents []byte) (map[string]string, error) { - var ips struct { - PublicIPv4 string `json:"public-ipv4"` - PrivateIPv4 string `json:"local-ipv4"` - PublicIPv6 string `json:"public-ipv6"` - PrivateIPv6 string `json:"local-ipv6"` +func ExtractIPsFromMetadata(metadata datasource.Metadata) map[string]string { + subs := map[string]string{} + if metadata.PrivateIPv4 != nil { + subs["$private_ipv4"] = metadata.PrivateIPv4.String() } - if err := json.Unmarshal(contents, &ips); err != nil { - return nil, err + if metadata.PublicIPv4 != nil { + subs["$public_ipv4"] = metadata.PublicIPv4.String() } - m := make(map[string]string) - if ips.PrivateIPv4 != "" { - m["$private_ipv4"] = ips.PrivateIPv4 + if metadata.PrivateIPv6 != nil { + subs["$private_ipv6"] = metadata.PrivateIPv6.String() } - if ips.PublicIPv4 != "" { - m["$public_ipv4"] = ips.PublicIPv4 + if metadata.PublicIPv6 != nil { + subs["$public_ipv6"] = metadata.PublicIPv6.String() } - if ips.PrivateIPv6 != "" { - m["$private_ipv6"] = ips.PrivateIPv6 - } - if ips.PublicIPv6 != "" { - m["$public_ipv6"] = ips.PublicIPv6 - } - return m, nil + + return subs } func sortedKeys(m map[string]string) (keys []string) { diff --git a/initialize/meta_data_test.go b/initialize/meta_data_test.go index fd5b856..15c08a0 100644 --- a/initialize/meta_data_test.go +++ b/initialize/meta_data_test.go @@ -15,71 +15,29 @@ package initialize import ( + "net" "reflect" "testing" - "github.com/coreos/coreos-cloudinit/config" + "github.com/coreos/coreos-cloudinit/datasource" ) -func TestParseMetadata(t *testing.T) { - for i, tt := range []struct { - in string - want *config.CloudConfig - err bool - }{ - {"", nil, false}, - {`garbage, invalid json`, nil, true}, - {`{"foo": "bar"}`, &config.CloudConfig{}, false}, - {`{"network_config": {"content_path": "asdf"}}`, &config.CloudConfig{NetworkConfigPath: "asdf"}, false}, - {`{"hostname": "turkleton"}`, &config.CloudConfig{Hostname: "turkleton"}, false}, - {`{"public_keys": {"jack": "jill", "bob": "alice"}}`, &config.CloudConfig{SSHAuthorizedKeys: []string{"alice", "jill"}}, false}, - {`{"unknown": "thing", "hostname": "my_host", "public_keys": {"do": "re", "mi": "fa"}, "network_config": {"content_path": "/root", "blah": "zzz"}}`, &config.CloudConfig{SSHAuthorizedKeys: []string{"re", "fa"}, Hostname: "my_host", NetworkConfigPath: "/root"}, false}, - } { - got, err := ParseMetaData(tt.in) - if tt.err != (err != nil) { - t.Errorf("case #%d: bad error state: got %t, want %t (err=%v)", i, (err != nil), tt.err, err) - } - if got == nil { - if tt.want != nil { - t.Errorf("case #%d: unexpected nil output", i) - } - } else if tt.want == nil { - t.Errorf("case #%d: unexpected non-nil output", i) - } else { - if !reflect.DeepEqual(*got, *tt.want) { - t.Errorf("case #%d: bad output:\ngot\n%v\nwant\n%v", i, *got, *tt.want) - } - } - } - -} - func TestExtractIPsFromMetadata(t *testing.T) { for i, tt := range []struct { - in []byte - err bool + in datasource.Metadata out map[string]string }{ { - []byte(`{"public-ipv4": "12.34.56.78", "local-ipv4": "1.2.3.4", "public-ipv6": "1234::", "local-ipv6": "5678::"}`), - false, + datasource.Metadata{ + PublicIPv4: net.ParseIP("12.34.56.78"), + PrivateIPv4: net.ParseIP("1.2.3.4"), + PublicIPv6: net.ParseIP("1234::"), + PrivateIPv6: net.ParseIP("5678::"), + }, map[string]string{"$public_ipv4": "12.34.56.78", "$private_ipv4": "1.2.3.4", "$public_ipv6": "1234::", "$private_ipv6": "5678::"}, }, - { - []byte(`{"local-ipv4": "127.0.0.1", "something_else": "don't care"}`), - false, - map[string]string{"$private_ipv4": "127.0.0.1"}, - }, - { - []byte(`garbage`), - true, - nil, - }, } { - got, err := ExtractIPsFromMetadata(tt.in) - if (err != nil) != tt.err { - t.Errorf("bad error state (got %t, want %t)", err != nil, tt.err) - } + got := ExtractIPsFromMetadata(tt.in) if !reflect.DeepEqual(got, tt.out) { t.Errorf("case %d: got %s, want %s", i, got, tt.out) } From 650a239fdbc00c8e4de55543c8ef3cedcef16bab Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 15:42:06 -0800 Subject: [PATCH 32/56] metadata: simplify merging of metadata Add an internal field for CloudConfig to make it easier to distinguish. Instead of creating two CloudConfigs and merging them, just merge the metadata into the existing CloudConfig. --- config/config.go | 19 +++-- coreos-cloudinit.go | 84 +++++++-------------- coreos-cloudinit_test.go | 137 ++++++++++++----------------------- initialize/config.go | 4 +- initialize/meta_data.go | 16 ---- network/debian.go | 4 +- network/debian_test.go | 2 +- network/digitalocean.go | 6 +- network/digitalocean_test.go | 2 +- 9 files changed, 94 insertions(+), 180 deletions(-) diff --git a/config/config.go b/config/config.go index 3195860..f22f699 100644 --- a/config/config.go +++ b/config/config.go @@ -27,14 +27,13 @@ import ( // directly to YAML. Fields that cannot be set in the cloud-config (fields // used for internal use) have the YAML tag '-' so that they aren't marshalled. type CloudConfig struct { - SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` - CoreOS CoreOS `yaml:"coreos"` - WriteFiles []File `yaml:"write_files"` - Hostname string `yaml:"hostname"` - Users []User `yaml:"users"` - ManageEtcHosts EtcHosts `yaml:"manage_etc_hosts"` - NetworkConfigPath string `yaml:"-"` - NetworkConfig string `yaml:"-"` + SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` + CoreOS CoreOS `yaml:"coreos"` + WriteFiles []File `yaml:"write_files"` + Hostname string `yaml:"hostname"` + Users []User `yaml:"users"` + ManageEtcHosts EtcHosts `yaml:"manage_etc_hosts"` + Internal Internals `yaml:"-"` } type CoreOS struct { @@ -47,6 +46,10 @@ type CoreOS struct { Units []Unit `yaml:"units"` } +type Internals struct { + NetworkConfig []byte +} + func IsCloudConfig(userdata string) bool { header := strings.SplitN(userdata, "\n", 2)[0] diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 5977aae..cc2be1e 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -189,19 +189,8 @@ func main() { env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, subs) userdata := env.Apply(string(userdataBytes)) - var ccm, ccu *config.CloudConfig + var ccu *config.CloudConfig var script *config.Script - ccm = initialize.ParseMetaData(metadata) - - if ccm != nil && flags.convertNetconf != "" { - fmt.Printf("Fetching network config from datasource of type %q\n", ds.Type()) - netconfBytes, err := ds.FetchNetworkConfig(ccm.NetworkConfigPath) - if err != nil { - fmt.Printf("Failed fetching network config from datasource: %v\n", err) - os.Exit(1) - } - ccm.NetworkConfig = string(netconfBytes) - } if ud, err := initialize.ParseUserData(userdata); err != nil { fmt.Printf("Failed to parse user-data: %v\nContinuing...\n", err) @@ -215,26 +204,22 @@ func main() { } } - var cc *config.CloudConfig - if ccm != nil && ccu != nil { - fmt.Println("Merging cloud-config from meta-data and user-data") - merged := mergeCloudConfig(*ccm, *ccu) - cc = &merged - } else if ccm != nil && ccu == nil { - fmt.Println("Processing cloud-config from meta-data") - cc = ccm - } else if ccm == nil && ccu != nil { - fmt.Println("Processing cloud-config from user-data") - cc = ccu - } else { - fmt.Println("No cloud-config data to handle.") - } + fmt.Println("Merging cloud-config from meta-data and user-data") + cc := mergeConfigs(ccu, metadata) - if cc != nil { - if err = initialize.Apply(*cc, env); err != nil { - fmt.Printf("Failed to apply cloud-config: %v\n", err) + if flags.convertNetconf != "" { + fmt.Printf("Fetching network config from datasource of type %q\n", ds.Type()) + netconfBytes, err := ds.FetchNetworkConfig(metadata.NetworkConfigPath) + if err != nil { + fmt.Printf("Failed fetching network config from datasource: %v\n", err) os.Exit(1) } + cc.Internal.NetworkConfig = netconfBytes + } + + if err = initialize.Apply(cc, env); err != nil { + fmt.Printf("Failed to apply cloud-config: %v\n", err) + os.Exit(1) } if script != nil { @@ -249,38 +234,25 @@ func main() { } } -// mergeCloudConfig merges certain options from mdcc (a CloudConfig derived from -// meta-data) onto udcc (a CloudConfig derived from user-data), if they are -// not already set on udcc (i.e. user-data always takes precedence) -// NB: This needs to be kept in sync with ParseMetadata so that it tracks all -// elements of a CloudConfig which that function can populate. -func mergeCloudConfig(mdcc, udcc config.CloudConfig) (cc config.CloudConfig) { - if mdcc.Hostname != "" { - if udcc.Hostname != "" { - fmt.Printf("Warning: user-data hostname (%s) overrides metadata hostname (%s)\n", udcc.Hostname, mdcc.Hostname) - } else { - udcc.Hostname = mdcc.Hostname - } +// mergeConfigs merges certain options from md (meta-data from the datasource) +// onto cc (a CloudConfig derived from user-data), if they are not already set +// on cc (i.e. user-data always takes precedence) +func mergeConfigs(cc *config.CloudConfig, md datasource.Metadata) (out config.CloudConfig) { + if cc != nil { + out = *cc + } - } - for _, key := range mdcc.SSHAuthorizedKeys { - udcc.SSHAuthorizedKeys = append(udcc.SSHAuthorizedKeys, key) - } - if mdcc.NetworkConfigPath != "" { - if udcc.NetworkConfigPath != "" { - fmt.Printf("Warning: user-data NetworkConfigPath %s overrides metadata NetworkConfigPath %s\n", udcc.NetworkConfigPath, mdcc.NetworkConfigPath) + if md.Hostname != "" { + if out.Hostname != "" { + fmt.Printf("Warning: user-data hostname (%s) overrides metadata hostname (%s)\n", out.Hostname, md.Hostname) } else { - udcc.NetworkConfigPath = mdcc.NetworkConfigPath + out.Hostname = md.Hostname } } - if mdcc.NetworkConfig != "" { - if udcc.NetworkConfig != "" { - fmt.Printf("Warning: user-data NetworkConfig %s overrides metadata NetworkConfig %s\n", udcc.NetworkConfig, mdcc.NetworkConfig) - } else { - udcc.NetworkConfig = mdcc.NetworkConfig - } + for _, key := range md.SSHPublicKeys { + out.SSHAuthorizedKeys = append(out.SSHAuthorizedKeys, key) } - return udcc + return } // getDatasources creates a slice of possible Datasources for cloudinit based diff --git a/coreos-cloudinit_test.go b/coreos-cloudinit_test.go index 3d7f366..cd87d5f 100644 --- a/coreos-cloudinit_test.go +++ b/coreos-cloudinit_test.go @@ -19,116 +19,71 @@ import ( "testing" "github.com/coreos/coreos-cloudinit/config" + "github.com/coreos/coreos-cloudinit/datasource" ) -func TestMergeCloudConfig(t *testing.T) { - simplecc := config.CloudConfig{ - SSHAuthorizedKeys: []string{"abc", "def"}, - Hostname: "foobar", - NetworkConfigPath: "/path/somewhere", - NetworkConfig: `{}`, - } - for i, tt := range []struct { - udcc config.CloudConfig - mdcc config.CloudConfig - want config.CloudConfig +func TestMergeConfigs(t *testing.T) { + tests := []struct { + cc *config.CloudConfig + md datasource.Metadata + + out config.CloudConfig }{ { - // If mdcc is empty, udcc should be returned unchanged - simplecc, - config.CloudConfig{}, - simplecc, + // If md is empty and cc is nil, result should be empty + out: config.CloudConfig{}, }, { - // If udcc is empty, mdcc should be returned unchanged(overridden) - config.CloudConfig{}, - simplecc, - simplecc, + // If md and cc are empty, result should be empty + cc: &config.CloudConfig{}, + out: config.CloudConfig{}, + }, + { + // If cc is empty, cc should be returned unchanged + cc: &config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def"}, Hostname: "cc-host"}, + out: config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def"}, Hostname: "cc-host"}, + }, + { + // If cc is empty, cc should be returned unchanged(overridden) + cc: &config.CloudConfig{}, + md: datasource.Metadata{Hostname: "md-host", SSHPublicKeys: map[string]string{"key": "ghi"}}, + out: config.CloudConfig{SSHAuthorizedKeys: []string{"ghi"}, Hostname: "md-host"}, + }, + { + // If cc is nil, cc should be returned unchanged(overridden) + md: datasource.Metadata{Hostname: "md-host", SSHPublicKeys: map[string]string{"key": "ghi"}}, + out: config.CloudConfig{SSHAuthorizedKeys: []string{"ghi"}, Hostname: "md-host"}, }, { // user-data should override completely in the case of conflicts - simplecc, - config.CloudConfig{ - Hostname: "meta-hostname", - NetworkConfigPath: "/path/meta", - NetworkConfig: `{"hostname":"test"}`, - }, - simplecc, + cc: &config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def"}, Hostname: "cc-host"}, + md: datasource.Metadata{Hostname: "md-host"}, + out: config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def"}, Hostname: "cc-host"}, }, { // Mixed merge should succeed - config.CloudConfig{ - SSHAuthorizedKeys: []string{"abc", "def"}, - Hostname: "user-hostname", - NetworkConfigPath: "/path/somewhere", - NetworkConfig: `{"hostname":"test"}`, - }, - config.CloudConfig{ - SSHAuthorizedKeys: []string{"woof", "qux"}, - Hostname: "meta-hostname", - }, - config.CloudConfig{ - SSHAuthorizedKeys: []string{"abc", "def", "woof", "qux"}, - Hostname: "user-hostname", - NetworkConfigPath: "/path/somewhere", - NetworkConfig: `{"hostname":"test"}`, - }, + cc: &config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def"}, Hostname: "cc-host"}, + md: datasource.Metadata{Hostname: "md-host", SSHPublicKeys: map[string]string{"key": "ghi"}}, + out: config.CloudConfig{SSHAuthorizedKeys: []string{"abc", "def", "ghi"}, Hostname: "cc-host"}, }, { // Completely non-conflicting merge should be fine - config.CloudConfig{ - Hostname: "supercool", - }, - config.CloudConfig{ - SSHAuthorizedKeys: []string{"zaphod", "beeblebrox"}, - NetworkConfigPath: "/dev/fun", - NetworkConfig: `{"hostname":"test"}`, - }, - config.CloudConfig{ - Hostname: "supercool", - SSHAuthorizedKeys: []string{"zaphod", "beeblebrox"}, - NetworkConfigPath: "/dev/fun", - NetworkConfig: `{"hostname":"test"}`, - }, + cc: &config.CloudConfig{Hostname: "cc-host"}, + md: datasource.Metadata{SSHPublicKeys: map[string]string{"zaphod": "beeblebrox"}}, + out: config.CloudConfig{Hostname: "cc-host", SSHAuthorizedKeys: []string{"beeblebrox"}}, }, { // Non-mergeable settings in user-data should not be affected - config.CloudConfig{ - Hostname: "mememe", - ManageEtcHosts: config.EtcHosts("lolz"), - }, - config.CloudConfig{ - Hostname: "youyouyou", - NetworkConfigPath: "meta-meta-yo", - NetworkConfig: `{"hostname":"test"}`, - }, - config.CloudConfig{ - Hostname: "mememe", - ManageEtcHosts: config.EtcHosts("lolz"), - NetworkConfigPath: "meta-meta-yo", - NetworkConfig: `{"hostname":"test"}`, - }, + cc: &config.CloudConfig{Hostname: "cc-host", ManageEtcHosts: config.EtcHosts("lolz")}, + md: datasource.Metadata{Hostname: "md-host"}, + out: config.CloudConfig{Hostname: "cc-host", ManageEtcHosts: config.EtcHosts("lolz")}, }, - { - // Non-mergeable (unexpected) settings in meta-data are ignored - config.CloudConfig{ - Hostname: "mememe", - }, - config.CloudConfig{ - ManageEtcHosts: config.EtcHosts("lolz"), - NetworkConfigPath: "meta-meta-yo", - NetworkConfig: `{"hostname":"test"}`, - }, - config.CloudConfig{ - Hostname: "mememe", - NetworkConfigPath: "meta-meta-yo", - NetworkConfig: `{"hostname":"test"}`, - }, - }, - } { - got := mergeCloudConfig(tt.mdcc, tt.udcc) - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("case #%d: mergeCloudConfig mutated CloudConfig unexpectedly:\ngot:\n%s\nwant:\n%s", i, got, tt.want) + } + + for i, tt := range tests { + out := mergeConfigs(tt.cc, tt.md) + if !reflect.DeepEqual(tt.out, out) { + t.Errorf("bad config (%d): want %#v, got %#v", i, tt.out, out) } } } diff --git a/initialize/config.go b/initialize/config.go index b88a009..f0fc264 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -170,9 +170,9 @@ func Apply(cfg config.CloudConfig, env *Environment) error { var err error switch env.NetconfType() { case "debian": - interfaces, err = network.ProcessDebianNetconf(cfg.NetworkConfig) + interfaces, err = network.ProcessDebianNetconf(cfg.Internal.NetworkConfig) case "digitalocean": - interfaces, err = network.ProcessDigitalOceanNetconf(cfg.NetworkConfig) + interfaces, err = network.ProcessDigitalOceanNetconf(cfg.Internal.NetworkConfig) default: err = fmt.Errorf("Unsupported network config format %q", env.NetconfType()) } diff --git a/initialize/meta_data.go b/initialize/meta_data.go index 35a9122..fb92b19 100644 --- a/initialize/meta_data.go +++ b/initialize/meta_data.go @@ -17,25 +17,9 @@ package initialize import ( "sort" - "github.com/coreos/coreos-cloudinit/config" "github.com/coreos/coreos-cloudinit/datasource" ) -// ParseMetaData parses a JSON blob in the OpenStack metadata service format, -// and converts it to a partially hydrated CloudConfig. -func ParseMetaData(metadata datasource.Metadata) *config.CloudConfig { - var cfg config.CloudConfig - if len(metadata.SSHPublicKeys) > 0 { - cfg.SSHAuthorizedKeys = make([]string, 0, len(metadata.SSHPublicKeys)) - for _, name := range sortedKeys(metadata.SSHPublicKeys) { - cfg.SSHAuthorizedKeys = append(cfg.SSHAuthorizedKeys, metadata.SSHPublicKeys[name]) - } - } - cfg.Hostname = metadata.Hostname - cfg.NetworkConfigPath = metadata.NetworkConfigPath - return &cfg -} - // ExtractIPsFromMetaData parses a JSON blob in the OpenStack metadata service // format and returns a substitution map possibly containing private_ipv4, // public_ipv4, private_ipv6, and public_ipv6 addresses. diff --git a/network/debian.go b/network/debian.go index eeccd74..91646cb 100644 --- a/network/debian.go +++ b/network/debian.go @@ -19,9 +19,9 @@ import ( "strings" ) -func ProcessDebianNetconf(config string) ([]InterfaceGenerator, error) { +func ProcessDebianNetconf(config []byte) ([]InterfaceGenerator, error) { log.Println("Processing Debian network config") - lines := formatConfig(config) + lines := formatConfig(string(config)) stanzas, err := parseStanzas(lines) if err != nil { return nil, err diff --git a/network/debian_test.go b/network/debian_test.go index 8cf284b..da9e281 100644 --- a/network/debian_test.go +++ b/network/debian_test.go @@ -44,7 +44,7 @@ func TestProcessDebianNetconf(t *testing.T) { {"auto eth1\nauto eth2", false, 0}, {"iface eth1 inet manual", false, 1}, } { - interfaces, err := ProcessDebianNetconf(tt.in) + interfaces, err := ProcessDebianNetconf([]byte(tt.in)) failed := err != nil if tt.fail != failed { t.Fatalf("bad failure state for %q: got %t, want %t", tt.in, failed, tt.fail) diff --git a/network/digitalocean.go b/network/digitalocean.go index e1e9108..d55681a 100644 --- a/network/digitalocean.go +++ b/network/digitalocean.go @@ -23,14 +23,14 @@ import ( "github.com/coreos/coreos-cloudinit/datasource/metadata/digitalocean" ) -func ProcessDigitalOceanNetconf(config string) ([]InterfaceGenerator, error) { +func ProcessDigitalOceanNetconf(config []byte) ([]InterfaceGenerator, error) { log.Println("Processing DigitalOcean network config") - if config == "" { + if len(config) == 0 { return nil, nil } var cfg digitalocean.Metadata - if err := json.Unmarshal([]byte(config), &cfg); err != nil { + if err := json.Unmarshal(config, &cfg); err != nil { return nil, err } diff --git a/network/digitalocean_test.go b/network/digitalocean_test.go index b4ba476..5cb7257 100644 --- a/network/digitalocean_test.go +++ b/network/digitalocean_test.go @@ -378,7 +378,7 @@ func TestProcessDigitalOceanNetconf(t *testing.T) { ifaces: []InterfaceGenerator{}, }, } { - ifaces, err := ProcessDigitalOceanNetconf(tt.cfg) + ifaces, err := ProcessDigitalOceanNetconf([]byte(tt.cfg)) if !errorsEqual(tt.err, err) { t.Fatalf("bad error (%q): want %q, got %q", tt.cfg, tt.err, err) } From 42153edbbc49333c456ff8f6f10630d8037c3d6d Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 15:45:15 -0800 Subject: [PATCH 33/56] initialize: change env to process from metadata We don't use general substitutions so just have env pick the values it wants to substitute. --- coreos-cloudinit.go | 5 +--- initialize/env.go | 26 ++++++++--------- initialize/env_test.go | 56 +++++++++++++++++++----------------- initialize/meta_data.go | 50 -------------------------------- initialize/meta_data_test.go | 45 ----------------------------- 5 files changed, 43 insertions(+), 139 deletions(-) delete mode 100644 initialize/meta_data.go delete mode 100644 initialize/meta_data_test.go diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index cc2be1e..fefc3dc 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -182,11 +182,8 @@ func main() { os.Exit(1) } - // Extract IPv4 addresses from metadata - subs := initialize.ExtractIPsFromMetadata(metadata) - // Apply environment to user-data - env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, subs) + env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, metadata) userdata := env.Apply(string(userdataBytes)) var ccu *config.CloudConfig diff --git a/initialize/env.go b/initialize/env.go index 0c6e0bb..fc9411f 100644 --- a/initialize/env.go +++ b/initialize/env.go @@ -15,12 +15,14 @@ package initialize import ( + "net" "os" "path" "regexp" "strings" "github.com/coreos/coreos-cloudinit/config" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/system" ) @@ -36,20 +38,18 @@ type Environment struct { } // TODO(jonboulle): this is getting unwieldy, should be able to simplify the interface somehow -func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, substitutions map[string]string) *Environment { - if substitutions == nil { - substitutions = make(map[string]string) - } - // If certain values are not in the supplied substitution, fall back to retrieving them from the environment - for k, v := range map[string]string{ - "$public_ipv4": os.Getenv("COREOS_PUBLIC_IPV4"), - "$private_ipv4": os.Getenv("COREOS_PRIVATE_IPV4"), - "$public_ipv6": os.Getenv("COREOS_PUBLIC_IPV6"), - "$private_ipv6": os.Getenv("COREOS_PRIVATE_IPV6"), - } { - if _, ok := substitutions[k]; !ok { - substitutions[k] = v +func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, metadata datasource.Metadata) *Environment { + firstNonNull := func(ip net.IP, env string) string { + if ip == nil { + return env } + return ip.String() + } + substitutions := map[string]string{ + "$public_ipv4": firstNonNull(metadata.PublicIPv4, os.Getenv("COREOS_PUBLIC_IPV4")), + "$private_ipv4": firstNonNull(metadata.PrivateIPv4, os.Getenv("COREOS_PRIVATE_IPV4")), + "$public_ipv6": firstNonNull(metadata.PublicIPv6, os.Getenv("COREOS_PUBLIC_IPV6")), + "$private_ipv6": firstNonNull(metadata.PrivateIPv6, os.Getenv("COREOS_PRIVATE_IPV6")), } return &Environment{root, configRoot, workspace, netconfType, sshKeyName, substitutions} } diff --git a/initialize/env_test.go b/initialize/env_test.go index f21aa97..d56916a 100644 --- a/initialize/env_test.go +++ b/initialize/env_test.go @@ -16,10 +16,12 @@ package initialize import ( "io/ioutil" + "net" "os" "path" "testing" + "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/system" ) @@ -29,18 +31,18 @@ func TestEnvironmentApply(t *testing.T) { os.Setenv("COREOS_PUBLIC_IPV6", "1234::") os.Setenv("COREOS_PRIVATE_IPV6", "5678::") for _, tt := range []struct { - subs map[string]string - input string - out string + metadata datasource.Metadata + input string + out string }{ { // Substituting both values directly should always take precedence // over environment variables - map[string]string{ - "$public_ipv4": "192.0.2.3", - "$private_ipv4": "192.0.2.203", - "$public_ipv6": "fe00:1234::", - "$private_ipv6": "fe00:5678::", + datasource.Metadata{ + PublicIPv4: net.ParseIP("192.0.2.3"), + PrivateIPv4: net.ParseIP("192.0.2.203"), + PublicIPv6: net.ParseIP("fe00:1234::"), + PrivateIPv6: net.ParseIP("fe00:5678::"), }, `[Service] ExecStart=/usr/bin/echo "$public_ipv4 $public_ipv6" @@ -53,25 +55,29 @@ ExecStop=/usr/bin/echo $unknown`, }, { // Substituting one value directly while falling back with the other - map[string]string{"$private_ipv4": "127.0.0.1"}, + datasource.Metadata{ + PrivateIPv4: net.ParseIP("127.0.0.1"), + }, "$private_ipv4\n$public_ipv4", "127.0.0.1\n1.2.3.4", }, { // Falling back to environment variables for both values - map[string]string{"foo": "bar"}, + datasource.Metadata{}, "$private_ipv4\n$public_ipv4", "5.6.7.8\n1.2.3.4", }, { // No substitutions - nil, + datasource.Metadata{}, "$private_ipv4\nfoobar", "5.6.7.8\nfoobar", }, { // Escaping substitutions - map[string]string{"$private_ipv4": "127.0.0.1"}, + datasource.Metadata{ + PrivateIPv4: net.ParseIP("127.0.0.1"), + }, `\$private_ipv4 $private_ipv4 addr: \$private_ipv4 @@ -83,13 +89,13 @@ addr: $private_ipv4 }, { // No substitutions with escaping - nil, + datasource.Metadata{}, "\\$test\n$test", "\\$test\n$test", }, } { - env := NewEnvironment("./", "./", "./", "", "", tt.subs) + env := NewEnvironment("./", "./", "./", "", "", tt.metadata) got := env.Apply(tt.input) if got != tt.out { t.Fatalf("Environment incorrectly applied.\ngot:\n%s\nwant:\n%s", got, tt.out) @@ -98,11 +104,11 @@ addr: $private_ipv4 } func TestEnvironmentFile(t *testing.T) { - subs := map[string]string{ - "$public_ipv4": "1.2.3.4", - "$private_ipv4": "5.6.7.8", - "$public_ipv6": "1234::", - "$private_ipv6": "5678::", + metadata := datasource.Metadata{ + PublicIPv4: net.ParseIP("1.2.3.4"), + PrivateIPv4: net.ParseIP("5.6.7.8"), + PublicIPv6: net.ParseIP("1234::"), + PrivateIPv6: net.ParseIP("5678::"), } expect := "COREOS_PRIVATE_IPV4=5.6.7.8\nCOREOS_PRIVATE_IPV6=5678::\nCOREOS_PUBLIC_IPV4=1.2.3.4\nCOREOS_PUBLIC_IPV6=1234::\n" @@ -112,7 +118,7 @@ func TestEnvironmentFile(t *testing.T) { } defer os.RemoveAll(dir) - env := NewEnvironment("./", "./", "./", "", "", subs) + env := NewEnvironment("./", "./", "./", "", "", metadata) ef := env.DefaultEnvironmentFile() err = system.WriteEnvFile(ef, dir) if err != nil { @@ -131,14 +137,10 @@ func TestEnvironmentFile(t *testing.T) { } func TestEnvironmentFileNil(t *testing.T) { - subs := map[string]string{ - "$public_ipv4": "", - "$private_ipv4": "", - "$public_ipv6": "", - "$private_ipv6": "", - } + os.Clearenv() + metadata := datasource.Metadata{} - env := NewEnvironment("./", "./", "./", "", "", subs) + env := NewEnvironment("./", "./", "./", "", "", metadata) ef := env.DefaultEnvironmentFile() if ef != nil { t.Fatalf("Environment file not nil: %v", ef) diff --git a/initialize/meta_data.go b/initialize/meta_data.go deleted file mode 100644 index fb92b19..0000000 --- a/initialize/meta_data.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package initialize - -import ( - "sort" - - "github.com/coreos/coreos-cloudinit/datasource" -) - -// ExtractIPsFromMetaData parses a JSON blob in the OpenStack metadata service -// format and returns a substitution map possibly containing private_ipv4, -// public_ipv4, private_ipv6, and public_ipv6 addresses. -func ExtractIPsFromMetadata(metadata datasource.Metadata) map[string]string { - subs := map[string]string{} - if metadata.PrivateIPv4 != nil { - subs["$private_ipv4"] = metadata.PrivateIPv4.String() - } - if metadata.PublicIPv4 != nil { - subs["$public_ipv4"] = metadata.PublicIPv4.String() - } - if metadata.PrivateIPv6 != nil { - subs["$private_ipv6"] = metadata.PrivateIPv6.String() - } - if metadata.PublicIPv6 != nil { - subs["$public_ipv6"] = metadata.PublicIPv6.String() - } - - return subs -} - -func sortedKeys(m map[string]string) (keys []string) { - for key := range m { - keys = append(keys, key) - } - sort.Strings(keys) - return -} diff --git a/initialize/meta_data_test.go b/initialize/meta_data_test.go deleted file mode 100644 index 15c08a0..0000000 --- a/initialize/meta_data_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package initialize - -import ( - "net" - "reflect" - "testing" - - "github.com/coreos/coreos-cloudinit/datasource" -) - -func TestExtractIPsFromMetadata(t *testing.T) { - for i, tt := range []struct { - in datasource.Metadata - out map[string]string - }{ - { - datasource.Metadata{ - PublicIPv4: net.ParseIP("12.34.56.78"), - PrivateIPv4: net.ParseIP("1.2.3.4"), - PublicIPv6: net.ParseIP("1234::"), - PrivateIPv6: net.ParseIP("5678::"), - }, - map[string]string{"$public_ipv4": "12.34.56.78", "$private_ipv4": "1.2.3.4", "$public_ipv6": "1234::", "$private_ipv6": "5678::"}, - }, - } { - got := ExtractIPsFromMetadata(tt.in) - if !reflect.DeepEqual(got, tt.out) { - t.Errorf("case %d: got %s, want %s", i, got, tt.out) - } - } -} From 9605b5edf27a30ed6b108838530f5c3a72a10780 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 23 Jan 2015 11:31:57 -0800 Subject: [PATCH 34/56] datasource: remove FetchNetworkConfig step Its easier to let each datasource grab all metadata in the FetchMetadata stage than to break it into multiple stages. --- coreos-cloudinit.go | 12 +---- datasource/configdrive/configdrive.go | 9 +--- datasource/configdrive/configdrive_test.go | 11 +++-- datasource/datasource.go | 15 +++---- datasource/file/file.go | 4 -- .../metadata/cloudsigma/server_context.go | 4 -- datasource/metadata/digitalocean/metadata.go | 13 +----- .../metadata/digitalocean/metadata_test.go | 28 ++++++++++++ datasource/metadata/ec2/metadata.go | 6 --- datasource/metadata/ec2/metadata_test.go | 44 +++++++++---------- datasource/metadata/metadata.go | 4 -- datasource/proc_cmdline/proc_cmdline.go | 4 -- datasource/url/url.go | 4 -- datasource/waagent/waagent.go | 4 -- 14 files changed, 65 insertions(+), 97 deletions(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index fefc3dc..963cb0a 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -188,7 +188,6 @@ func main() { var ccu *config.CloudConfig var script *config.Script - if ud, err := initialize.ParseUserData(userdata); err != nil { fmt.Printf("Failed to parse user-data: %v\nContinuing...\n", err) failure = true @@ -204,16 +203,6 @@ func main() { fmt.Println("Merging cloud-config from meta-data and user-data") cc := mergeConfigs(ccu, metadata) - if flags.convertNetconf != "" { - fmt.Printf("Fetching network config from datasource of type %q\n", ds.Type()) - netconfBytes, err := ds.FetchNetworkConfig(metadata.NetworkConfigPath) - if err != nil { - fmt.Printf("Failed fetching network config from datasource: %v\n", err) - os.Exit(1) - } - cc.Internal.NetworkConfig = netconfBytes - } - if err = initialize.Apply(cc, env); err != nil { fmt.Printf("Failed to apply cloud-config: %v\n", err) os.Exit(1) @@ -249,6 +238,7 @@ func mergeConfigs(cc *config.CloudConfig, md datasource.Metadata) (out config.Cl for _, key := range md.SSHPublicKeys { out.SSHAuthorizedKeys = append(out.SSHAuthorizedKeys, key) } + out.Internal.NetworkConfig = md.NetworkConfig return } diff --git a/datasource/configdrive/configdrive.go b/datasource/configdrive/configdrive.go index 4b5b2e7..3d9b459 100644 --- a/datasource/configdrive/configdrive.go +++ b/datasource/configdrive/configdrive.go @@ -69,7 +69,7 @@ func (cd *configDrive) FetchMetadata() (metadata datasource.Metadata, err error) metadata.SSHPublicKeys = m.SSHAuthorizedKeyMap metadata.Hostname = m.Hostname - metadata.NetworkConfigPath = m.NetworkConfig.ContentPath + metadata.NetworkConfig, err = cd.tryReadFile(path.Join(cd.openstackRoot(), m.NetworkConfig.ContentPath)) return } @@ -78,13 +78,6 @@ func (cd *configDrive) FetchUserdata() ([]byte, error) { return cd.tryReadFile(path.Join(cd.openstackVersionRoot(), "user_data")) } -func (cd *configDrive) FetchNetworkConfig(filename string) ([]byte, error) { - if filename == "" { - return []byte{}, nil - } - return cd.tryReadFile(path.Join(cd.openstackRoot(), filename)) -} - func (cd *configDrive) Type() string { return "cloud-drive" } diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index f53a5a4..0dd49a8 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -39,11 +39,14 @@ func TestFetchMetadata(t *testing.T) { metadata: datasource.Metadata{Hostname: "host"}, }, { - root: "/media/configdrive", - files: test.MockFilesystem{"/media/configdrive/openstack/latest/meta_data.json": `{"hostname": "host", "network_config": {"content_path": "path"}, "public_keys":{"1": "key1", "2": "key2"}}`}, + root: "/media/configdrive", + files: test.MockFilesystem{ + "/media/configdrive/openstack/latest/meta_data.json": `{"hostname": "host", "network_config": {"content_path": "config_file.json"}, "public_keys":{"1": "key1", "2": "key2"}}`, + "/media/configdrive/openstack/config_file.json": "make it work", + }, metadata: datasource.Metadata{ - Hostname: "host", - NetworkConfigPath: "path", + Hostname: "host", + NetworkConfig: []byte("make it work"), SSHPublicKeys: map[string]string{ "1": "key1", "2": "key2", diff --git a/datasource/datasource.go b/datasource/datasource.go index cf0f2f8..766f9a7 100644 --- a/datasource/datasource.go +++ b/datasource/datasource.go @@ -24,16 +24,15 @@ type Datasource interface { ConfigRoot() string FetchMetadata() (Metadata, error) FetchUserdata() ([]byte, error) - FetchNetworkConfig(string) ([]byte, error) Type() string } type Metadata struct { - PublicIPv4 net.IP - PublicIPv6 net.IP - PrivateIPv4 net.IP - PrivateIPv6 net.IP - Hostname string - SSHPublicKeys map[string]string - NetworkConfigPath string + PublicIPv4 net.IP + PublicIPv6 net.IP + PrivateIPv4 net.IP + PrivateIPv6 net.IP + Hostname string + SSHPublicKeys map[string]string + NetworkConfig []byte } diff --git a/datasource/file/file.go b/datasource/file/file.go index e4f2424..2700b46 100644 --- a/datasource/file/file.go +++ b/datasource/file/file.go @@ -50,10 +50,6 @@ func (f *localFile) FetchUserdata() ([]byte, error) { return ioutil.ReadFile(f.path) } -func (f *localFile) FetchNetworkConfig(filename string) ([]byte, error) { - return nil, nil -} - func (f *localFile) Type() string { return "local-file" } diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index c3d58b8..b618e45 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -145,10 +145,6 @@ func (scs *serverContextService) FetchUserdata() ([]byte, error) { return []byte(userData), nil } -func (scs *serverContextService) FetchNetworkConfig(a string) ([]byte, error) { - return nil, nil -} - func (scs *serverContextService) findLocalIP(mac string) (net.IP, error) { ifaces, err := net.Interfaces() if err != nil { diff --git a/datasource/metadata/digitalocean/metadata.go b/datasource/metadata/digitalocean/metadata.go index 194cae0..a42796e 100644 --- a/datasource/metadata/digitalocean/metadata.go +++ b/datasource/metadata/digitalocean/metadata.go @@ -61,8 +61,6 @@ type Metadata struct { } type metadataService struct { - interfaces Interfaces - dns DNS metadata.MetadataService } @@ -81,9 +79,6 @@ func (ms *metadataService) FetchMetadata() (metadata datasource.Metadata, err er return } - ms.interfaces = m.Interfaces - ms.dns = m.DNS - if len(m.Interfaces.Public) > 0 { if m.Interfaces.Public[0].IPv4 != nil { metadata.PublicIPv4 = net.ParseIP(m.Interfaces.Public[0].IPv4.IPAddress) @@ -105,17 +100,11 @@ func (ms *metadataService) FetchMetadata() (metadata datasource.Metadata, err er for i, key := range m.PublicKeys { metadata.SSHPublicKeys[strconv.Itoa(i)] = key } + metadata.NetworkConfig = data return } -func (ms metadataService) FetchNetworkConfig(filename string) ([]byte, error) { - return json.Marshal(Metadata{ - Interfaces: ms.interfaces, - DNS: ms.dns, - }) -} - func (ms metadataService) Type() string { return "digitalocean-metadata-service" } diff --git a/datasource/metadata/digitalocean/metadata_test.go b/datasource/metadata/digitalocean/metadata_test.go index aa03b37..881a352 100644 --- a/datasource/metadata/digitalocean/metadata_test.go +++ b/datasource/metadata/digitalocean/metadata_test.go @@ -90,6 +90,34 @@ func TestFetchMetadata(t *testing.T) { "0": "publickey1", "1": "publickey2", }, + NetworkConfig: []byte(`{ + "droplet_id": 1, + "user_data": "hello", + "vendor_data": "hello", + "public_keys": [ + "publickey1", + "publickey2" + ], + "region": "nyc2", + "interfaces": { + "public": [ + { + "ipv4": { + "ip_address": "192.168.1.2", + "netmask": "255.255.255.0", + "gateway": "192.168.1.1" + }, + "ipv6": { + "ip_address": "fe00::", + "cidr": 126, + "gateway": "fe00::" + }, + "mac": "ab:cd:ef:gh:ij", + "type": "public" + } + ] + } +}`), }, }, { diff --git a/datasource/metadata/ec2/metadata.go b/datasource/metadata/ec2/metadata.go index ab1417f..35baa09 100644 --- a/datasource/metadata/ec2/metadata.go +++ b/datasource/metadata/ec2/metadata.go @@ -85,12 +85,6 @@ func (ms metadataService) FetchMetadata() (datasource.Metadata, error) { return metadata, err } - if contentPath, err := ms.fetchAttribute(fmt.Sprintf("%s/network_config/content_path", ms.MetadataUrl())); err == nil { - metadata.NetworkConfigPath = contentPath - } else if _, ok := err.(pkg.ErrNotFound); !ok { - return metadata, err - } - return metadata, nil } diff --git a/datasource/metadata/ec2/metadata_test.go b/datasource/metadata/ec2/metadata_test.go index f888175..ba463c2 100644 --- a/datasource/metadata/ec2/metadata_test.go +++ b/datasource/metadata/ec2/metadata_test.go @@ -162,40 +162,36 @@ func TestFetchMetadata(t *testing.T) { root: "/", metadataPath: "2009-04-04/meta-data", resources: map[string]string{ - "/2009-04-04/meta-data/hostname": "host", - "/2009-04-04/meta-data/local-ipv4": "1.2.3.4", - "/2009-04-04/meta-data/public-ipv4": "5.6.7.8", - "/2009-04-04/meta-data/public-keys": "0=test1\n", - "/2009-04-04/meta-data/public-keys/0": "openssh-key", - "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", - "/2009-04-04/meta-data/network_config/content_path": "path", + "/2009-04-04/meta-data/hostname": "host", + "/2009-04-04/meta-data/local-ipv4": "1.2.3.4", + "/2009-04-04/meta-data/public-ipv4": "5.6.7.8", + "/2009-04-04/meta-data/public-keys": "0=test1\n", + "/2009-04-04/meta-data/public-keys/0": "openssh-key", + "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", }, expect: datasource.Metadata{ - Hostname: "host", - PrivateIPv4: net.ParseIP("1.2.3.4"), - PublicIPv4: net.ParseIP("5.6.7.8"), - SSHPublicKeys: map[string]string{"test1": "key"}, - NetworkConfigPath: "path", + Hostname: "host", + PrivateIPv4: net.ParseIP("1.2.3.4"), + PublicIPv4: net.ParseIP("5.6.7.8"), + SSHPublicKeys: map[string]string{"test1": "key"}, }, }, { root: "/", metadataPath: "2009-04-04/meta-data", resources: map[string]string{ - "/2009-04-04/meta-data/hostname": "host domain another_domain", - "/2009-04-04/meta-data/local-ipv4": "1.2.3.4", - "/2009-04-04/meta-data/public-ipv4": "5.6.7.8", - "/2009-04-04/meta-data/public-keys": "0=test1\n", - "/2009-04-04/meta-data/public-keys/0": "openssh-key", - "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", - "/2009-04-04/meta-data/network_config/content_path": "path", + "/2009-04-04/meta-data/hostname": "host domain another_domain", + "/2009-04-04/meta-data/local-ipv4": "1.2.3.4", + "/2009-04-04/meta-data/public-ipv4": "5.6.7.8", + "/2009-04-04/meta-data/public-keys": "0=test1\n", + "/2009-04-04/meta-data/public-keys/0": "openssh-key", + "/2009-04-04/meta-data/public-keys/0/openssh-key": "key", }, expect: datasource.Metadata{ - Hostname: "host", - PrivateIPv4: net.ParseIP("1.2.3.4"), - PublicIPv4: net.ParseIP("5.6.7.8"), - SSHPublicKeys: map[string]string{"test1": "key"}, - NetworkConfigPath: "path", + Hostname: "host", + PrivateIPv4: net.ParseIP("1.2.3.4"), + PublicIPv4: net.ParseIP("5.6.7.8"), + SSHPublicKeys: map[string]string{"test1": "key"}, }, }, { diff --git a/datasource/metadata/metadata.go b/datasource/metadata/metadata.go index b29cb34..2baa4f1 100644 --- a/datasource/metadata/metadata.go +++ b/datasource/metadata/metadata.go @@ -52,10 +52,6 @@ func (ms MetadataService) FetchUserdata() ([]byte, error) { return ms.FetchData(ms.UserdataUrl()) } -func (ms MetadataService) FetchNetworkConfig(filename string) ([]byte, error) { - return nil, nil -} - func (ms MetadataService) FetchData(url string) ([]byte, error) { if data, err := ms.Client.GetRetry(url); err == nil { return data, err diff --git a/datasource/proc_cmdline/proc_cmdline.go b/datasource/proc_cmdline/proc_cmdline.go index 64e13aa..8423b25 100644 --- a/datasource/proc_cmdline/proc_cmdline.go +++ b/datasource/proc_cmdline/proc_cmdline.go @@ -81,10 +81,6 @@ func (c *procCmdline) FetchUserdata() ([]byte, error) { return cfg, nil } -func (c *procCmdline) FetchNetworkConfig(filename string) ([]byte, error) { - return nil, nil -} - func (c *procCmdline) Type() string { return "proc-cmdline" } diff --git a/datasource/url/url.go b/datasource/url/url.go index aa699bc..8a9c541 100644 --- a/datasource/url/url.go +++ b/datasource/url/url.go @@ -50,10 +50,6 @@ func (f *remoteFile) FetchUserdata() ([]byte, error) { return client.GetRetry(f.url) } -func (f *remoteFile) FetchNetworkConfig(filename string) ([]byte, error) { - return nil, nil -} - func (f *remoteFile) Type() string { return "url" } diff --git a/datasource/waagent/waagent.go b/datasource/waagent/waagent.go index fdc543b..d0460b9 100644 --- a/datasource/waagent/waagent.go +++ b/datasource/waagent/waagent.go @@ -103,10 +103,6 @@ func (a *waagent) FetchUserdata() ([]byte, error) { return a.tryReadFile(path.Join(a.root, "CustomData")) } -func (a *waagent) FetchNetworkConfig(filename string) ([]byte, error) { - return nil, nil -} - func (a *waagent) Type() string { return "waagent" } From 536f8acf2a0d65b5104841b62488c550bb94384f Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Mon, 26 Jan 2015 17:35:08 -0800 Subject: [PATCH 35/56] config: remove network config from CloudConfig --- config/config.go | 17 ++++++----------- coreos-cloudinit.go | 23 ++++++++++++++++++++--- initialize/config.go | 22 ++++------------------ initialize/env.go | 9 ++------- initialize/env_test.go | 6 +++--- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/config/config.go b/config/config.go index f22f699..bb1d771 100644 --- a/config/config.go +++ b/config/config.go @@ -27,13 +27,12 @@ import ( // directly to YAML. Fields that cannot be set in the cloud-config (fields // used for internal use) have the YAML tag '-' so that they aren't marshalled. type CloudConfig struct { - SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` - CoreOS CoreOS `yaml:"coreos"` - WriteFiles []File `yaml:"write_files"` - Hostname string `yaml:"hostname"` - Users []User `yaml:"users"` - ManageEtcHosts EtcHosts `yaml:"manage_etc_hosts"` - Internal Internals `yaml:"-"` + SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` + CoreOS CoreOS `yaml:"coreos"` + WriteFiles []File `yaml:"write_files"` + Hostname string `yaml:"hostname"` + Users []User `yaml:"users"` + ManageEtcHosts EtcHosts `yaml:"manage_etc_hosts"` } type CoreOS struct { @@ -46,10 +45,6 @@ type CoreOS struct { Units []Unit `yaml:"units"` } -type Internals struct { - NetworkConfig []byte -} - func IsCloudConfig(userdata string) bool { header := strings.SplitN(userdata, "\n", 2)[0] diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 963cb0a..7e0eec4 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -33,6 +33,7 @@ import ( "github.com/coreos/coreos-cloudinit/datasource/url" "github.com/coreos/coreos-cloudinit/datasource/waagent" "github.com/coreos/coreos-cloudinit/initialize" + "github.com/coreos/coreos-cloudinit/network" "github.com/coreos/coreos-cloudinit/pkg" "github.com/coreos/coreos-cloudinit/system" ) @@ -183,7 +184,7 @@ func main() { } // Apply environment to user-data - env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.convertNetconf, flags.sshKeyName, metadata) + env := initialize.NewEnvironment("/", ds.ConfigRoot(), flags.workspace, flags.sshKeyName, metadata) userdata := env.Apply(string(userdataBytes)) var ccu *config.CloudConfig @@ -203,7 +204,24 @@ func main() { fmt.Println("Merging cloud-config from meta-data and user-data") cc := mergeConfigs(ccu, metadata) - if err = initialize.Apply(cc, env); err != nil { + var ifaces []network.InterfaceGenerator + if flags.convertNetconf != "" { + var err error + switch flags.convertNetconf { + case "debian": + ifaces, err = network.ProcessDebianNetconf(metadata.NetworkConfig) + case "digitalocean": + ifaces, err = network.ProcessDigitalOceanNetconf(metadata.NetworkConfig) + default: + err = fmt.Errorf("Unsupported network config format %q", flags.convertNetconf) + } + if err != nil { + fmt.Printf("Failed to generate interfaces: %v\n", err) + os.Exit(1) + } + } + + if err = initialize.Apply(cc, ifaces, env); err != nil { fmt.Printf("Failed to apply cloud-config: %v\n", err) os.Exit(1) } @@ -238,7 +256,6 @@ func mergeConfigs(cc *config.CloudConfig, md datasource.Metadata) (out config.Cl for _, key := range md.SSHPublicKeys { out.SSHAuthorizedKeys = append(out.SSHAuthorizedKeys, key) } - out.Internal.NetworkConfig = md.NetworkConfig return } diff --git a/initialize/config.go b/initialize/config.go index f0fc264..3bf7f54 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -42,7 +42,7 @@ type CloudConfigUnit interface { // Apply renders a CloudConfig to an Environment. This can involve things like // configuring the hostname, adding new users, writing various configuration // files to disk, and manipulating systemd services. -func Apply(cfg config.CloudConfig, env *Environment) error { +func Apply(cfg config.CloudConfig, ifaces []network.InterfaceGenerator, env *Environment) error { if cfg.Hostname != "" { if err := system.SetHostname(cfg.Hostname); err != nil { return err @@ -165,23 +165,9 @@ func Apply(cfg config.CloudConfig, env *Environment) error { } } - if env.NetconfType() != "" { - var interfaces []network.InterfaceGenerator - var err error - switch env.NetconfType() { - case "debian": - interfaces, err = network.ProcessDebianNetconf(cfg.Internal.NetworkConfig) - case "digitalocean": - interfaces, err = network.ProcessDigitalOceanNetconf(cfg.Internal.NetworkConfig) - default: - err = fmt.Errorf("Unsupported network config format %q", env.NetconfType()) - } - if err != nil { - return err - } - - units = append(units, createNetworkingUnits(interfaces)...) - if err := system.RestartNetwork(interfaces); err != nil { + if len(ifaces) > 0 { + units = append(units, createNetworkingUnits(ifaces)...) + if err := system.RestartNetwork(ifaces); err != nil { return err } } diff --git a/initialize/env.go b/initialize/env.go index fc9411f..f90cc93 100644 --- a/initialize/env.go +++ b/initialize/env.go @@ -32,13 +32,12 @@ type Environment struct { root string configRoot string workspace string - netconfType string sshKeyName string substitutions map[string]string } // TODO(jonboulle): this is getting unwieldy, should be able to simplify the interface somehow -func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, metadata datasource.Metadata) *Environment { +func NewEnvironment(root, configRoot, workspace, sshKeyName string, metadata datasource.Metadata) *Environment { firstNonNull := func(ip net.IP, env string) string { if ip == nil { return env @@ -51,7 +50,7 @@ func NewEnvironment(root, configRoot, workspace, netconfType, sshKeyName string, "$public_ipv6": firstNonNull(metadata.PublicIPv6, os.Getenv("COREOS_PUBLIC_IPV6")), "$private_ipv6": firstNonNull(metadata.PrivateIPv6, os.Getenv("COREOS_PRIVATE_IPV6")), } - return &Environment{root, configRoot, workspace, netconfType, sshKeyName, substitutions} + return &Environment{root, configRoot, workspace, sshKeyName, substitutions} } func (e *Environment) Workspace() string { @@ -66,10 +65,6 @@ func (e *Environment) ConfigRoot() string { return e.configRoot } -func (e *Environment) NetconfType() string { - return e.netconfType -} - func (e *Environment) SSHKeyName() string { return e.sshKeyName } diff --git a/initialize/env_test.go b/initialize/env_test.go index d56916a..abb770c 100644 --- a/initialize/env_test.go +++ b/initialize/env_test.go @@ -95,7 +95,7 @@ addr: $private_ipv4 }, } { - env := NewEnvironment("./", "./", "./", "", "", tt.metadata) + env := NewEnvironment("./", "./", "./", "", tt.metadata) got := env.Apply(tt.input) if got != tt.out { t.Fatalf("Environment incorrectly applied.\ngot:\n%s\nwant:\n%s", got, tt.out) @@ -118,7 +118,7 @@ func TestEnvironmentFile(t *testing.T) { } defer os.RemoveAll(dir) - env := NewEnvironment("./", "./", "./", "", "", metadata) + env := NewEnvironment("./", "./", "./", "", metadata) ef := env.DefaultEnvironmentFile() err = system.WriteEnvFile(ef, dir) if err != nil { @@ -140,7 +140,7 @@ func TestEnvironmentFileNil(t *testing.T) { os.Clearenv() metadata := datasource.Metadata{} - env := NewEnvironment("./", "./", "./", "", "", metadata) + env := NewEnvironment("./", "./", "./", "", metadata) ef := env.DefaultEnvironmentFile() if ef != nil { t.Fatalf("Environment file not nil: %v", ef) From 7d8b29e597a48c6875d4a75507aff4ab09d4146a Mon Sep 17 00:00:00 2001 From: Jonathan Boulle Date: Wed, 28 Jan 2015 10:19:16 -0800 Subject: [PATCH 36/56] docs: fix typo --- Documentation/cloud-config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index 1ab4216..660b3e4 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -151,7 +151,7 @@ coreos: Environment="LOCKSMITHD_ENDPOINT=example.com:4001" ``` -For the complete list of locksmith configuraion parameters, see the [locksmith documentation][locksmith-readme]. +For the complete list of locksmith configuration parameters, see the [locksmith documentation][locksmith-readme]. [locksmith-readme]: https://github.com/coreos/locksmith/blob/master/README.md From cf3baa8805cd1ca2fadc8c007ecd3a0d7f41be2c Mon Sep 17 00:00:00 2001 From: Alex Malinovich Date: Wed, 28 Jan 2015 14:19:08 -0800 Subject: [PATCH 37/56] Fix GitHub capitalization --- Documentation/cloud-config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index 660b3e4..21acc75 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -290,8 +290,8 @@ All but the `passwd` and `ssh-authorized-keys` fields will be ignored if the use - **groups**: Add user to these additional groups - **no-user-group**: Boolean. Skip default group creation. - **ssh-authorized-keys**: List of public SSH keys to authorize for this user -- **coreos-ssh-import-github**: Authorize SSH keys from Github user -- **coreos-ssh-import-github-users**: Authorize SSH keys from a list of Github users +- **coreos-ssh-import-github**: Authorize SSH keys from GitHub user +- **coreos-ssh-import-github-users**: Authorize SSH keys from a list of GitHub users - **coreos-ssh-import-url**: Authorize SSH keys imported from a url endpoint. - **system**: Create the user as a system user. No home directory will be created. - **no-log-init**: Boolean. Skip initialization of lastlog and faillog databases. From afbf1dbb3adb32eaba08764a844d0ff8c3472c6a Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Thu, 5 Feb 2015 02:56:28 -0800 Subject: [PATCH 38/56] Add etcd 2.0 configuration flag support. --- config/etcd.go | 82 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/config/etcd.go b/config/etcd.go index 44ff452..d52bdb6 100644 --- a/config/etcd.go +++ b/config/etcd.go @@ -15,37 +15,53 @@ package config type Etcd struct { - Addr string `yaml:"addr" env:"ETCD_ADDR"` - BindAddr string `yaml:"bind_addr" env:"ETCD_BIND_ADDR"` - CAFile string `yaml:"ca_file" env:"ETCD_CA_FILE"` - CertFile string `yaml:"cert_file" env:"ETCD_CERT_FILE"` - ClusterActiveSize int `yaml:"cluster_active_size" env:"ETCD_CLUSTER_ACTIVE_SIZE"` - ClusterRemoveDelay float64 `yaml:"cluster_remove_delay" env:"ETCD_CLUSTER_REMOVE_DELAY"` - ClusterSyncInterval float64 `yaml:"cluster_sync_interval" env:"ETCD_CLUSTER_SYNC_INTERVAL"` - CorsOrigins string `yaml:"cors" env:"ETCD_CORS"` - DataDir string `yaml:"data_dir" env:"ETCD_DATA_DIR"` - Discovery string `yaml:"discovery" env:"ETCD_DISCOVERY"` - GraphiteHost string `yaml:"graphite_host" env:"ETCD_GRAPHITE_HOST"` - HTTPReadTimeout float64 `yaml:"http_read_timeout" env:"ETCD_HTTP_READ_TIMEOUT"` - HTTPWriteTimeout float64 `yaml:"http_write_timeout" env:"ETCD_HTTP_WRITE_TIMEOUT"` - KeyFile string `yaml:"key_file" env:"ETCD_KEY_FILE"` - MaxResultBuffer int `yaml:"max_result_buffer" env:"ETCD_MAX_RESULT_BUFFER"` - MaxRetryAttempts int `yaml:"max_retry_attempts" env:"ETCD_MAX_RETRY_ATTEMPTS"` - Name string `yaml:"name" env:"ETCD_NAME"` - PeerAddr string `yaml:"peer_addr" env:"ETCD_PEER_ADDR"` - PeerBindAddr string `yaml:"peer_bind_addr" env:"ETCD_PEER_BIND_ADDR"` - PeerCAFile string `yaml:"peer_ca_file" env:"ETCD_PEER_CA_FILE"` - PeerCertFile string `yaml:"peer_cert_file" env:"ETCD_PEER_CERT_FILE"` - PeerElectionTimeout int `yaml:"peer_election_timeout" env:"ETCD_PEER_ELECTION_TIMEOUT"` - PeerHeartbeatInterval int `yaml:"peer_heartbeat_interval" env:"ETCD_PEER_HEARTBEAT_INTERVAL"` - PeerKeyFile string `yaml:"peer_key_file" env:"ETCD_PEER_KEY_FILE"` - Peers string `yaml:"peers" env:"ETCD_PEERS"` - PeersFile string `yaml:"peers_file" env:"ETCD_PEERS_FILE"` - RetryInterval float64 `yaml:"retry_interval" env:"ETCD_RETRY_INTERVAL"` - Snapshot bool `yaml:"snapshot" env:"ETCD_SNAPSHOT"` - SnapshotCount int `yaml:"snapshot_count" env:"ETCD_SNAPSHOTCOUNT"` - StrTrace string `yaml:"trace" env:"ETCD_TRACE"` - Verbose bool `yaml:"verbose" env:"ETCD_VERBOSE"` - VeryVerbose bool `yaml:"very_verbose" env:"ETCD_VERY_VERBOSE"` - VeryVeryVerbose bool `yaml:"very_very_verbose" env:"ETCD_VERY_VERY_VERBOSE"` + Addr string `yaml:"addr" env:"ETCD_ADDR"` + AdvertiseClientURLs string `yaml:"advertise_client_urls" env:"ETCD_ADVERTISE_CLIENT_URLS"` + BindAddr string `yaml:"bind_addr" env:"ETCD_BIND_ADDR"` + CAFile string `yaml:"ca_file" env:"ETCD_CA_FILE"` + CertFile string `yaml:"cert_file" env:"ETCD_CERT_FILE"` + ClusterActiveSize int `yaml:"cluster_active_size" env:"ETCD_CLUSTER_ACTIVE_SIZE"` + ClusterRemoveDelay float64 `yaml:"cluster_remove_delay" env:"ETCD_CLUSTER_REMOVE_DELAY"` + ClusterSyncInterval float64 `yaml:"cluster_sync_interval" env:"ETCD_CLUSTER_SYNC_INTERVAL"` + CorsOrigins string `yaml:"cors" env:"ETCD_CORS"` + DataDir string `yaml:"data_dir" env:"ETCD_DATA_DIR"` + Discovery string `yaml:"discovery" env:"ETCD_DISCOVERY"` + DiscoveryFallback string `yaml:"discovery_fallback" env:"ETCD_DISCOVERY_FALLBACK"` + DiscoverySRV string `yaml:"discovery_srv" env:"ETCD_DISCOVERY_SRV"` + DiscoveryProxy string `yaml:"discovery_proxy" env:"ETCD_DISCOVERY_PROXY"` + ElectionTimeout int `yaml:"election_timeout" env:"ETCD_ELECTION_TIMEOUT"` + ForceNewCluster bool `yaml:"force_new_cluster" env:"ETCD_FORCE_NEW_CLUSTER"` + GraphiteHost string `yaml:"graphite_host" env:"ETCD_GRAPHITE_HOST"` + HeartbeatInterval int `yaml:"heartbeat_interval" env:"ETCD_HEARTBEAT_INTERVAL"` + HTTPReadTimeout float64 `yaml:"http_read_timeout" env:"ETCD_HTTP_READ_TIMEOUT"` + HTTPWriteTimeout float64 `yaml:"http_write_timeout" env:"ETCD_HTTP_WRITE_TIMEOUT"` + InitialAdvertisePeerURLs string `yaml:"initial_advertise_peer_urls" env:"ETCD_INITIAL_ADVERTISE_PEER_URLS"` + InitialCluster string `yaml:"initial_cluster" env:"ETCD_INITIAL_CLUSTER"` + InitialClusterState string `yaml:"initial_cluster_state" env:"ETCD_INITIAL_CLUSTER_STATE"` + InitialClusterToken string `yaml:"initial_cluster_token" env:"ETCD_INITIAL_CLUSTER_TOKEN"` + KeyFile string `yaml:"key_file" env:"ETCD_KEY_FILE"` + ListenClientURLs string `yaml:"listen_client_urls" env:"ETCD_LISTEN_CLIENT_URLS"` + ListenPeerURLs string `yaml:"listen_peer_urls" env:"ETCD_LISTEN_PEER_URLS"` + MaxResultBuffer int `yaml:"max_result_buffer" env:"ETCD_MAX_RESULT_BUFFER"` + MaxRetryAttempts int `yaml:"max_retry_attempts" env:"ETCD_MAX_RETRY_ATTEMPTS"` + MaxSnapshots int `yaml:"max_snapshots" env:"ETCD_MAX_SNAPSHOTS"` + MaxWALs int `yaml:"max_wals" env:"ETCD_MAX_WALS"` + Name string `yaml:"name" env:"ETCD_NAME"` + PeerAddr string `yaml:"peer_addr" env:"ETCD_PEER_ADDR"` + PeerBindAddr string `yaml:"peer_bind_addr" env:"ETCD_PEER_BIND_ADDR"` + PeerCAFile string `yaml:"peer_ca_file" env:"ETCD_PEER_CA_FILE"` + PeerCertFile string `yaml:"peer_cert_file" env:"ETCD_PEER_CERT_FILE"` + PeerElectionTimeout int `yaml:"peer_election_timeout" env:"ETCD_PEER_ELECTION_TIMEOUT"` + PeerHeartbeatInterval int `yaml:"peer_heartbeat_interval" env:"ETCD_PEER_HEARTBEAT_INTERVAL"` + PeerKeyFile string `yaml:"peer_key_file" env:"ETCD_PEER_KEY_FILE"` + Peers string `yaml:"peers" env:"ETCD_PEERS"` + PeersFile string `yaml:"peers_file" env:"ETCD_PEERS_FILE"` + Proxy string `yaml:"proxy" env:"ETCD_PROXY"` + RetryInterval float64 `yaml:"retry_interval" env:"ETCD_RETRY_INTERVAL"` + Snapshot bool `yaml:"snapshot" env:"ETCD_SNAPSHOT"` + SnapshotCount int `yaml:"snapshot_count" env:"ETCD_SNAPSHOTCOUNT"` + StrTrace string `yaml:"trace" env:"ETCD_TRACE"` + Verbose bool `yaml:"verbose" env:"ETCD_VERBOSE"` + VeryVerbose bool `yaml:"very_verbose" env:"ETCD_VERY_VERBOSE"` + VeryVeryVerbose bool `yaml:"very_very_verbose" env:"ETCD_VERY_VERY_VERBOSE"` } From 080c698ec2a82ce81b970248d13a1f2609da8b4f Mon Sep 17 00:00:00 2001 From: Rob Szumski Date: Fri, 6 Feb 2015 13:31:50 -0800 Subject: [PATCH 39/56] docs: link to CoreUpdate and Omaha --- Documentation/cloud-config.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index 21acc75..1b70c05 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -167,9 +167,12 @@ The `reboot-strategy` parameter also affects the behaviour of [locksmith](https: - _etcd-lock_: Reboot after first taking a distributed lock in etcd, this guarantees that only one host will reboot concurrently and that the cluster will remain available during the update. - _best-effort_ - If etcd is running, "etcd-lock", otherwise simply "reboot". - _off_ - Disable rebooting after updates are applied (not recommended). -- **server**: is the omaha endpoint URL which will be queried for updates. +- **server**: The location of the [CoreUpdate][coreupdate] server which will be queried for updates. Also known as the [omaha][omaha-docs] server endpoint. - **group**: signifies the channel which should be used for automatic updates. This value defaults to the version of the image initially downloaded. (one of "master", "alpha", "beta", "stable") +[coreupdate]: {{site.url}}/products/coreupdate +[omaha-docs]: https://code.google.com/p/omaha/ + *Note: cloudinit will only manipulate the locksmith unit file in the systemd runtime directory (`/run/systemd/system/locksmithd.service`). If any manual modifications are made to an overriding unit configuration file (e.g. `/etc/systemd/system/locksmithd.service`), cloudinit will no longer be able to control the locksmith service unit.* ##### Example From a3357c273c17590899ecaca4bd25c157888b3cbf Mon Sep 17 00:00:00 2001 From: Rob Szumski Date: Fri, 6 Feb 2015 13:43:06 -0800 Subject: [PATCH 40/56] docs: update links --- Documentation/cloud-config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index 1b70c05..c35f795 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -170,8 +170,8 @@ The `reboot-strategy` parameter also affects the behaviour of [locksmith](https: - **server**: The location of the [CoreUpdate][coreupdate] server which will be queried for updates. Also known as the [omaha][omaha-docs] server endpoint. - **group**: signifies the channel which should be used for automatic updates. This value defaults to the version of the image initially downloaded. (one of "master", "alpha", "beta", "stable") -[coreupdate]: {{site.url}}/products/coreupdate -[omaha-docs]: https://code.google.com/p/omaha/ +[coreupdate]: https://coreos.com/products/coreupdate +[omaha-docs]: https://coreos.com/docs/coreupdate/custom-apps/coreupdate-protocol/ *Note: cloudinit will only manipulate the locksmith unit file in the systemd runtime directory (`/run/systemd/system/locksmithd.service`). If any manual modifications are made to an overriding unit configuration file (e.g. `/etc/systemd/system/locksmithd.service`), cloudinit will no longer be able to control the locksmith service unit.* From 3b2af743bdad7943e618f0a92064000441f04ca9 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 11 Feb 2015 17:03:24 -0800 Subject: [PATCH 41/56] oem: add CloudSigma OEM --- coreos-cloudinit.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 7e0eec4..8cfee20 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -106,6 +106,9 @@ var ( "azure": oemConfig{ "from-waagent": "/var/lib/waagent", }, + "cloudsigma": oemConfig{ + "from-cloudsigma-metadata": "true", + }, } ) From 18caa5bf07c89d17a1675a1b1be526c6f836ba09 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 11 Feb 2015 17:19:05 -0800 Subject: [PATCH 42/56] coreos-cloudinit: bump to v1.3.0 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 8cfee20..feab6b3 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.2.1+git" + version = "1.3.0" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From eb0d2dbfa3fb03807bcb2637a0434bf97506b5d8 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 11 Feb 2015 17:19:32 -0800 Subject: [PATCH 43/56] coreos-cloudinit: bump to v1.3.0+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index feab6b3..d4f6c60 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.0" + version = "1.3.0+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 477053ffde04d7786cf98d7683bca29bc16dc1fd Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 13 Feb 2015 10:16:39 -0800 Subject: [PATCH 44/56] configdrive: check metadata length before parsing This was lost in some of the recent refactoring. --- datasource/configdrive/configdrive.go | 2 +- datasource/configdrive/configdrive_test.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/datasource/configdrive/configdrive.go b/datasource/configdrive/configdrive.go index 3d9b459..bbadf64 100644 --- a/datasource/configdrive/configdrive.go +++ b/datasource/configdrive/configdrive.go @@ -60,7 +60,7 @@ func (cd *configDrive) FetchMetadata() (metadata datasource.Metadata, err error) } `json:"network_config"` } - if data, err = cd.tryReadFile(path.Join(cd.openstackVersionRoot(), "meta_data.json")); err != nil { + if data, err = cd.tryReadFile(path.Join(cd.openstackVersionRoot(), "meta_data.json")); err != nil || len(data) == 0 { return } if err = json.Unmarshal([]byte(data), &m); err != nil { diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index 0dd49a8..d384890 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -29,6 +29,10 @@ func TestFetchMetadata(t *testing.T) { metadata datasource.Metadata }{ + { + root: "/", + files: test.MockFilesystem{"/openstack/latest/meta_data.json": ""}, + }, { root: "/", files: test.MockFilesystem{"/openstack/latest/meta_data.json": `{"ignore": "me"}`}, From 2fe0b0b2a8e85cedbc79d6f3d6ef2c1c13c2fdb3 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 13 Feb 2015 10:24:41 -0800 Subject: [PATCH 45/56] coreos-cloudinit: bump to v1.3.1 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index d4f6c60..3e65afb 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.0+git" + version = "1.3.1" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From f8aa7a43b8e929d48a268597d9dfc1973ce68bb4 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 13 Feb 2015 10:25:01 -0800 Subject: [PATCH 46/56] coreos-cloudinit: bump to v1.3.1+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 3e65afb..5c32f26 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.1" + version = "1.3.1+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 47ac4f69315969cdf0fee81da81d6c6928e86886 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 13 Feb 2015 21:01:44 -0800 Subject: [PATCH 47/56] test: add directory support to MockFilesystem --- datasource/configdrive/configdrive_test.go | 27 +++-- datasource/test/filesystem.go | 57 ++++++++++ datasource/test/filesystem_test.go | 115 +++++++++++++++++++++ datasource/test/test.go | 28 ----- datasource/waagent/waagent_test.go | 22 ++-- test | 1 + 6 files changed, 197 insertions(+), 53 deletions(-) create mode 100644 datasource/test/filesystem.go create mode 100644 datasource/test/filesystem_test.go delete mode 100644 datasource/test/test.go diff --git a/datasource/configdrive/configdrive_test.go b/datasource/configdrive/configdrive_test.go index d384890..e40a8fd 100644 --- a/datasource/configdrive/configdrive_test.go +++ b/datasource/configdrive/configdrive_test.go @@ -31,23 +31,22 @@ func TestFetchMetadata(t *testing.T) { }{ { root: "/", - files: test.MockFilesystem{"/openstack/latest/meta_data.json": ""}, + files: test.NewMockFilesystem(test.File{Path: "/openstack/latest/meta_data.json", Contents: ""}), }, { root: "/", - files: test.MockFilesystem{"/openstack/latest/meta_data.json": `{"ignore": "me"}`}, + files: test.NewMockFilesystem(test.File{Path: "/openstack/latest/meta_data.json", Contents: `{"ignore": "me"}`}), }, { root: "/", - files: test.MockFilesystem{"/openstack/latest/meta_data.json": `{"hostname": "host"}`}, + files: test.NewMockFilesystem(test.File{Path: "/openstack/latest/meta_data.json", Contents: `{"hostname": "host"}`}), metadata: datasource.Metadata{Hostname: "host"}, }, { root: "/media/configdrive", - files: test.MockFilesystem{ - "/media/configdrive/openstack/latest/meta_data.json": `{"hostname": "host", "network_config": {"content_path": "config_file.json"}, "public_keys":{"1": "key1", "2": "key2"}}`, - "/media/configdrive/openstack/config_file.json": "make it work", - }, + files: test.NewMockFilesystem(test.File{Path: "/media/configdrive/openstack/latest/meta_data.json", Contents: `{"hostname": "host", "network_config": {"content_path": "config_file.json"}, "public_keys":{"1": "key1", "2": "key2"}}`}, + test.File{Path: "/media/configdrive/openstack/config_file.json", Contents: "make it work"}, + ), metadata: datasource.Metadata{ Hostname: "host", NetworkConfig: []byte("make it work"), @@ -61,10 +60,10 @@ func TestFetchMetadata(t *testing.T) { cd := configDrive{tt.root, tt.files.ReadFile} metadata, err := cd.FetchMetadata() if err != nil { - t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) + t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err) } if !reflect.DeepEqual(tt.metadata, metadata) { - t.Fatalf("bad metadata for %q: want %#v, got %#v", tt, tt.metadata, metadata) + t.Fatalf("bad metadata for %+v: want %#v, got %#v", tt, tt.metadata, metadata) } } } @@ -78,27 +77,27 @@ func TestFetchUserdata(t *testing.T) { }{ { "/", - test.MockFilesystem{}, + test.NewMockFilesystem(), "", }, { "/", - test.MockFilesystem{"/openstack/latest/user_data": "userdata"}, + test.NewMockFilesystem(test.File{Path: "/openstack/latest/user_data", Contents: "userdata"}), "userdata", }, { "/media/configdrive", - test.MockFilesystem{"/media/configdrive/openstack/latest/user_data": "userdata"}, + test.NewMockFilesystem(test.File{Path: "/media/configdrive/openstack/latest/user_data", Contents: "userdata"}), "userdata", }, } { cd := configDrive{tt.root, tt.files.ReadFile} userdata, err := cd.FetchUserdata() if err != nil { - t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) + t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err) } if string(userdata) != tt.userdata { - t.Fatalf("bad userdata for %q: want %q, got %q", tt, tt.userdata, userdata) + t.Fatalf("bad userdata for %+v: want %q, got %q", tt, tt.userdata, userdata) } } } diff --git a/datasource/test/filesystem.go b/datasource/test/filesystem.go new file mode 100644 index 0000000..95d6fb2 --- /dev/null +++ b/datasource/test/filesystem.go @@ -0,0 +1,57 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "fmt" + "os" + "path" +) + +type MockFilesystem map[string]File + +type File struct { + Path string + Contents string + Directory bool +} + +func (m MockFilesystem) ReadFile(filename string) ([]byte, error) { + if f, ok := m[path.Clean(filename)]; ok { + if f.Directory { + return nil, fmt.Errorf("read %s: is a directory", filename) + } + return []byte(f.Contents), nil + } + return nil, os.ErrNotExist +} + +func NewMockFilesystem(files ...File) MockFilesystem { + fs := MockFilesystem{} + for _, file := range files { + fs[file.Path] = file + + // Create the directories leading up to the file + p := path.Dir(file.Path) + for p != "/" && p != "." { + if f, ok := fs[p]; ok && !f.Directory { + panic(fmt.Sprintf("%q already exists and is not a directory (%#v)", p, f)) + } + fs[p] = File{Path: p, Directory: true} + p = path.Dir(p) + } + } + return fs +} diff --git a/datasource/test/filesystem_test.go b/datasource/test/filesystem_test.go new file mode 100644 index 0000000..547c51f --- /dev/null +++ b/datasource/test/filesystem_test.go @@ -0,0 +1,115 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "errors" + "os" + "reflect" + "testing" +) + +func TestReadFile(t *testing.T) { + tests := []struct { + filesystem MockFilesystem + + filename string + contents string + err error + }{ + { + filename: "dne", + err: os.ErrNotExist, + }, + { + filesystem: MockFilesystem{ + "exists": File{Contents: "hi"}, + }, + filename: "exists", + contents: "hi", + }, + { + filesystem: MockFilesystem{ + "dir": File{Directory: true}, + }, + filename: "dir", + err: errors.New("read dir: is a directory"), + }, + } + + for i, tt := range tests { + contents, err := tt.filesystem.ReadFile(tt.filename) + if tt.contents != string(contents) { + t.Errorf("bad contents (test %d): want %q, got %q", i, tt.contents, string(contents)) + } + if !reflect.DeepEqual(tt.err, err) { + t.Errorf("bad error (test %d): want %v, got %v", i, tt.err, err) + } + } +} + +func TestNewMockFilesystem(t *testing.T) { + tests := []struct { + files []File + + filesystem MockFilesystem + }{ + { + filesystem: MockFilesystem{}, + }, + { + files: []File{File{Path: "file"}}, + filesystem: MockFilesystem{ + "file": File{Path: "file"}, + }, + }, + { + files: []File{File{Path: "/file"}}, + filesystem: MockFilesystem{ + "/file": File{Path: "/file"}, + }, + }, + { + files: []File{File{Path: "/dir/file"}}, + filesystem: MockFilesystem{ + "/dir": File{Path: "/dir", Directory: true}, + "/dir/file": File{Path: "/dir/file"}, + }, + }, + { + files: []File{File{Path: "/dir/dir/file"}}, + filesystem: MockFilesystem{ + "/dir": File{Path: "/dir", Directory: true}, + "/dir/dir": File{Path: "/dir/dir", Directory: true}, + "/dir/dir/file": File{Path: "/dir/dir/file"}, + }, + }, + { + files: []File{File{Path: "/dir/dir/dir", Directory: true}}, + filesystem: MockFilesystem{ + "/dir": File{Path: "/dir", Directory: true}, + "/dir/dir": File{Path: "/dir/dir", Directory: true}, + "/dir/dir/dir": File{Path: "/dir/dir/dir", Directory: true}, + }, + }, + } + + for i, tt := range tests { + filesystem := NewMockFilesystem(tt.files...) + if !reflect.DeepEqual(tt.filesystem, filesystem) { + t.Errorf("bad filesystem (test %d): want %#v, got %#v", i, tt.filesystem, filesystem) + } + } +} diff --git a/datasource/test/test.go b/datasource/test/test.go deleted file mode 100644 index 84696e2..0000000 --- a/datasource/test/test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package test - -import ( - "os" -) - -type MockFilesystem map[string]string - -func (m MockFilesystem) ReadFile(filename string) ([]byte, error) { - if contents, ok := m[filename]; ok { - return []byte(contents), nil - } - return nil, os.ErrNotExist -} diff --git a/datasource/waagent/waagent_test.go b/datasource/waagent/waagent_test.go index 1036b03..f60a4c2 100644 --- a/datasource/waagent/waagent_test.go +++ b/datasource/waagent/waagent_test.go @@ -31,19 +31,19 @@ func TestFetchMetadata(t *testing.T) { }{ { root: "/", - files: test.MockFilesystem{}, + files: test.NewMockFilesystem(), }, { root: "/", - files: test.MockFilesystem{"/SharedConfig.xml": ""}, + files: test.NewMockFilesystem(test.File{Path: "/SharedConfig.xml", Contents: ""}), }, { root: "/var/lib/waagent", - files: test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ""}, + files: test.NewMockFilesystem(test.File{Path: "/var/lib/waagent/SharedConfig.xml", Contents: ""}), }, { root: "/var/lib/waagent", - files: test.MockFilesystem{"/var/lib/waagent/SharedConfig.xml": ` + files: test.NewMockFilesystem(test.File{Path: "/var/lib/waagent/SharedConfig.xml", Contents: ` @@ -79,7 +79,7 @@ func TestFetchMetadata(t *testing.T) { -`}, +`}), metadata: datasource.Metadata{ PrivateIPv4: net.ParseIP("100.73.202.64"), PublicIPv4: net.ParseIP("191.239.39.77"), @@ -89,10 +89,10 @@ func TestFetchMetadata(t *testing.T) { a := waagent{tt.root, tt.files.ReadFile} metadata, err := a.FetchMetadata() if err != nil { - t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) + t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err) } if !reflect.DeepEqual(tt.metadata, metadata) { - t.Fatalf("bad metadata for %q: want %#v, got %#v", tt, tt.metadata, metadata) + t.Fatalf("bad metadata for %+v: want %#v, got %#v", tt, tt.metadata, metadata) } } } @@ -104,21 +104,21 @@ func TestFetchUserdata(t *testing.T) { }{ { "/", - test.MockFilesystem{}, + test.NewMockFilesystem(), }, { "/", - test.MockFilesystem{"/CustomData": ""}, + test.NewMockFilesystem(test.File{Path: "/CustomData", Contents: ""}), }, { "/var/lib/waagent/", - test.MockFilesystem{"/var/lib/waagent/CustomData": ""}, + test.NewMockFilesystem(test.File{Path: "/var/lib/waagent/CustomData", Contents: ""}), }, } { a := waagent{tt.root, tt.files.ReadFile} _, err := a.FetchUserdata() if err != nil { - t.Fatalf("bad error for %q: want %v, got %q", tt, nil, err) + t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err) } } } diff --git a/test b/test index b9de140..a24bb31 100755 --- a/test +++ b/test @@ -24,6 +24,7 @@ declare -a TESTPKGS=( datasource/metadata/digitalocean datasource/metadata/ec2 datasource/proc_cmdline + datasource/test datasource/url datasource/waagent initialize From 987aa218839d557b27675953b46b1dcc387b04b0 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Fri, 13 Feb 2015 22:28:09 -0800 Subject: [PATCH 48/56] configdrive: check the network config path Check to make sure that a network config path has been specified before trying to read from it. Otherwise, it will end up trying to read a directory. --- datasource/configdrive/configdrive.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/datasource/configdrive/configdrive.go b/datasource/configdrive/configdrive.go index bbadf64..ed4c7c7 100644 --- a/datasource/configdrive/configdrive.go +++ b/datasource/configdrive/configdrive.go @@ -69,7 +69,9 @@ func (cd *configDrive) FetchMetadata() (metadata datasource.Metadata, err error) metadata.SSHPublicKeys = m.SSHAuthorizedKeyMap metadata.Hostname = m.Hostname - metadata.NetworkConfig, err = cd.tryReadFile(path.Join(cd.openstackRoot(), m.NetworkConfig.ContentPath)) + if m.NetworkConfig.ContentPath != "" { + metadata.NetworkConfig, err = cd.tryReadFile(path.Join(cd.openstackRoot(), m.NetworkConfig.ContentPath)) + } return } From 7bf9712724df622ebc0aa5d9c7d377338800f5a0 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 18 Feb 2015 11:12:46 -0800 Subject: [PATCH 49/56] coreos-cloudinit: bump to v1.3.2 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 5c32f26..7585b87 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.1+git" + version = "1.3.2" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From e0104e6d933a96de2cdb0f5ccc14232b005f35f2 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Wed, 18 Feb 2015 11:13:34 -0800 Subject: [PATCH 50/56] coreos-cloudinit: bump to v1.3.2+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 7585b87..91992cb 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.2" + version = "1.3.2+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From b429eaab84d313f61a0b59e937c88e2fc0e2a744 Mon Sep 17 00:00:00 2001 From: Rob Szumski Date: Wed, 18 Feb 2015 15:05:28 -0800 Subject: [PATCH 51/56] docs: fix formatting --- Documentation/cloud-config.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/cloud-config.md b/Documentation/cloud-config.md index c35f795..1256482 100644 --- a/Documentation/cloud-config.md +++ b/Documentation/cloud-config.md @@ -120,6 +120,7 @@ Environment="FLANNELD_ETCD_PREFIX=/coreos.com/network2" ``` List of flannel configuration parameters: + - **etcd_endpoints**: Comma separated list of etcd endpoints - **etcd_cafile**: Path to CA file used for TLS communication with etcd - **etcd_certfile**: Path to certificate file used for TLS communication with etcd From c30fc51b035e0bc1f8d35cb10b4bec5c7d1c6820 Mon Sep 17 00:00:00 2001 From: Kiril Vladimirov Date: Sat, 21 Feb 2015 19:22:16 +0200 Subject: [PATCH 52/56] fix(datasource/CloudSigma): Make sure public ssh key is not empty Even when public ssh key is not set by the user, CloudSigma's server context has a key `meta.ssh_public_key` which is just an empty string. So instead of just relying on the "comma ok" idiom I make sure the value is not an empty string. --- datasource/metadata/cloudsigma/server_context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index b618e45..d1a5015 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -108,7 +108,7 @@ func (scs *serverContextService) FetchMetadata() (metadata datasource.Metadata, } metadata.SSHPublicKeys = map[string]string{} - if key, ok := inputMetadata.Meta["ssh_public_key"]; ok { + if key, _ := inputMetadata.Meta["ssh_public_key"]; len(key) > 0 { splitted := strings.Split(key, " ") metadata.SSHPublicKeys[splitted[len(splitted)-1]] = key } From be53013431eddf412e29777e7b33d718531fc0d4 Mon Sep 17 00:00:00 2001 From: Kiril Vladimirov Date: Sun, 22 Feb 2015 05:31:38 +0200 Subject: [PATCH 53/56] fix(datasource/CloudSigma): Add a test for an empty ssh key --- .../metadata/cloudsigma/server_context.go | 2 ++ .../cloudsigma/server_context_test.go | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/datasource/metadata/cloudsigma/server_context.go b/datasource/metadata/cloudsigma/server_context.go index d1a5015..855ae97 100644 --- a/datasource/metadata/cloudsigma/server_context.go +++ b/datasource/metadata/cloudsigma/server_context.go @@ -108,6 +108,8 @@ func (scs *serverContextService) FetchMetadata() (metadata datasource.Metadata, } metadata.SSHPublicKeys = map[string]string{} + // CloudSigma uses an empty string, rather than no string, + // to represent the lack of a SSH key if key, _ := inputMetadata.Meta["ssh_public_key"]; len(key) > 0 { splitted := strings.Split(key, " ") metadata.SSHPublicKeys[splitted[len(splitted)-1]] = key diff --git a/datasource/metadata/cloudsigma/server_context_test.go b/datasource/metadata/cloudsigma/server_context_test.go index 726425b..4f29d7f 100644 --- a/datasource/metadata/cloudsigma/server_context_test.go +++ b/datasource/metadata/cloudsigma/server_context_test.go @@ -43,6 +43,27 @@ func (f *fakeCepgoClient) FetchRaw(key string) ([]byte, error) { return f.raw, f.err } +func TestServerContextWithEmptyPublicSSHKey(t *testing.T) { + client := new(fakeCepgoClient) + scs := NewServerContextService() + scs.client = client + client.raw = []byte(`{ + "meta": { + "base64_fields": "cloudinit-user-data", + "cloudinit-user-data": "I2Nsb3VkLWNvbmZpZwoKaG9zdG5hbWU6IGNvcmVvczE=", + "ssh_public_key": "" + } + }`) + metadata, err := scs.FetchMetadata() + if err != nil { + t.Error(err.Error()) + } + + if len(metadata.SSHPublicKeys) != 0 { + t.Error("There should be no Public SSH Keys provided") + } +} + func TestServerContextFetchMetadata(t *testing.T) { client := new(fakeCepgoClient) scs := NewServerContextService() From 672e4c07af698b52ffd38feff08672d74e36a977 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 23 Feb 2015 09:17:21 -0700 Subject: [PATCH 54/56] Fix typo, "contents" should be "content" The validation of the encoding for write_files was looking for a node named "contents" when the node name is "content" Signed-off-by: Darren Shepherd --- config/validate/rules.go | 4 ++-- config/validate/rules_test.go | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/config/validate/rules.go b/config/validate/rules.go index 4ba9606..1f65114 100644 --- a/config/validate/rules.go +++ b/config/validate/rules.go @@ -57,9 +57,9 @@ func checkEncoding(cfg node, report *Report) { continue } - c := f.Child("contents") + c := f.Child("content") if _, err := config.DecodeContent(c.String(), e.String()); err != nil { - report.Error(c.line, fmt.Sprintf("contents cannot be decoded as %q", e.String())) + report.Error(c.line, fmt.Sprintf("content cannot be decoded as %q", e.String())) } } } diff --git a/config/validate/rules_test.go b/config/validate/rules_test.go index dbfbaf8..01d4231 100644 --- a/config/validate/rules_test.go +++ b/config/validate/rules_test.go @@ -60,27 +60,27 @@ func TestCheckEncoding(t *testing.T) { }{ {}, { - config: "write_files:\n - encoding: base64\n contents: aGVsbG8K", + config: "write_files:\n - encoding: base64\n content: aGVsbG8K", }, { - config: "write_files:\n - contents: !!binary aGVsbG8K", + config: "write_files:\n - content: !!binary aGVsbG8K", }, { - config: "write_files:\n - encoding: base64\n contents: !!binary aGVsbG8K", - entries: []Entry{{entryError, `contents cannot be decoded as "base64"`, 3}}, + config: "write_files:\n - encoding: base64\n content: !!binary aGVsbG8K", + entries: []Entry{{entryError, `content cannot be decoded as "base64"`, 3}}, }, { - config: "write_files:\n - encoding: base64\n contents: !!binary YUdWc2JHOEsK", + config: "write_files:\n - encoding: base64\n content: !!binary YUdWc2JHOEsK", }, { - config: "write_files:\n - encoding: gzip\n contents: !!binary H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + config: "write_files:\n - encoding: gzip\n content: !!binary H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", }, { - config: "write_files:\n - encoding: gzip+base64\n contents: H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", + config: "write_files:\n - encoding: gzip+base64\n content: H4sIAOC3tVQAA8tIzcnJ5wIAIDA6NgYAAAA=", }, { - config: "write_files:\n - encoding: custom\n contents: hello", - entries: []Entry{{entryError, `contents cannot be decoded as "custom"`, 3}}, + config: "write_files:\n - encoding: custom\n content: hello", + entries: []Entry{{entryError, `content cannot be decoded as "custom"`, 3}}, }, } From 14cad6f7c3559b5611fe91e7e0452b4aac6c4c55 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 24 Feb 2015 12:24:37 -0800 Subject: [PATCH 55/56] coreos-cloudinit: bump to v1.3.3 --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 91992cb..5d8183d 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.2+git" + version = "1.3.3" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute From 66a2f00679ef4a78a20fe2593ef2cdf86aa51bea Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 24 Feb 2015 12:25:00 -0800 Subject: [PATCH 56/56] coreos-cloudinit: bump to v1.3.3+git --- coreos-cloudinit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 5d8183d..50be23b 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -39,7 +39,7 @@ import ( ) const ( - version = "1.3.3" + version = "1.3.3+git" datasourceInterval = 100 * time.Millisecond datasourceMaxInterval = 30 * time.Second datasourceTimeout = 5 * time.Minute