Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3db7ced

Browse files
Merge pull request #3892 from norio-nomura/yq-provision-mode
feature: "yq" provision mode
2 parents 6414eca + 2f2f47f commit 3db7ced

File tree

16 files changed

+273
-30
lines changed

16 files changed

+273
-30
lines changed

‎hack/test-templates.sh‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ declare -A CHECKS=(
5656
["user-v2"]=""
5757
["mount-path-with-spaces"]=""
5858
["provision-data"]=""
59+
["provision-yq"]=""
5960
["param-env-variables"]=""
6061
["set-user"]=""
6162
["preserve-env"]="1"
@@ -90,6 +91,7 @@ case "$NAME" in
9091
CHECKS["clone"]="1"
9192
CHECKS["mount-path-with-spaces"]="1"
9293
CHECKS["provision-data"]="1"
94+
CHECKS["provision-yq"]="1"
9395
CHECKS["param-env-variables"]="1"
9496
CHECKS["set-user"]="1"
9597
;;
@@ -199,6 +201,11 @@ if [[ -n ${CHECKS["provision-data"]} ]]; then
199201
limactl shell "$NAME" grep -q fs.inotify.max_user_watches /etc/sysctl.d/99-inotify.conf
200202
fi
201203

204+
if [[ -n ${CHECKS["provision-yq"]} ]]; then
205+
INFO 'Testing that /tmp/param-yq.json was created successfully on provision'
206+
limactl shell "$NAME" grep -q '"YQ": "yq"' /tmp/param-yq.json
207+
fi
208+
202209
if [[ -n ${CHECKS["param-env-variables"]} ]]; then
203210
INFO 'Testing that PARAM env variables are exported to all types of provisioning scripts and probes'
204211
limactl shell "$NAME" test -e /tmp/param-ansible

‎hack/test-templates/test-misc.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ param:
2020
PROBE: probe
2121
SYSTEM: system
2222
USER: user
23+
YQ: yq
2324

2425
provision:
2526
- mode: ansible
@@ -37,6 +38,10 @@ provision:
3738
content: |
3839
fs.inotify.max_user_watches = 524288
3940
fs.inotify.max_user_instances = 512
41+
- mode: yq
42+
path: "/tmp/param-{{.Param.YQ}}.json"
43+
expression: .YQ = "{{.Param.YQ}}"
44+
user: "{{.User}}"
4045

4146
probes:
4247
- mode: readiness

‎pkg/cidata/cidata.TEMPLATE.d/boot.sh‎

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,93 @@ if [ -d "${LIMA_CIDATA_MNT}"/provision.data ]; then
6464
owner=$(deref "LIMA_CIDATA_DATAFILE_${filename}_OWNER")
6565
path=$(deref "LIMA_CIDATA_DATAFILE_${filename}_PATH")
6666
permissions=$(deref "LIMA_CIDATA_DATAFILE_${filename}_PERMISSIONS")
67+
user="${owner%%:*}"
6768
if [ -e "$path" ] && [ "$overwrite" = "false" ]; then
6869
INFO "Not overwriting $path"
6970
else
7071
INFO "Copying $f to $path"
71-
# intermediate directories will be owned by root, regardless of OWNER setting
72-
mkdir -p "$(dirname "$path")"
72+
if ! sudo -iu "${user}" mkdir -p "$(dirname "$path")"; then
73+
WARNING "Failed to create directory for ${path} (as user ${user})"
74+
WARNING "Falling back to creating directory as root to maintain compatibility"
75+
mkdir -p "$(dirname "$path")"
76+
fi
7377
cp "$f" "$path"
7478
chown "$owner" "$path"
7579
chmod "$permissions" "$path"
7680
fi
7781
done
7882
fi
7983

84+
if [ -d "${LIMA_CIDATA_MNT}"/provision.yq ]; then
85+
yq="${LIMA_CIDATA_MNT}/lima-guestagent yq"
86+
for f in "${LIMA_CIDATA_MNT}"/provision.yq/*; do
87+
filename=$(basename "${f}")
88+
format=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_FORMAT")
89+
owner=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_OWNER")
90+
path=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_PATH")
91+
permissions=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_PERMISSIONS")
92+
user="${owner%%:*}"
93+
# Creating intermediate directories may fail if the user does not have permission.
94+
# TODO: Create intermediate directories with the specified group ownership.
95+
if ! sudo -iu "${user}" mkdir -p "$(dirname "${path}")"; then
96+
WARNING "Failed to create directory for ${path} (as user ${user})"
97+
CODE=1
98+
continue
99+
fi
100+
# Since CIDATA is mounted with dmode=700,fmode=700,
101+
# `lima-guestagent yq` cannot be executed by non-root users,
102+
# and provision.yq/* files cannot be read by non-root users.
103+
if [ -f "${path}" ]; then
104+
INFO "Updating ${path}"
105+
# If the user does not have write permission, it should fail.
106+
# This avoids changes being made by the wrong user.
107+
if ! sudo -iu "${user}" test -w "${path}"; then
108+
WARNING "File ${path} is not writable by user ${user}"
109+
CODE=1
110+
continue
111+
fi
112+
# Relies on the fact that yq does not change the owner of the existing file.
113+
if ! ${yq} --inplace --from-file "${f}" --input-format "${format}" --output-format "${format}" "${path}"; then
114+
WARNING "Failed to update ${path} (as user ${user})"
115+
CODE=1
116+
continue
117+
fi
118+
else
119+
if [ "${format}" = "auto" ]; then
120+
# yq can't determine the output format from non-existing files
121+
case "${path}" in
122+
*.csv) format=csv ;;
123+
*.ini) format=ini ;;
124+
*.json) format=json ;;
125+
*.properties) format=properties ;;
126+
*.toml) format=toml ;;
127+
*.tsv) format=tsv ;;
128+
*.xml) format=xml ;;
129+
*.yaml | *.yml) format=yaml ;;
130+
*)
131+
format=yaml
132+
WARNING "Cannot determine file type for ${path}, using yaml format"
133+
;;
134+
esac
135+
fi
136+
INFO "Creating ${path}"
137+
if ! ${yq} --null-input --from-file "${f}" --output-format "${format}" | sudo -iu "${user}" tee "${path}"; then
138+
WARNING "Failed to create ${path} (as user ${user})"
139+
CODE=1
140+
continue
141+
fi
142+
fi
143+
if ! sudo -iu "${user}" chown "${owner}" "${path}"; then
144+
WARNING "Failed to set owner for ${path} (as user ${user})"
145+
CODE=1
146+
fi
147+
if ! sudo -iu "${user}" chmod "${permissions}" "${path}"; then
148+
WARNING "Failed to set permissions for ${path} (as user ${user})"
149+
CODE=1
150+
fi
151+
done
152+
fi
153+
80154
if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then
81155
for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do
82156
INFO "Executing $f"

‎pkg/cidata/cidata.TEMPLATE.d/lima.env‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ LIMA_CIDATA_DATAFILE_{{$dataFile.FileName}}_OWNER={{$dataFile.Owner}}
2525
LIMA_CIDATA_DATAFILE_{{$dataFile.FileName}}_PATH={{$dataFile.Path}}
2626
LIMA_CIDATA_DATAFILE_{{$dataFile.FileName}}_PERMISSIONS={{$dataFile.Permissions}}
2727
{{- end}}
28+
{{- range $yqProvision := .YQProvisions}}
29+
LIMA_CIDATA_YQ_PROVISION_{{$yqProvision.FileName}}_FORMAT={{$yqProvision.Format}}
30+
LIMA_CIDATA_YQ_PROVISION_{{$yqProvision.FileName}}_OWNER={{$yqProvision.Owner}}
31+
LIMA_CIDATA_YQ_PROVISION_{{$yqProvision.FileName}}_PATH={{$yqProvision.Path}}
32+
LIMA_CIDATA_YQ_PROVISION_{{$yqProvision.FileName}}_PERMISSIONS={{$yqProvision.Permissions}}
33+
{{- end}}
2834
LIMA_CIDATA_GUEST_INSTALL_PREFIX={{ .GuestInstallPrefix }}
2935
{{- if .Containerd.User}}
3036
LIMA_CIDATA_CONTAINERD_USER=1

‎pkg/cidata/cidata.go‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,15 @@ func templateArgs(ctx context.Context, bootScripts bool, instDir, name string, i
335335
Permissions: *f.Permissions,
336336
})
337337
}
338+
if f.Mode == limatype.ProvisionModeYQ {
339+
args.YQProvisions = append(args.YQProvisions, YQProvision{
340+
FileName: fmt.Sprintf("%08d", i),
341+
Format: *f.Format,
342+
Owner: *f.Owner,
343+
Path: *f.Path,
344+
Permissions: *f.Permissions,
345+
})
346+
}
338347
}
339348

340349
return &args, nil
@@ -402,6 +411,11 @@ func GenerateISO9660(ctx context.Context, drv driver.Driver, instDir, name strin
402411
Path: fmt.Sprintf("provision.%s/%08d", f.Mode, i),
403412
Reader: strings.NewReader(*f.Content),
404413
})
414+
case limatype.ProvisionModeYQ:
415+
layout = append(layout, iso9660util.Entry{
416+
Path: fmt.Sprintf("provision.%s/%08d", f.Mode, i),
417+
Reader: strings.NewReader(*f.Expression),
418+
})
405419
case limatype.ProvisionModeBoot:
406420
continue
407421
case limatype.ProvisionModeAnsible:

‎pkg/cidata/template.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ type DataFile struct {
5858
Permissions string
5959
}
6060

61+
type YQProvision struct {
62+
FileName string
63+
Format string
64+
Owner string
65+
Path string
66+
Permissions string
67+
}
68+
6169
type Disk struct {
6270
Name string
6371
Device string
@@ -93,6 +101,7 @@ type TemplateArgs struct {
93101
Param map[string]string
94102
BootScripts bool
95103
DataFiles []DataFile
104+
YQProvisions []YQProvision
96105
DNSAddresses []string
97106
CACerts CACerts
98107
HostHomeMountPoint string

‎pkg/limatmpl/embed.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,11 @@ func (tmpl *Template) embedAllScripts(ctx context.Context, embedAll bool) error
648648
if p.Content != nil {
649649
continue
650650
}
651+
case limatype.ProvisionModeYQ:
652+
newName = "expression"
653+
if p.Expression != nil {
654+
continue
655+
}
651656
default:
652657
if p.Script != "" {
653658
continue

‎pkg/limatmpl/embed_test.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ provision:
343343
- mode: data
344344
file: base1.sh # This comment will move to the "content" key
345345
path: /tmp/data
346+
- mode: yq
347+
file: base1.sh # This comment will move to the "expression" key
348+
path: /tmp/yq
346349
`,
347350
`
348351
# base0.yaml is ignored
@@ -364,6 +367,11 @@ provision:
364367
#!/usr/bin/env bash
365368
echo "This is base1.sh"
366369
path: /tmp/data
370+
- mode: yq
371+
expression: |- # This comment will move to the "expression" key
372+
#!/usr/bin/env bash
373+
echo "This is base1.sh"
374+
path: /tmp/yq
367375
368376
# base0.yaml is ignored
369377
`,

‎pkg/limatype/lima_yaml.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ const (
235235
ProvisionModeDependency ProvisionMode = "dependency"
236236
ProvisionModeAnsible ProvisionMode = "ansible" // DEPRECATED
237237
ProvisionModeData ProvisionMode = "data"
238+
ProvisionModeYQ ProvisionMode = "yq"
238239
)
239240

240241
type Provision struct {
@@ -245,6 +246,9 @@ type Provision struct {
245246
Playbook string `yaml:"playbook,omitempty" json:"playbook,omitempty"` // DEPRECATED
246247
// All ProvisionData fields must be nil unless Mode is ProvisionModeData
247248
ProvisionData `yaml:",inline"` // Flatten fields for "strict" YAML mode
249+
// ProvisionModeYQ borrows Owner, Path, and Permissions from ProvisionData
250+
Expression *string `yaml:"expression,omitempty" json:"expression,omitempty" jsonschema:"nullable"`
251+
Format *string `yaml:"format,omitempty" json:"format,omitempty" jsonschema:"nullable"`
248252
}
249253

250254
type ProvisionData struct {

‎pkg/limayaml/defaults.go‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,27 @@ func FillDefault(ctx context.Context, y, d, o *limatype.LimaYAML, filePath strin
405405
if provision.Overwrite == nil {
406406
provision.Overwrite = ptr.Of(true)
407407
}
408+
}
409+
if provision.Mode == limatype.ProvisionModeYQ {
410+
if provision.Expression != nil {
411+
if out, err := executeGuestTemplate(*provision.Expression, instDir, y.User, y.Param); err == nil {
412+
provision.Expression = ptr.Of(out.String())
413+
} else {
414+
logrus.WithError(err).Warnf("Couldn't process expression %q as a template", *provision.Expression)
415+
}
416+
}
417+
if provision.Format == nil {
418+
provision.Format = ptr.Of("auto")
419+
}
420+
}
421+
if provision.Mode == limatype.ProvisionModeData || provision.Mode == limatype.ProvisionModeYQ {
408422
if provision.Owner == nil {
409423
provision.Owner = ptr.Of("root:root")
410424
} else {
411425
if out, err := executeGuestTemplate(*provision.Owner, instDir, y.User, y.Param); err == nil {
412426
provision.Owner = ptr.Of(out.String())
413427
} else {
414-
logrus.WithError(err).Warnf("Couldn't owner %q as a template", *provision.Owner)
428+
logrus.WithError(err).Warnf("Couldn't process owner %q as a template", *provision.Owner)
415429
}
416430
}
417431
// Path is required; validation will throw an error when it is nil

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /