Skip to content

Commit 82ed658

Browse files
authored
Accept string or numeric spec.host.files.perm (#248)
1 parent 92714ef commit 82ed658

File tree

3 files changed

+117
-6
lines changed

3 files changed

+117
-6
lines changed

config/cluster/uploadfile.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,60 @@
11
package cluster
22

33
import (
4+
"fmt"
45
"path/filepath"
6+
"strconv"
57
)
68

79
// UploadFile describes a file to be uploaded for the host
810
type UploadFile struct {
9-
Name string `yaml:"name,omitempty"`
10-
Source string `yaml:"src" validate:"required"`
11-
DestinationDir string `yaml:"dstDir" validate:"required"`
12-
PermMode string `yaml:"perm" default:"0755"`
11+
Name string `yaml:"name,omitempty"`
12+
Source string `yaml:"src" validate:"required"`
13+
DestinationDir string `yaml:"dstDir" validate:"required"`
14+
PermMode interface{} `yaml:"perm" default:"0755"`
15+
PermString string `yaml:"-"`
16+
}
17+
18+
// UnmarshalYAML sets in some sane defaults when unmarshaling the data from yaml
19+
func (u *UploadFile) UnmarshalYAML(unmarshal func(interface{}) error) error {
20+
type uploadFile UploadFile
21+
yu := (*uploadFile)(u)
22+
23+
if err := unmarshal(yu); err != nil {
24+
return err
25+
}
26+
27+
switch t := u.PermMode.(type) {
28+
case int:
29+
if t < 0 {
30+
return fmt.Errorf("invalid uploadFile permission: %d: must be a positive value", t)
31+
}
32+
if t == 0 {
33+
return fmt.Errorf("invalid nil uploadFile permission")
34+
}
35+
u.PermString = fmt.Sprintf("%#o", t)
36+
case string:
37+
u.PermString = t
38+
default:
39+
return fmt.Errorf("invalid value for uploadFile perm, must be a string or a number")
40+
}
41+
42+
for i, c := range u.PermString {
43+
n, err := strconv.Atoi(string(c))
44+
if err != nil {
45+
return fmt.Errorf("failed to parse uploadFile permission %s: %w", u.PermString, err)
46+
}
47+
48+
// These could catch some weird octal conversion mistakes
49+
if i == 1 && n < 4 {
50+
return fmt.Errorf("invalid uploadFile permission %s: owner would have unconventional access", u.PermString)
51+
}
52+
if n > 7 {
53+
return fmt.Errorf("invalid uploadFile permission %s: octal value can't have numbers over 7", u.PermString)
54+
}
55+
}
56+
57+
return nil
1358
}
1459

1560
func (u *UploadFile) Resolve() ([]string, error) {

config/cluster/uploadfile_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package cluster
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"gopkg.in/yaml.v2"
8+
)
9+
10+
func TestPermStringUnmarshalWithOctal(t *testing.T) {
11+
u := UploadFile{}
12+
yml := []byte(`
13+
src: /tmp
14+
dstDir: /tmp
15+
perm: 0755
16+
`)
17+
18+
require.NoError(t, yaml.Unmarshal(yml, &u))
19+
require.Equal(t, "0755", u.PermString)
20+
}
21+
22+
func TestPermStringUnmarshalWithString(t *testing.T) {
23+
u := UploadFile{}
24+
yml := []byte(`
25+
src: /tmp
26+
dstDir: /tmp
27+
perm: "0755"
28+
`)
29+
30+
require.NoError(t, yaml.Unmarshal(yml, &u))
31+
require.Equal(t, "0755", u.PermString)
32+
}
33+
34+
func TestPermStringUnmarshalWithInvalidString(t *testing.T) {
35+
u := UploadFile{}
36+
yml := []byte(`
37+
src: /tmp
38+
dstDir: /tmp
39+
perm: u+rwx
40+
`)
41+
42+
require.Error(t, yaml.Unmarshal(yml, &u))
43+
}
44+
45+
func TestPermStringUnmarshalWithInvalidNumber(t *testing.T) {
46+
u := UploadFile{}
47+
yml := []byte(`
48+
src: /tmp
49+
dstDir: /tmp
50+
perm: 0800
51+
`)
52+
53+
require.Error(t, yaml.Unmarshal(yml, &u))
54+
}
55+
56+
func TestPermStringUnmarshalWithZero(t *testing.T) {
57+
u := UploadFile{}
58+
yml := []byte(`
59+
src: /tmp
60+
dstDir: /tmp
61+
perm: 0
62+
`)
63+
t.Logf("what the hell: %+v %+v", u.PermMode, u.PermString)
64+
65+
require.Error(t, yaml.Unmarshal(yml, &u))
66+
}

phase/uploadfiles.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (p *UploadFiles) uploadFiles(h *cluster.Host) error {
5050
return err
5151
}
5252

53-
if err := h.Execf("install -d %s -m %s", f.DestinationDir, f.PermMode, exec.Sudo(h)); err != nil {
53+
if err := h.Execf("install -d %s -m %s", f.DestinationDir, f.PermString, exec.Sudo(h)); err != nil {
5454
return err
5555
}
5656

@@ -62,7 +62,7 @@ func (p *UploadFiles) uploadFiles(h *cluster.Host) error {
6262
return err
6363
}
6464

65-
if err := h.Configurer.Chmod(h, destination, f.PermMode); err != nil {
65+
if err := h.Configurer.Chmod(h, destination, f.PermString); err != nil {
6666
return err
6767
}
6868
}

0 commit comments

Comments
 (0)