elemental-toolkit version:
v2.3.2, with base image registry.suse.com/suse/sl-micro/6.2/baremetal-iso-image:2.3.0-7.111.
CPU architecture, OS, and Version:
x86_64, SUSE Linux Micro 6.2.
Describe the bug
The permissions field behaves differently depending on which of the two file-writing mechanisms you use, and the difference isn't documented.
write_files: (the cloud-init compatibility path) treats permissions as an octal string, so permissions: "0600" produces mode 0o600.
Extended files: (a yip stage step) treats permissions as a raw integer and applies it directly as the file mode (os.FileMode(n)). There, permissions: "0600" as a string doesn't unmarshal into the integer field and the file is silently not written. A bare permissions: 0600 depends on the parser: YAML reads it as octal 384 (correct), while a JSON/decimal path gives 600, which is mode 0o1130. Only the decimal 384 is unambiguous.
So the same permissions: "0600" works under write_files: but is silently dropped under files:. The docs show permissions: 0644 for files: without noting that it only works because YAML happens to parse the leading zero as octal.
To Reproduce
Consumed here through a Rancher SeedImage, whose spec.cloud-config is handed to yip on the node. Full object:
apiVersion: elemental.cattle.io/v1beta1
kind: SeedImage
metadata:
name: perms-repro
namespace: fleet-default
spec:
type: iso
baseImage: registry.suse.com/suse/sl-micro/6.2/baremetal-iso-image:2.3.0-7.111
registrationRef:
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
name: <your-existing-machineregistration>
namespace: fleet-default
cloud-config:
name: perms-repro
stages:
initramfs:
- name: write a file via files with string permissions
files:
- path: /tmp/via-files.txt
permissions: "0600"
content: |
hello
Boot a node from the resulting ISO. /tmp/via-files.txt does not exist, and nothing is logged about it. Change permissions: "0600" to permissions: 384 and it is created with mode 0o600.
For contrast, the same file written through write_files: (legacy cloud-config, replacing the cloud-config: block above) is created correctly at 0o600:
cloud-config:
write_files:
- path: /tmp/via-writefiles.txt
permissions: "0600"
content: |
hello
The same behavior reproduces without Rancher: place a yip config in a cloud-init dir and run elemental run-stage <stage>.
Expected behavior
files: and write_files: should handle permissions the same way (accept an octal string in both), or files: should error clearly when it receives a string or an out-of-range value instead of skipping the file silently. The docs should also state that files[].permissions is a numeric mode and give an unambiguous form (384 for 0o600, 420 for 0o644, 288 for 0o440).
Logs
files: with permissions: "0600" writes no file and surfaces no error.
- A stored
600 gives ls -l mode 0o1130; NetworkManager then ignores the keyfile and nmcli con up <name> returns Error: unknown connection.
- Delivered via Rancher OS Manager 1.9; the
cloud-config CRD field is schemaless (x-kubernetes-preserve-unknown-fields: true), so yip receives the value unchanged.
Additional context
Confirmed by testing: the CRD field is a schemaless passthrough, a stored 600 produces mode 0o1130, "0600" under files: produces no file, and "0600" under write_files: works. The exact yip unmarshaling path is inferred from these results rather than read from source.
Related:
elemental-toolkit version:
v2.3.2, with base image
registry.suse.com/suse/sl-micro/6.2/baremetal-iso-image:2.3.0-7.111.CPU architecture, OS, and Version:
x86_64, SUSE Linux Micro 6.2.
Describe the bug
The
permissionsfield behaves differently depending on which of the two file-writing mechanisms you use, and the difference isn't documented.write_files:(the cloud-init compatibility path) treatspermissionsas an octal string, sopermissions: "0600"produces mode0o600.Extended
files:(a yip stage step) treatspermissionsas a raw integer and applies it directly as the file mode (os.FileMode(n)). There,permissions: "0600"as a string doesn't unmarshal into the integer field and the file is silently not written. A barepermissions: 0600depends on the parser: YAML reads it as octal384(correct), while a JSON/decimal path gives600, which is mode0o1130. Only the decimal384is unambiguous.So the same
permissions: "0600"works underwrite_files:but is silently dropped underfiles:. The docs showpermissions: 0644forfiles:without noting that it only works because YAML happens to parse the leading zero as octal.To Reproduce
Consumed here through a Rancher SeedImage, whose
spec.cloud-configis handed to yip on the node. Full object:Boot a node from the resulting ISO.
/tmp/via-files.txtdoes not exist, and nothing is logged about it. Changepermissions: "0600"topermissions: 384and it is created with mode0o600.For contrast, the same file written through
write_files:(legacy cloud-config, replacing thecloud-config:block above) is created correctly at0o600:The same behavior reproduces without Rancher: place a yip config in a cloud-init dir and run
elemental run-stage <stage>.Expected behavior
files:andwrite_files:should handlepermissionsthe same way (accept an octal string in both), orfiles:should error clearly when it receives a string or an out-of-range value instead of skipping the file silently. The docs should also state thatfiles[].permissionsis a numeric mode and give an unambiguous form (384for0o600,420for0o644,288for0o440).Logs
files:withpermissions: "0600"writes no file and surfaces no error.600givesls -lmode0o1130; NetworkManager then ignores the keyfile andnmcli con up <name>returnsError: unknown connection.cloud-configCRD field is schemaless (x-kubernetes-preserve-unknown-fields: true), so yip receives the value unchanged.Additional context
Confirmed by testing: the CRD field is a schemaless passthrough, a stored
600produces mode0o1130,"0600"underfiles:produces no file, and"0600"underwrite_files:works. The exact yip unmarshaling path is inferred from these results rather than read from source.Related:
0600is stored as decimal600