diff --git a/coreos-cloudinit.go b/coreos-cloudinit.go index 9431690..68e23e1 100644 --- a/coreos-cloudinit.go +++ b/coreos-cloudinit.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "os" - "strings" "github.com/coreos/coreos-cloudinit/datasource" "github.com/coreos/coreos-cloudinit/initialize" @@ -76,7 +75,7 @@ func main() { userdata := string(userdataBytes) userdata = env.Apply(userdata) - parsed, err := ParseUserData(userdata) + parsed, err := initialize.ParseUserData(userdata) if err != nil { log.Printf("Failed parsing user-data: %v", err) if ignoreFailure { @@ -109,21 +108,3 @@ func main() { } } -func ParseUserData(contents string) (interface{}, error) { - header := strings.SplitN(contents, "\n", 2)[0] - - if strings.HasPrefix(header, "#!") { - log.Printf("Parsing user-data as script") - return system.Script(contents), nil - - } else if header == "#cloud-config" { - log.Printf("Parsing user-data as cloud-config") - cfg, err := initialize.NewCloudConfig(contents) - if err != nil { - log.Fatal(err.Error()) - } - return *cfg, nil - } else { - return nil, fmt.Errorf("Unrecognized user-data header: %s", header) - } -} diff --git a/initialize/user_data.go b/initialize/user_data.go new file mode 100644 index 0000000..a34d534 --- /dev/null +++ b/initialize/user_data.go @@ -0,0 +1,33 @@ +package initialize + +import ( + "fmt" + "log" + "strings" + + "github.com/coreos/coreos-cloudinit/system" +) + +func ParseUserData(contents string) (interface{}, error) { + header := strings.SplitN(contents, "\n", 2)[0] + + // Explicitly trim the header so we can handle user-data from + // non-unix operating systems. The rest of the file is parsed + // by goyaml, which correctly handles CRLF. + header = strings.TrimSpace(header) + + if strings.HasPrefix(header, "#!") { + log.Printf("Parsing user-data as script") + return system.Script(contents), nil + + } else if header == "#cloud-config" { + log.Printf("Parsing user-data as cloud-config") + cfg, err := NewCloudConfig(contents) + if err != nil { + log.Fatal(err.Error()) + } + return *cfg, nil + } else { + return nil, fmt.Errorf("Unrecognized user-data header: %s", header) + } +} diff --git a/initialize/user_data_test.go b/initialize/user_data_test.go new file mode 100644 index 0000000..c24d322 --- /dev/null +++ b/initialize/user_data_test.go @@ -0,0 +1,31 @@ +package initialize + +import ( + "testing" +) + +func TestParseHeaderCRLF(t *testing.T) { + configs := []string{ + "#cloud-config\nfoo: bar", + "#cloud-config\r\nfoo: bar", + } + + for i, config := range configs { + _, err := ParseUserData(config) + if err != nil { + t.Errorf("Failed parsing config %d: %v", i, err) + } + } + + scripts := []string{ + "#!bin/bash\necho foo", + "#!bin/bash\r\necho foo", + } + + for i, script := range scripts { + _, err := ParseUserData(script) + if err != nil { + t.Errorf("Failed parsing script %d: %v", i, err) + } + } +}