-
Notifications
You must be signed in to change notification settings - Fork 653
/
Copy pathtemplate.go
144 lines (130 loc) · 2.92 KB
/
template.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package cidata
import (
"bytes"
"embed"
"errors"
"fmt"
"io/fs"
"path"
"github.com/lima-vm/lima/pkg/iso9660util"
"github.com/containerd/containerd/identifiers"
"github.com/lima-vm/lima/pkg/textutil"
)
//go:embed cidata.TEMPLATE.d
var templateFS embed.FS
const templateFSRoot = "cidata.TEMPLATE.d"
type CACerts struct {
RemoveDefaults *bool
Trusted []Cert
}
type Cert struct {
Lines []string
}
type Containerd struct {
System bool
User bool
}
type Network struct {
MACAddress string
Interface string
}
type Mount struct {
Tag string
MountPoint string // abs path, accessible by the User
Type string
Options string
}
type BootCmds struct {
Lines []string
}
type Disk struct {
Name string
Device string
}
type TemplateArgs struct {
Name string // instance name
IID string // instance id
User string // user name
UID int
SSHPubKeys []string
Mounts []Mount
MountType string
Disks []Disk
Containerd Containerd
Networks []Network
SlirpNICName string
SlirpGateway string
SlirpDNS string
SlirpIPAddress string
UDPDNSLocalPort int
TCPDNSLocalPort int
Env map[string]string
DNSAddresses []string
CACerts CACerts
HostHomeMountPoint string
BootCmds []BootCmds
RosettaEnabled bool
RosettaBinFmt bool
}
func ValidateTemplateArgs(args TemplateArgs) error {
if err := identifiers.Validate(args.Name); err != nil {
return err
}
if err := identifiers.Validate(args.User); err != nil {
return err
}
// if args.User == "root" {
// return errors.New("field User must not be \"root\"")
// }
// if args.UID == 0 {
// return errors.New("field UID must not be 0")
// }
if len(args.SSHPubKeys) == 0 {
return errors.New("field SSHPubKeys must be set")
}
for i, m := range args.Mounts {
f := m.MountPoint
if !path.IsAbs(f) {
return fmt.Errorf("field mounts[%d] must be absolute, got %q", i, f)
}
}
return nil
}
func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, error) {
if err := ValidateTemplateArgs(args); err != nil {
return nil, err
}
fsys, err := fs.Sub(templateFS, templateFSRoot)
if err != nil {
return nil, err
}
var layout []iso9660util.Entry
walkFn := func(path string, d fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if d.IsDir() {
return nil
}
if !d.Type().IsRegular() {
return fmt.Errorf("got non-regular file %q", path)
}
templateB, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
b, err := textutil.ExecuteTemplate(string(templateB), args)
if err != nil {
return err
}
layout = append(layout, iso9660util.Entry{
Path: path,
Reader: bytes.NewReader(b),
})
return nil
}
if err := fs.WalkDir(fsys, ".", walkFn); err != nil {
return nil, err
}
return layout, nil
}