From abb49b2c7fc0f325388bde1ca0c1515acf311761 Mon Sep 17 00:00:00 2001 From: Jason Colapietro Date: Tue, 4 Aug 2026 00:31:37 -0400 Subject: [PATCH 1/4] docs: add file append and overwrite examples --- docs/examples.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 68e9a2f6..e30d40fc 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -149,6 +149,38 @@ storage: mode: 0644 ``` +Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. This example appends a rule to a drop-in under `/etc/sudoers.d/` instead of modifying `/etc/sudoers` directly. + + +```yaml +variant: fcos +version: 1.7.0 +storage: + files: + - path: /etc/sudoers.d/core + mode: 0440 + overwrite: false + append: + - inline: | + core ALL=(ALL) NOPASSWD: /usr/bin/podman +``` + +Use `overwrite: true` with `contents` when any existing filesystem node at the path should be removed and replaced. This example replaces anything at `/etc/example.conf` with a regular file containing the specified settings. + + +```yaml +variant: fcos +version: 1.7.0 +storage: + files: + - path: /etc/example.conf + overwrite: true + contents: + inline: | + enabled = true + mode: 0644 +``` + ### Directory trees Consider a directory tree at `~/conf/tree` on the system running Butane: From 69b8b4fe2634c5eee7e0d0810b1d04681aa61798 Mon Sep 17 00:00:00 2001 From: Jason Colapietro Date: Thu, 6 Aug 2026 13:36:00 -0400 Subject: [PATCH 2/4] docs: clarify append example target --- docs/examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples.md b/docs/examples.md index e30d40fc..ab9ad35c 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -149,7 +149,7 @@ storage: mode: 0644 ``` -Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. This example appends a rule to a drop-in under `/etc/sudoers.d/` instead of modifying `/etc/sudoers` directly. +Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. For sudoers rules, prefer a drop-in under `/etc/sudoers.d/` over modifying `/etc/sudoers` directly; this example appends to `/etc/sudoers.d/core`. ```yaml From 4080fc60c655b9355b1444dc64914448c3ba4d1e Mon Sep 17 00:00:00 2001 From: Jason Colapietro Date: Fri, 7 Aug 2026 14:20:57 -0400 Subject: [PATCH 3/4] docs: append to /etc/sudoers as requested in the issue --- docs/examples.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/examples.md b/docs/examples.md index ab9ad35c..e3572144 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -149,7 +149,22 @@ storage: mode: 0644 ``` -Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. For sudoers rules, prefer a drop-in under `/etc/sudoers.d/` over modifying `/etc/sudoers` directly; this example appends to `/etc/sudoers.d/core`. +Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. This example adds a sudoers rule to the end of the shipped `/etc/sudoers`. + + +```yaml +variant: fcos +version: 1.7.0 +storage: + files: + - path: /etc/sudoers + overwrite: false + append: + - inline: | + core ALL=(ALL) NOPASSWD: /usr/bin/podman +``` + +For sudoers rules specifically, a drop-in under `/etc/sudoers.d/` is usually preferable to appending to `/etc/sudoers`, since it survives updates to the shipped file. The same `append` semantics apply, and a new drop-in needs an explicit `mode`: ```yaml From 745c98792300404a5f042480109d11d9da9d23a8 Mon Sep 17 00:00:00 2001 From: Jason Colapietro Date: Wed, 12 Aug 2026 18:15:33 -0400 Subject: [PATCH 4/4] docs: bound passwordless sudo example --- docs/examples.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples.md b/docs/examples.md index e3572144..c92e2bc9 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -149,7 +149,7 @@ storage: mode: 0644 ``` -Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. This example adds a sudoers rule to the end of the shipped `/etc/sudoers`. +Use ordinary `contents` when Butane should write the complete contents of a new or existing regular file. Use `append` with the safe default `overwrite: false` when the existing contents should be preserved and one or more fragments added to the end. This example adds a sudoers rule to the end of the shipped `/etc/sudoers`. The rule deliberately allows only one command with exact arguments; avoid granting unrestricted passwordless access to shells, package managers, or container runtimes, since that is equivalent to root access. ```yaml @@ -161,7 +161,7 @@ storage: overwrite: false append: - inline: | - core ALL=(ALL) NOPASSWD: /usr/bin/podman + core ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart example.service ``` For sudoers rules specifically, a drop-in under `/etc/sudoers.d/` is usually preferable to appending to `/etc/sudoers`, since it survives updates to the shipped file. The same `append` semantics apply, and a new drop-in needs an explicit `mode`: @@ -177,7 +177,7 @@ storage: overwrite: false append: - inline: | - core ALL=(ALL) NOPASSWD: /usr/bin/podman + core ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart example.service ``` Use `overwrite: true` with `contents` when any existing filesystem node at the path should be removed and replaced. This example replaces anything at `/etc/example.conf` with a regular file containing the specified settings.