Skip to content

TFTP feature#533

Open
stejskalleos wants to merge 1 commit into
theforeman:masterfrom
stejskalleos:ls/feat_tftp
Open

TFTP feature#533
stejskalleos wants to merge 1 commit into
theforeman:masterfrom
stejskalleos:ls/feat_tftp

Conversation

@stejskalleos

@stejskalleos stejskalleos commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Why are you introducing these changes? (Problem description, related links)

Support the TFTP Smart Proxy feature.

What are the changes introduced in this pull request?

  • foremanctl deploy ---add-feature tftp

How to test this pull request

./foremanctl deploy --help

  --tftp-root FOREMAN_PROXY_TFTP_ROOT
                        Directory to serve TFTP files from. (persisted)
  --tftp-servername FOREMAN_PROXY_TFTP_SERVERNAME
                        Server name to use for TFTP. (persisted)
./foremanctl deploy --add-feature foreman-proxy --add-feature tftp \
  --tftp-root /var/lib/foreman-custom-tftp \
  --tftp-servername something-else.example.com \

Go to https://quadlet.example.com/smart_proxies/2-quadlet-example-com, TFTP should be enabled.

vagrant ssh quadlet
sudo podman exec -it foreman-proxy /bin/bash
cat /etc/foreman-proxy/settings.d/tftp.yml
---
:enabled: false
:tftproot: /var/lib/foreman-custom-tftp
:tftp_servername: something-else.example.com
:tftp_connect_timeout: 10
:verify_server_cert: true
./foremanctl deploy --remove-feature tftp
./foremanctl features
=>

tftp                      available    Enable TFTP feature on Foreman Proxy

cat /etc/foreman-proxy/settings.d/tftp.yml

---
:enabled: false
:tftproot: /var/lib/foreman-custom-tftp
:tftp_servername: something-else.example.com
:tftp_connect_timeout: 10
:verify_server_cert: true

Go to https://quadlet.example.com/smart_proxies/2-quadlet-example-com, TFTP should be disabled.

Checklist

  • Tests added/updated (if applicable)
  • Documentation updated (if applicable)

Comment thread docs/user/parameters.md Outdated
Comment thread src/playbooks/deploy/metadata.obsah.yaml Outdated
@stejskalleos stejskalleos requested a review from evgeni June 2, 2026 10:32

# TFTP settings
foreman_proxy_tftp_root: /var/lib/tftpboot
foreman_proxy_tftp_servername: "{{ ansible_facts['fqdn'] }}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a default? IIRC the code has a fallback on the Smart Proxy's hostname already so this doesn't add anything. In a remote setup it will also be guaranteed wrong.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, this is completely random (I was just browsing this repository) but:

TFTP clients usually do not have DNS stack available, therefore, this must be IP address if anything. I see fqdn so I assume this would be a hostname. I remember there was some FQDN>IP hack somewhere but using IP was always the best and the safest thing to do.

This has always been terrible name, servername. What it does is sets up next-server which is probably the root cause of all of this terminology. But what users typically need to set is an IP address.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that is a better value. Ideally this value defaults to empty and we force users to provide the value when they enable the TFTP feature. Then input validation forces a valid IPv4 address.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could at least rename the parameter in foremactl.
Change it to tftp-ip and update the description.
WDYT?

Comment thread src/playbooks/deploy/metadata.obsah.yaml Outdated

@evgeni evgeni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get a test that sets up a tftp-server (on the quadlet machine), instructs the proxy to create a file in the tftp root and uses tftp to fetch that file?

Comment thread src/roles/foreman_proxy/defaults/main.yaml Outdated
type: Boolean
foreman_proxy_tftp_root:
parameter: --tftp-root
help: Directory to serve TFTP files from.

@evgeni evgeni Jun 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ewouds comment in jira made me realize that this description is wrong.
We also use /var/lib/tftpboot for the httpboot module (https://github.com/theforeman/smart-proxy/blob/3e249dd019dd36f41b546fe44c045ab055c1da6c/modules/httpboot/httpboot_plugin.rb#L13) and do not allow users to configure that in Puppet.

It is unclear to me how the HTTPBoot thing obtains the files (seems there is no code for that), so maybe it relies on the TFTP module to place the files and just exposes them over HTTP instead of TFTP?

(This is not blocking the feature here, just food for further thought going forward)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also faced similar doubts while just scaffolding httpboot feature, and i realised its use /var/lib/tftp which is not created by httpboot, which makes me think why we don't add tftp as dependency for httpboot. for full context you can refer #518 (comment)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which makes me think why we don't add tftp as dependency for httpboot.

You may find theforeman/smart-proxy@db33bc6 interesting.

Perhaps we should call it the netboot directory? I already had https://github.com/theforeman/puppet-foreman_proxy/blob/master/manifests/tftp/netboot.pp in the old installer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"interesting" as in "wait, what!?"? ;-)

How is the directory populated, when the TFTP feature is off, but HTTPBoot is on?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic? In theforeman/puppet-foreman_proxy@e4b7763 I wrote:

To get the netboot files, the TFTP feature must still be enabled.

It was a long discussion that was rather tedious. I'm not sure the whole use case of netbooting with HTTPBoot without TFTP was ever really well supported.

@arvind4501 arvind4501 Jun 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the directory populated, when the TFTP feature is off, but HTTPBoot is on?

AFAIK, no population happens, just configuration, As of today, by default httpboot enablement will add :root_dir: /var/lib/tftpboot in config, and still be indirectly dependent on tftp to create and populate that directory

@stejskalleos

Copy link
Copy Markdown
Contributor Author

Can we get a test that sets up a tftp-server (on the quadlet machine), instructs the proxy to create a file in the tftp root and uses tftp to fetch that file?

I'm still working on this test; I will add it in the upcoming commit.

Comment thread .github/workflows/test.yml Outdated
Comment thread src/roles/foreman_proxy/tasks/feature/tftp.yaml
Comment thread src/roles/foreman_proxy/tasks/feature/tftp.yaml Outdated
Comment thread src/roles/foreman_proxy/tasks/feature/tftp.yaml Outdated
@stejskalleos

Copy link
Copy Markdown
Contributor Author

@ehelms applied comments from your review.
Can't add the tests for the feature because of a broken local environment.
I'm trying to figure it out in the meantime.

type: AbsolutePath
foreman_proxy_tftp_servername:
parameter: --tftp-servername
help: Server name to use for TFTP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the validation message below, I'd include this line here in some form:

  This should be the IP address of the TFTP server (TFTP clients typically do not have DNS available).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which I will also point out is slightly ironic we call it servername and then state it should be the IP address.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we're talking about https://www.rfc-editor.org/info/rfc2132/#section-9.4. DHCP option 66 is called TFTP server name. Sadly it doesn't describe at all what the content of it should be at the protocol level.

If we look at what we do for ISC DHCP (https://github.com/theforeman/smart-proxy/blob/3e249dd019dd36f41b546fe44c045ab055c1da6c/modules/dhcp_common/isc/omapi_provider.rb#L205-L217) then that's basically trying to send an IP, but ISC DHCP itself can also be configured with a hostname where the service does a lookup.

Kea's all-options.json actually has an example that is a hostname: https://github.com/isc-projects/kea/blob/f79874a1f22c29b96ee543f5bc905960818991f7/doc/examples/kea4/all-options.json#L787-L798.

So I'm not sure we need to be so strict in only accepting an IP. Apologies for not digging into that deep enough before.

Comment thread tests/foreman_proxy_test.py
@stejskalleos stejskalleos force-pushed the ls/feat_tftp branch 2 times, most recently from f92121c to bee64a8 Compare June 10, 2026 07:14
Comment thread development/playbooks/tftp/tftp.yaml Outdated
Comment thread src/roles/foreman_proxy/tasks/feature/tftp.yaml Outdated
Comment thread tests/foreman_proxy_test.py
Comment thread src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2 Outdated
Comment thread tests/foreman_proxy_test.py Outdated
@evgeni

evgeni commented Jun 10, 2026

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This pull request adds TFTP feature support to foremanctl, enabling Foreman Proxy to serve PXE boot files via TFTP. The changes declare a new tftp feature with two configurable parameters (--tftp-root and --tftp-servername), implement Foreman Proxy task logic to set up directory mounts and validate configuration, provide a development Ansible playbook for test environment setup, integrate TFTP initialization into the GitHub Actions test workflow, add integration tests for PXE config read/write operations, and document the new parameters in the user guide.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'TFTP feature' is vague and generic, using non-descriptive terminology that doesn't clearly convey the specific change or improvement being introduced. Use a more specific title that describes the primary change, such as 'Add TFTP Smart Proxy feature support' or 'Implement TFTP feature for Foreman Proxy deployment'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the motivation, changes, and testing instructions for implementing TFTP Smart Proxy feature support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2 (1)

3-3: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Use container path instead of host path for :tftproot.

The Foreman Proxy runs inside a container where {{ foreman_proxy_tftp_root }} (the host path) is mounted to /var/lib/tftpboot (see src/roles/foreman_proxy/tasks/feature/tftp.yaml line 26). The configuration must reference the container path, not the host path. When a user specifies a custom --tftp-root, the current template will render a path that doesn't exist inside the container, breaking TFTP functionality.

🐛 Proposed fix
 ---
 :enabled: {{ feature_enabled }}
-:tftproot: {{ foreman_proxy_tftp_root }}
+:tftproot: /var/lib/tftpboot
 :tftp_servername: {{ foreman_proxy_tftp_servername }}
 :tftp_connect_timeout: 10
 :verify_server_cert: true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2` at line 3, The
template settings.d/tftp.yml.j2 is using the host path variable
foreman_proxy_tftp_root for :tftproot:, which is wrong inside the container;
change the template to reference the container TFTP root (/var/lib/tftpboot)
instead of {{ foreman_proxy_tftp_root }} so the rendered config points to the
path mounted inside the Foreman Proxy container (update settings.d/tftp.yml.j2
to use /var/lib/tftpboot for :tftproot:).
🧹 Nitpick comments (2)
docs/user/parameters.md (1)

117-117: ⚡ Quick win

Consider using the more descriptive help text from metadata.

The description "Directory for TFTP" is brief. For consistency with the CLI help text defined in src/playbooks/deploy/metadata.obsah.yaml, consider using "Directory to serve TFTP files from."

📝 Suggested improvement
-| `--tftp-root` | Directory for TFTP | `--foreman-proxy-tftp-root` |
+| `--tftp-root` | Directory to serve TFTP files from | `--foreman-proxy-tftp-root` |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/user/parameters.md` at line 117, The docs line for the CLI flag
`--tftp-root` uses a terse description; update the help text to match the more
descriptive metadata wording by replacing "Directory for TFTP" with "Directory
to serve TFTP files from" to keep consistency with the CLI help defined in
src/playbooks/deploy/metadata.obsah.yaml and ensure the parameter `--tftp-root`
documentation mirrors that metadata description.
src/playbooks/deploy/metadata.obsah.yaml (1)

59-65: ⚡ Quick win

Consider clarifying that --tftp-servername should be an IP address.

The help text at line 65 says "Server name to use for TFTP" but doesn't mention that TFTP clients typically lack DNS, so this should be an IP address. The validation error message in src/roles/foreman_proxy/tasks/feature/tftp.yaml line 9 does explain this, but users won't see that guidance until validation fails.

📝 Suggested help text improvement
   foreman_proxy_tftp_servername:
     parameter: --tftp-servername
-    help: Server name to use for TFTP.
+    help: Server name (typically an IP address) to use for TFTP. TFTP clients usually do not have DNS available.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/playbooks/deploy/metadata.obsah.yaml` around lines 59 - 65, Update the
help text for the foreman_proxy_tftp_servername parameter (parameter:
--tftp-servername) to explicitly state that it must be an IP address (TFTP
clients typically lack DNS resolution), so users see this guidance before
validation; modify the "help" value to mention "IP address (no DNS)" or similar
and optionally include an example format to match the validation in
src/roles/foreman_proxy/tasks/feature/tftp.yaml.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@development/playbooks/tftp/metadata.obsah.yaml`:
- Line 1: The playbook currently located under development/playbooks/tftp/
(metadata.obsah.yaml) must be relocated into one of the approved subdirectories
under development/playbooks/ (vms/, test/, smoker/, deploy-dev/, security/,
sos/, or lock/); choose the most appropriate bucket for this playbook's purpose,
move metadata.obsah.yaml into that directory, and update any references or
automation that point at development/playbooks/tftp/ to the new path so
discovery/automation continues to work.

---

Duplicate comments:
In `@src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2`:
- Line 3: The template settings.d/tftp.yml.j2 is using the host path variable
foreman_proxy_tftp_root for :tftproot:, which is wrong inside the container;
change the template to reference the container TFTP root (/var/lib/tftpboot)
instead of {{ foreman_proxy_tftp_root }} so the rendered config points to the
path mounted inside the Foreman Proxy container (update settings.d/tftp.yml.j2
to use /var/lib/tftpboot for :tftproot:).

---

Nitpick comments:
In `@docs/user/parameters.md`:
- Line 117: The docs line for the CLI flag `--tftp-root` uses a terse
description; update the help text to match the more descriptive metadata wording
by replacing "Directory for TFTP" with "Directory to serve TFTP files from" to
keep consistency with the CLI help defined in
src/playbooks/deploy/metadata.obsah.yaml and ensure the parameter `--tftp-root`
documentation mirrors that metadata description.

In `@src/playbooks/deploy/metadata.obsah.yaml`:
- Around line 59-65: Update the help text for the foreman_proxy_tftp_servername
parameter (parameter: --tftp-servername) to explicitly state that it must be an
IP address (TFTP clients typically lack DNS resolution), so users see this
guidance before validation; modify the "help" value to mention "IP address (no
DNS)" or similar and optionally include an example format to match the
validation in src/roles/foreman_proxy/tasks/feature/tftp.yaml.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ae1de4bc-3999-41dd-9bdb-dd5c320feaf7

📥 Commits

Reviewing files that changed from the base of the PR and between 377474a and bee64a8.

📒 Files selected for processing (10)
  • .github/workflows/test.yml
  • development/playbooks/tftp/metadata.obsah.yaml
  • development/playbooks/tftp/tftp.yaml
  • docs/user/parameters.md
  • src/features.yaml
  • src/playbooks/deploy/metadata.obsah.yaml
  • src/roles/foreman_proxy/defaults/main.yaml
  • src/roles/foreman_proxy/tasks/feature/tftp.yaml
  • src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2
  • tests/foreman_proxy_test.py

Comment thread development/playbooks/tftp/metadata.obsah.yaml
@stejskalleos stejskalleos force-pushed the ls/feat_tftp branch 2 times, most recently from 7917de5 to 3463691 Compare June 11, 2026 06:05
Comment thread src/roles/foreman_proxy/handlers/main.yml Outdated
Comment thread src/roles/foreman_proxy/tasks/feature/tftp.yaml Outdated
Comment thread tests/foreman_proxy_test.py Outdated
Comment thread tests/foreman_proxy_test.py Outdated
Comment thread tests/conftest.py
Comment thread src/roles/foreman_proxy/templates/settings.d/tftp.yml.j2 Outdated
Comment thread tests/conftest.py Outdated
Comment thread tests/foreman_proxy_test.py
Comment thread tests/foreman_proxy_test.py Outdated
Comment thread docs/user/parameters.md Outdated
@stejskalleos stejskalleos force-pushed the ls/feat_tftp branch 3 times, most recently from ed3fa54 to 7119759 Compare June 12, 2026 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants