-
Notifications
You must be signed in to change notification settings - Fork 107
/
filesystem_customizations.go
117 lines (99 loc) · 3.35 KB
/
filesystem_customizations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package blueprint
import (
"encoding/json"
"fmt"
"github.com/osbuild/osbuild-composer/internal/common"
)
type FilesystemCustomization struct {
Mountpoint string `json:"mountpoint,omitempty" toml:"mountpoint,omitempty"`
MinSize uint64 `json:"minsize,omitempty" toml:"minsize,omitempty"`
// Note: The TOML `size` tag has been deprecated in favor of `minsize`.
// we check for it in the TOML unmarshaler and use it as `minsize`.
// However due to the TOML marshaler implementation, we can omit adding
// a field for this tag and get the benifit of not having to export it.
}
func (fsc *FilesystemCustomization) UnmarshalTOML(data interface{}) error {
d, _ := data.(map[string]interface{})
switch d["mountpoint"].(type) {
case string:
fsc.Mountpoint = d["mountpoint"].(string)
default:
return fmt.Errorf("TOML unmarshal: mountpoint must be string, got %v of type %T", d["mountpoint"], d["mountpoint"])
}
var size uint64
var minsize uint64
// `size` is an alias for `minsize. We check for the `size` keyword
// for backwards compatibility. We don't export a `Size` field as
// we would like to discourage its use.
switch d["size"].(type) {
case int64:
size = uint64(d["size"].(int64))
case string:
s, err := common.DataSizeToUint64(d["size"].(string))
if err != nil {
return fmt.Errorf("TOML unmarshal: size is not valid filesystem size (%w)", err)
}
size = s
case nil:
size = 0
default:
return fmt.Errorf("TOML unmarshal: size must be integer or string, got %v of type %T", d["size"], d["size"])
}
switch d["minsize"].(type) {
case int64:
minsize = uint64(d["minsize"].(int64))
case string:
s, err := common.DataSizeToUint64(d["minsize"].(string))
if err != nil {
return fmt.Errorf("TOML unmarshal: minsize is not valid filesystem size (%w)", err)
}
minsize = s
case nil:
minsize = 0
default:
return fmt.Errorf("TOML unmarshal: minsize must be integer or string, got %v of type %T", d["minsize"], d["minsize"])
}
if size == 0 && minsize == 0 {
return fmt.Errorf("TOML unmarshal: minsize must be greater than 0, got %v", minsize)
}
if size > 0 && minsize == 0 {
fsc.MinSize = size
return nil
}
if size == 0 && minsize > 0 {
fsc.MinSize = minsize
return nil
}
if size > 0 && minsize > 0 {
return fmt.Errorf("TOML unmarshal: size and minsize cannot both be set (size is an alias for minsize)")
}
return nil
}
func (fsc *FilesystemCustomization) UnmarshalJSON(data []byte) error {
var v interface{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
d, _ := v.(map[string]interface{})
switch d["mountpoint"].(type) {
case string:
fsc.Mountpoint = d["mountpoint"].(string)
default:
return fmt.Errorf("JSON unmarshal: mountpoint must be string, got %v of type %T", d["mountpoint"], d["mountpoint"])
}
// The JSON specification only mentions float64 and Go defaults to it: https://go.dev/blog/json
switch d["minsize"].(type) {
case float64:
// Note that it uses different key than the TOML version
fsc.MinSize = uint64(d["minsize"].(float64))
case string:
size, err := common.DataSizeToUint64(d["minsize"].(string))
if err != nil {
return fmt.Errorf("JSON unmarshal: size is not valid filesystem size (%w)", err)
}
fsc.MinSize = size
default:
return fmt.Errorf("JSON unmarshal: minsize must be float64 number or string, got %v of type %T", d["minsize"], d["minsize"])
}
return nil
}