Skip to content
This repository was archived by the owner on Sep 18, 2020. It is now read-only.

Commit 1cd1ecb

Browse files
committed
Merge pull request #423 from cihangir/decoding-support-for-writefiles
config: add decoding support for cloud init template write_files section
2 parents d17c76c + 2b5417e commit 1cd1ecb

File tree

5 files changed

+77
-64
lines changed

5 files changed

+77
-64
lines changed

config/config.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ func NewCloudConfig(contents string) (*CloudConfig, error) {
6868
return &cfg, err
6969
}
7070

71+
// Decode decodes the content of cloud config. Currently only WriteFiles section
72+
// supports several types of encoding and all of them are supported. After
73+
// decode operation, Encoding type is unset.
74+
func (cc *CloudConfig) Decode() error {
75+
for i, file := range cc.WriteFiles {
76+
content, err := DecodeContent(file.Content, file.Encoding)
77+
if err != nil {
78+
return err
79+
}
80+
81+
cc.WriteFiles[i].Content = string(content)
82+
cc.WriteFiles[i].Encoding = ""
83+
}
84+
85+
return nil
86+
}
7187
func (cc CloudConfig) String() string {
7288
bytes, err := yaml.Marshal(cc)
7389
if err != nil {

config/config_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package config
1616

1717
import (
18+
"fmt"
1819
"reflect"
1920
"regexp"
2021
"strings"
@@ -73,6 +74,50 @@ func TestNewCloudConfig(t *testing.T) {
7374
}
7475
}
7576

77+
func TestNewCloudConfigDecode(t *testing.T) {
78+
// //all of these decode to "bar"
79+
contentTests := map[string]string{
80+
"base64": "YmFy",
81+
"b64": "YmFy",
82+
// theoretically gz+gzip are supported but they break yaml
83+
// "gz": "\x1f\x8b\x08\x08w\x14\x87T\x02\xffok\x00KJ,\x02\x00\xaa\x8c\xffv\x03\x00\x00\x00",
84+
// "gzip": "\x1f\x8b\x08\x08w\x14\x87T\x02\xffok\x00KJ,\x02\x00\xaa\x8c\xffv\x03\x00\x00\x00",
85+
"gz+base64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
86+
"gzip+base64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
87+
"gz+b64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
88+
"gzip+b64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
89+
}
90+
91+
type testCase struct {
92+
contents string
93+
config CloudConfig
94+
}
95+
96+
var decodingTests []testCase
97+
for name, content := range contentTests {
98+
decodingTests = append(decodingTests, testCase{
99+
contents: fmt.Sprintf("#cloud-config\nwrite_files:\n - encoding: %q\n content: |\n %s", name, content),
100+
config: CloudConfig{WriteFiles: []File{{Content: "bar"}}},
101+
})
102+
}
103+
104+
for i, tt := range decodingTests {
105+
config, err := NewCloudConfig(tt.contents)
106+
if err != nil {
107+
t.Errorf("bad error (test case #%d): want %v, got %s", i, nil, err)
108+
}
109+
110+
if err := config.Decode(); err != nil {
111+
t.Errorf("bad error (test case #%d): want %v, got %s", i, nil, err)
112+
}
113+
114+
if !reflect.DeepEqual(&tt.config, config) {
115+
t.Errorf("bad config (test case #%d): want %#v, got %#v", i, tt.config, config)
116+
}
117+
}
118+
119+
}
120+
76121
func TestIsZero(t *testing.T) {
77122
tests := []struct {
78123
c interface{}

initialize/user_data.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,16 @@ func ParseUserData(contents string) (interface{}, error) {
3636
return config.NewScript(contents)
3737
case config.IsCloudConfig(contents):
3838
log.Printf("Parsing user-data as cloud-config")
39-
return config.NewCloudConfig(contents)
39+
cc, err := config.NewCloudConfig(contents)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
if err := cc.Decode(); err != nil {
45+
return nil, err
46+
}
47+
48+
return cc, nil
4049
case config.IsIgnitionConfig(contents):
4150
return nil, ErrIgnitionConfig
4251
default:

system/file.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,16 @@ func (f *File) Permissions() (os.FileMode, error) {
4545
return os.FileMode(perm), nil
4646
}
4747

48+
// WriteFile writes given endecoded file to the filesystem
4849
func WriteFile(f *File, root string) (string, error) {
50+
if f.Encoding != "" {
51+
return "", fmt.Errorf("Unable to write file with encoding %s", f.Encoding)
52+
}
53+
4954
fullpath := path.Join(root, f.Path)
5055
dir := path.Dir(fullpath)
5156
log.Printf("Writing file to %q", fullpath)
5257

53-
content, err := config.DecodeContent(f.Content, f.Encoding)
54-
55-
if err != nil {
56-
return "", fmt.Errorf("Unable to decode %s (%v)", f.Path, err)
57-
}
58-
5958
if err := EnsureDirectoryExists(dir); err != nil {
6059
return "", err
6160
}
@@ -71,7 +70,7 @@ func WriteFile(f *File, root string) (string, error) {
7170
return "", err
7271
}
7372

74-
if err := ioutil.WriteFile(tmp.Name(), content, perm); err != nil {
73+
if err := ioutil.WriteFile(tmp.Name(), []byte(f.Content), perm); err != nil {
7574
return "", err
7675
}
7776

system/file_test.go

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -147,62 +147,6 @@ func TestWriteFilePermissions(t *testing.T) {
147147
}
148148
}
149149

150-
func TestWriteFileEncodedContent(t *testing.T) {
151-
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
152-
if err != nil {
153-
t.Fatalf("Unable to create tempdir: %v", err)
154-
}
155-
defer os.RemoveAll(dir)
156-
157-
//all of these decode to "bar"
158-
content_tests := map[string]string{
159-
"base64": "YmFy",
160-
"b64": "YmFy",
161-
"gz": "\x1f\x8b\x08\x08w\x14\x87T\x02\xffok\x00KJ,\x02\x00\xaa\x8c\xffv\x03\x00\x00\x00",
162-
"gzip": "\x1f\x8b\x08\x08w\x14\x87T\x02\xffok\x00KJ,\x02\x00\xaa\x8c\xffv\x03\x00\x00\x00",
163-
"gz+base64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
164-
"gzip+base64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
165-
"gz+b64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
166-
"gzip+b64": "H4sIABMVh1QAA0tKLAIAqoz/dgMAAAA=",
167-
}
168-
169-
for encoding, content := range content_tests {
170-
fullPath := path.Join(dir, encoding)
171-
172-
wf := File{config.File{
173-
Path: encoding,
174-
Encoding: encoding,
175-
Content: content,
176-
RawFilePermissions: "0644",
177-
}}
178-
179-
path, err := WriteFile(&wf, dir)
180-
if err != nil {
181-
t.Fatalf("Processing of WriteFile failed: %v", err)
182-
} else if path != fullPath {
183-
t.Fatalf("WriteFile returned bad path: want %s, got %s", fullPath, path)
184-
}
185-
186-
fi, err := os.Stat(fullPath)
187-
if err != nil {
188-
t.Fatalf("Unable to stat file: %v", err)
189-
}
190-
191-
if fi.Mode() != os.FileMode(0644) {
192-
t.Errorf("File has incorrect mode: %v", fi.Mode())
193-
}
194-
195-
contents, err := ioutil.ReadFile(fullPath)
196-
if err != nil {
197-
t.Fatalf("Unable to read expected file: %v", err)
198-
}
199-
200-
if string(contents) != "bar" {
201-
t.Fatalf("File has incorrect contents: '%s'", contents)
202-
}
203-
}
204-
}
205-
206150
func TestWriteFileInvalidEncodedContent(t *testing.T) {
207151
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
208152
if err != nil {

0 commit comments

Comments
 (0)