<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://theforeman.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://theforeman.org/" rel="alternate" type="text/html" /><updated>2026-03-11T12:15:51+00:00</updated><id>https://theforeman.org/feed.xml</id><subtitle>Foreman is an open source project that gives system administrators the power to easily automate repetitive tasks, quickly deploy applications, and proactively manage servers, on-premises or in the cloud.</subtitle><entry><title type="html">Packit-based nightlies or how to properly test plugins in production</title><link href="https://theforeman.org/2025/11/packit-based-nightlies-or-how-to-properly-test-plugins-in-production.html" rel="alternate" type="text/html" title="Packit-based nightlies or how to properly test plugins in production" /><published>2025-11-19T06:54:25+00:00</published><updated>2025-11-19T06:54:25+00:00</updated><id>https://theforeman.org/2025/11/packit-based-nightlies-or-how-to-properly-test-plugins-in-production</id><content type="html" xml:base="https://theforeman.org/2025/11/packit-based-nightlies-or-how-to-properly-test-plugins-in-production.html"><![CDATA[<p>The Foreman Project offers “nightly” repositories (<a href="https://yum.theforeman.org/">rpm</a>, <a href="https://deb.theforeman.org/">deb</a>) for everyone who wants to try out the latest changes in a production-like<sup id="fnref:production-like" role="doc-noteref"><a href="#fn:production-like" class="footnote" rel="footnote">1</a></sup> setup.
This is great to verify changes before they hit the next Foreman release.</p>

<p>However, these repositories have one problem: only a few packages are truly built every day (or night), the majority still requires people to prepare a release of the code.
This is done quite intentionally, as it keeps the repositories in a state where preparing a full Foreman release is rather quick, as only few packages need immediate human attention.
The downside is that you don’t get the absolute latest changes to try out.</p>

<p>For a while now, we had <a href="https://packit.dev">Packit</a> available for GitHub Pull Requests, which meant you could get an <a href="https://community.theforeman.org/t/packit-for-foreman-get-production-rpms-from-prs/32412">RPM with the changes from a PR</a> and install that on a regular nightly setup.
Those builds are only kept for 60 days and easily get out-of-date once the PR is merged, which means they are great to test that explicit change, but not suitable for full integration testing of all components.</p>

<p>Enter the <a href="https://copr.fedorainfracloud.org/coprs/g/theforeman/develop/"><code class="language-plaintext highlighter-rouge">@theforeman/develop</code> COPR</a>!
This is a new COPR repository we offer, <a href="https://community.theforeman.org/t/rfc-packit-based-nightlies-for-everyone/44268">built by Packit</a>, that contains builds of every single commit made to the main branches of our git repositories.</p>

<p>There is no testing or verification of the contents in this COPR.
If the RPM could be built, it will be published, even if the code is broken or dependencies can’t be satisfied.</p>

<p>If you’re still eager to try this out after all these warnings:</p>
<ul>
  <li>Prepare an Enterprise Linux 9 system, <a href="https://docs.theforeman.org/nightly/Installing_Server/index-katello.html#configuring-repositories_foreman">like you would for a normal nightly deployment</a></li>
  <li>Enable the COPR repository: <code class="language-plaintext highlighter-rouge">dnf copr enable @theforeman/develop rhel-9-x86_64</code></li>
  <li>Perform the rest of the deployment as usual</li>
</ul>

<p>This will use the “nightly” repository on <code class="language-plaintext highlighter-rouge">https://yum.theforeman.org</code> for Rails, Puma, etc. and the <code class="language-plaintext highlighter-rouge">@theforeman/develop</code> COPR for Foreman and plugins.</p>

<p>You can also enable the COPR on an existing system and either use <code class="language-plaintext highlighter-rouge">dnf upgrade</code> to update all available packages, or selectively install certain packages you want to try out, <a href="https://docs.theforeman.org/nightly/Upgrading_Project/index-katello.html#upgrading-your-foreman-server">like you would upgrade a normal nightly deployment</a>.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:production-like" role="doc-endnote">
      <p>Nobody would really run nightlies in prod, right?! <a href="#fnref:production-like" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Evgeni Golov</name></author><category term="foreman" /><category term="packit" /><summary type="html"><![CDATA[The Foreman Project offers “nightly” repositories (rpm, deb) for everyone who wants to try out the latest changes in a production-like1 setup. This is great to verify changes before they hit the next Foreman release. However, these repositories have one problem: only a few packages are truly built every day (or night), the majority still requires people to prepare a release of the code. This is done quite intentionally, as it keeps the repositories in a state where preparing a full Foreman release is rather quick, as only few packages need immediate human attention. The downside is that you don’t get the absolute latest changes to try out. For a while now, we had Packit available for GitHub Pull Requests, which meant you could get an RPM with the changes from a PR and install that on a regular nightly setup. Those builds are only kept for 60 days and easily get out-of-date once the PR is merged, which means they are great to test that explicit change, but not suitable for full integration testing of all components. Enter the @theforeman/develop COPR! This is a new COPR repository we offer, built by Packit, that contains builds of every single commit made to the main branches of our git repositories. There is no testing or verification of the contents in this COPR. If the RPM could be built, it will be published, even if the code is broken or dependencies can’t be satisfied. If you’re still eager to try this out after all these warnings: Prepare an Enterprise Linux 9 system, like you would for a normal nightly deployment Enable the COPR repository: dnf copr enable @theforeman/develop rhel-9-x86_64 Perform the rest of the deployment as usual This will use the “nightly” repository on https://yum.theforeman.org for Rails, Puma, etc. and the @theforeman/develop COPR for Foreman and plugins. You can also enable the COPR on an existing system and either use dnf upgrade to update all available packages, or selectively install certain packages you want to try out, like you would upgrade a normal nightly deployment. Nobody would really run nightlies in prod, right?! &#8617;]]></summary></entry><entry><title type="html">foremanctl 1.0 - deploying Foreman in Containers reaches first milestone</title><link href="https://theforeman.org/2025/10/foremanctl-10-deploying-foreman-in-containers-reaches-first-milestone.html" rel="alternate" type="text/html" title="foremanctl 1.0 - deploying Foreman in Containers reaches first milestone" /><published>2025-10-17T06:20:50+00:00</published><updated>2025-10-17T06:20:50+00:00</updated><id>https://theforeman.org/2025/10/foremanctl-10---deploying-foreman-in-containers-reaches-first-milestone</id><content type="html" xml:base="https://theforeman.org/2025/10/foremanctl-10-deploying-foreman-in-containers-reaches-first-milestone.html"><![CDATA[<p>Over the past few months, we’ve been working on a new way to deploy and manage Foreman and its components (like Katello, Candlepin, and Pulp) using <strong>containers</strong>.
Today, we’re happy to share that <strong>foremanctl 1.0</strong> has been tagged, marking our first milestone toward a fully containerized Foreman experience.</p>

<!--more-->

<h3 id="what-you-can-do-with-10">What You Can Do with 1.0</h3>

<p>With this first release, you can already:</p>

<ul>
  <li>Set up a basic Foreman + Katello environment using containers.</li>
  <li>Use an external database configuration.</li>
  <li>Manage services with systemd and Quadlet, making it easier to start, stop, and maintain the setup.</li>
</ul>

<p>Under the hood, <code class="language-plaintext highlighter-rouge">foremanctl</code> generates <strong>Podman Quadlet</strong> units that integrate directly with <strong>systemd</strong>, providing a consistent and declarative way to run Foreman services as containers — without relying on traditional installer RPMs.</p>

<p>If you’d like to try it out, follow the updated <a href="https://docs.theforeman.org/3.16/Quickstart/index-katello.html">Quickstart Guide for 3.16</a>, which now includes step-by-step instructions for installing and running <code class="language-plaintext highlighter-rouge">foremanctl</code>. For detailed changes and improvements, see the <a href="https://github.com/theforeman/foremanctl/releases/tag/1.0.0">1.0.0 release notes</a>.</p>

<hr />

<h3 id="whats-still-in-progress">What’s Still in Progress</h3>

<p>This release is an important first step, but it’s not yet a full replacement for the traditional installer setup. We’re continuing to work on:</p>

<ul>
  <li>Containerizing Smart Proxy</li>
  <li>Adding support for managing plugins (currently static list)</li>
  <li>Improving SELinux and networking integration</li>
  <li>Extending system requirement checks and configuration flexibility</li>
</ul>

<blockquote>
  <p><strong>Note:</strong> Smart Proxy services (like REX, Ansible, and DNS/DHCP) are not yet available in the release.</p>
</blockquote>

<p>You can follow progress and upcoming work items in the <a href="https://github.com/theforeman/foremanctl/milestone/2">foremanctl milestone 2.0 roadmap</a>.</p>

<p>Upcoming releases are expected to build on this foundation: <strong>3.16</strong> serving as an <em>alpha milestone</em>, <strong>3.17</strong> as <em>beta</em>, and <strong>3.18</strong> aimed to be a <em>GA-ready containerized deployment flow</em>.
(Please note that these plans reflect our current goals and may evolve as development continues.)</p>

<hr />

<h3 id="try-it-out-and-share-feedback">Try It Out and Share Feedback</h3>

<p>We’d love for you to experiment with <a href="https://github.com/theforeman/foremanctl">foremanctl</a>, try out the containerized setup, and tell us what works (and what doesn’t). Your feedback helps us smooth the rough edges and shape the next iterations.</p>

<p>Please share your experiences, questions, and feedback in the dedicated <a href="https://community.theforeman.org/t/foremanctl-1-0-feedback-and-discussion/44669">foremanctl 1.0 feedback thread</a> on the <a href="https://community.theforeman.org/">Foreman Community Forum</a>.</p>

<p>You can also open issues directly in the <a href="https://github.com/theforeman/foremanctl/issues">foremanctl repository</a> if you encounter specific bugs or setup problems.</p>

<p><strong><code class="language-plaintext highlighter-rouge">foremanctl 1.0</code></strong> is our first tangible step toward running Foreman in a modern, containerized way.
By building on systemd and Podman Quadlet, we’re making deployments more flexible, maintainable, and easier to evolve — while keeping the same Foreman you know and rely on.</p>

<p>Big thanks to everyone testing, contributing, and providing feedback. This is just the start — and we’re excited to see where it goes from here! \o/</p>]]></content><author><name>Archana Kumari</name></author><category term="foreman" /><category term="foremanctl" /><category term="containers" /><category term="quadlet" /><category term="podman" /><category term="systemd" /><category term="release" /><category term="katello" /><category term="pulp" /><summary type="html"><![CDATA[Over the past few months, we’ve been working on a new way to deploy and manage Foreman and its components (like Katello, Candlepin, and Pulp) using containers. Today, we’re happy to share that foremanctl 1.0 has been tagged, marking our first milestone toward a fully containerized Foreman experience.]]></summary></entry><entry><title type="html">betadots consulting services</title><link href="https://theforeman.org/2024/06/betadots-consulting-services.html" rel="alternate" type="text/html" title="betadots consulting services" /><published>2024-06-23T19:17:40+00:00</published><updated>2024-06-23T19:17:40+00:00</updated><id>https://theforeman.org/2024/06/betadots-consulting-services</id><content type="html" xml:base="https://theforeman.org/2024/06/betadots-consulting-services.html"><![CDATA[<p><a href="https://www.betadots.de/">betadots GmbH</a> joins the group of companies that
provide professional services for Foreman!</p>

<!--more-->

<p>Well, not really right now. We already do this since years! betadots is a
German consulting company with a focus on automation with open source
tooling. We have a long history in the Puppet ecosystem. We assist companies
with their planning and upgrading of their Puppet and Foreman infrastructure.
Besides that we also offer public and inhouse trainings for Puppet and
Foreman/Katello (with or without Puppet). The training material is also public
at: <a href="https://github.com/betadots/foreman-training?tab=readme-ov-file#foremankatello-training">github.com/betadots/foreman-training</a>.</p>

<p>betadots maintains an open source tool to visualize Hiera data,
<a href="https://github.com/betadots/hdm?tab=readme-ov-file#hdm---hiera-data-manager">HDM (Hiera Data Manager)</a>.
We also maintain a foreman plugin to display the information within the Foreman
UI.</p>

<p>Foreman has multiple Puppet modules to bootstrap Foreman and Katello, we provide
regular patches to the modules to improve the code quality, update dependencies
or implement new features.</p>]]></content><author><name>Tim Meusel</name></author><category term="foreman" /><summary type="html"><![CDATA[betadots GmbH joins the group of companies that provide professional services for Foreman!]]></summary></entry><entry><title type="html">Sunsetting rsync.theforeman.org</title><link href="https://theforeman.org/2024/05/sunsetting-rsynctheforemanorg.html" rel="alternate" type="text/html" title="Sunsetting rsync.theforeman.org" /><published>2024-05-10T07:59:32+00:00</published><updated>2024-05-10T07:59:32+00:00</updated><id>https://theforeman.org/2024/05/sunsetting-rsynctheforemanorg</id><content type="html" xml:base="https://theforeman.org/2024/05/sunsetting-rsynctheforemanorg.html"><![CDATA[<p>We’re plannig to shutdown <code class="language-plaintext highlighter-rouge">rsync.theforeman.org</code> on 2024-06-03, if you’re using it to mirror our repositories, please switch to HTTP(S) based mirroring.</p>

<!--more-->

<p>Today we run an <code class="language-plaintext highlighter-rouge">rsyncd</code> on our webserver to offer a set of shares:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">yum</code> - our RPM packages (same content as <code class="language-plaintext highlighter-rouge">yum.theforeman.org</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">deb</code> - our Debian packages (same content as <code class="language-plaintext highlighter-rouge">deb.theforeman.org</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">archivedeb</code> - our old Debian packages (same content as <code class="language-plaintext highlighter-rouge">archivedeb.theforeman.org</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">downloads</code> - misc downloads, especially release tarballs (same content as <code class="language-plaintext highlighter-rouge">downloads.theforeman.org</code>)</li>
  <li><code class="language-plaintext highlighter-rouge">debug-incoming</code> - write-only share for <code class="language-plaintext highlighter-rouge">foreman-debug</code> uploads</li>
</ul>

<p>Our CDN provider (<a href="https://fastly.com">Fastly</a>) doesn’t support rsync, so whenever someone tries to download things via rsync, it hits our webserver directly, instead of being served from a CDN (which is both quicker and cheaper).</p>

<p>Additionally, we’re currently <a href="https://github.com/theforeman/foreman-infra/issues/1724#issuecomment-1988313625">planing the move (and split) of our webserver</a>, which would make offering rsync more complicated.</p>

<p>With all that, we decided to discontinue the service altogether on 2024-06-03.</p>

<p>If you need to mirror our repositories, Katello and Pulp can do that for you via HTTP(S), and so can  <a href="https://packages.debian.org/search?keywords=debmirror"><code class="language-plaintext highlighter-rouge">debmirror</code></a> and <a href="https://dnf-plugins-core.readthedocs.io/en/latest/reposync.html"><code class="language-plaintext highlighter-rouge">dnf reposync</code></a>.</p>]]></content><author><name>Evgeni Golov</name></author><category term="foreman" /><summary type="html"><![CDATA[We’re plannig to shutdown rsync.theforeman.org on 2024-06-03, if you’re using it to mirror our repositories, please switch to HTTP(S) based mirroring.]]></summary></entry><entry><title type="html">Provisioning Ubuntu Autoinstall</title><link href="https://theforeman.org/2024/02/provisioning-ubuntu-autoinstall.html" rel="alternate" type="text/html" title="Provisioning Ubuntu Autoinstall" /><published>2024-02-27T09:41:32+00:00</published><updated>2024-02-27T09:41:32+00:00</updated><id>https://theforeman.org/2024/02/provisioning-ubuntu-autoinstall</id><content type="html" xml:base="https://theforeman.org/2024/02/provisioning-ubuntu-autoinstall.html"><![CDATA[<p>Foreman supports provisioning hosts running Debian and Ubuntu on VMware, Proxmox, cloud providers such as Microsoft Azure, and bare metal hosts.
With the Katello plug-in, provisioned and registered hosts receive versioned DEB content based on their lifecycle.
This blog article is a short summary of <em>what</em> happened behind the scenes to provisioning hosts running Ubuntu 20.04.3+, <em>why</em> you need new templates, and <em>how</em> to use the new deployment mechanism.</p>

<!--more-->

<h2 id="tldr">TL;DR</h2>

<p>Provisioning Ubuntu 20.04.3+ uses the new <a href="https://ubuntu.com/server/docs/install/autoinstall">Ubuntu Autoinstall</a> mechanism which is based on cloud-init to perform image-based deployments.
In your Foreman+Katello instance, you need the ISO image, boot files, and a user data template.
Associate the <code class="language-plaintext highlighter-rouge">Autoinstall</code> provisioning templates to your operating system entry.</p>

<p>For Ubuntu 20.04.z deployments, Foreman decides based on the minor OS version whether to use the <code class="language-plaintext highlighter-rouge">Preseed</code> or <code class="language-plaintext highlighter-rouge">Autoinstall</code> mechanism:</p>

<ul>
  <li>Minor OS version 0, 1, 2: Preseed</li>
  <li>Minor OS version 3 or above: Autoinstall</li>
</ul>

<p>Ensure that the mechanism matches the associated templates and that your managed host has at least 3 GiB of memory.
Ubuntu 22.04 “Jammy Jellyfish” deployment is Autoinstall-only and not affected by the minor OS version.</p>

<h2 id="previous-approach-using-debian-installer">Previous approach: using “debian-installer”</h2>

<p>Provisioning hosts with Debian and Ubuntu up to Ubuntu 20.04.2 supports <code class="language-plaintext highlighter-rouge">debian-installer</code> with <code class="language-plaintext highlighter-rouge">Preseed</code> templates.
With Ubuntu 20.04.3+ and Ubuntu 22.04, you have to use Autoinstall, a cloud-init-based mechanism, to perform network-based deployments.</p>

<h2 id="introducing-subiquity-aka-ubuntu-autoinstall">Introducing “Subiquity” aka. Ubuntu Autoinstall</h2>

<p>Ubuntu 20.04 comes with a new <code class="language-plaintext highlighter-rouge">Subiquity</code> installer, but .0, .1, and .2 still supported <code class="language-plaintext highlighter-rouge">debian-installer</code> and therefore <code class="language-plaintext highlighter-rouge">Preseed</code> templates.
With Ubuntu 20.04.2 and below, Ubuntu relied on the same deployment mechanism as Debian to install the operating system in an unattended way.
Foreman still contains different well tested and maintained <code class="language-plaintext highlighter-rouge">Preseed</code> templates to provision hosts running all Debian and Ubuntu 20.04.2 and older.</p>

<p>For the Foreman community, this meant additional development time to provide <code class="language-plaintext highlighter-rouge">Autoinstall</code> templates and the option to use the minor OS version for Ubuntu 20.04 to optionally select <code class="language-plaintext highlighter-rouge">debian-installer</code> on Ubuntu 20.04.0, 20.04.1, and 20.04.2.</p>

<h3 id="comparing-preseed-templates-and-autoinstall-templates">Comparing “Preseed” Templates and “Autoinstall” Templates</h3>

<p>Autoinstall templates are much shorter and simpler:</p>

<h4 id="preseed-default-template">Preseed Default template</h4>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># This preseed file was rendered from the Foreman provisioning template "Preseed default".</span>
<span class="c"># for debian12.example.com running Debian 12</span>
<span class="c"># Organization: Example</span>
<span class="c"># Location: Munich</span>

<span class="c"># Locale</span>
d-i debian-installer/locale string en_US
<span class="c"># country and keyboard settings are automatic. Keep them ...</span>
<span class="c"># ... for wheezy and newer:</span>
d-i keyboard-configuration/xkb-keymap seen <span class="nb">true</span>

<span class="c"># Network configuration</span>
d-i netcfg/choose_interface <span class="k">select </span>auto
d-i netcfg/get_hostname string debian12.example.com
d-i netcfg/get_domain string example.com
d-i netcfg/wireless_wep string

d-i hw-detect/load_firmware boolean <span class="nb">true</span>

<span class="c"># Mirror settings</span>
d-i mirror/country string manual
d-i mirror/http/hostname string ftp.debian.org:80
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i mirror/codename string bookworm
d-i mirror/suite string bookworm
d-i mirror/udeb/suite string bookworm

<span class="c"># Time settings</span>
d-i clock-setup/utc boolean <span class="nb">true
</span>d-i <span class="nb">time</span>/zone string UTC

<span class="c"># NTP</span>
d-i clock-setup/ntp boolean <span class="nb">true
</span>d-i clock-setup/ntp-server string 0.debian.pool.ntp.org

<span class="c"># Set alignment for automatic partitioning</span>
<span class="c"># Choices: cylinder, minimal, optimal</span>
<span class="c">#d-i partman/alignment select cylinder</span>

<span class="c"># Use the first detected hard disk</span>
d-i partman/early_command string <span class="se">\</span>
  <span class="nv">INSTALL_DISK</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>list-devices disk | <span class="nb">head</span> <span class="nt">-n1</span><span class="si">)</span><span class="s2">"</span><span class="p">;</span> <span class="se">\</span>
  debconf-set partman-auto/disk <span class="s2">"</span><span class="nv">$INSTALL_DISK</span><span class="s2">"</span><span class="p">;</span> <span class="se">\</span>
  debconf-set grub-installer/bootdev <span class="s2">"</span><span class="nv">$INSTALL_DISK</span><span class="s2">"</span>

<span class="c">### Partitioning</span>
<span class="c"># The presently available methods are: "regular", "lvm" and "crypto"</span>
d-i partman-auto/method string regular

<span class="c"># If one of the disks that are going to be automatically partitioned</span>
<span class="c"># contains an old LVM configuration, the user will normally receive a</span>
<span class="c"># warning. This can be preseeded away...</span>
d-i partman-lvm/device_remove_lvm boolean <span class="nb">true</span>
<span class="c"># The same applies to pre-existing software RAID array:</span>
d-i partman-md/device_remove_md boolean <span class="nb">true</span>
<span class="c"># And the same goes for the confirmation to write the lvm partitions.</span>
d-i partman-lvm/confirm boolean <span class="nb">true
</span>d-i partman-lvm/confirm_nooverwrite boolean <span class="nb">true</span>

<span class="c"># You can choose one of the three predefined partitioning recipes:</span>
<span class="c"># - atomic: all files in one partition</span>
<span class="c"># - home:   separate /home partition</span>
<span class="c"># - multi:  separate /home, /var, and /tmp partitions (/usr was removed in jessie)</span>
d-i partman-auto/choose_recipe <span class="k">select </span>atomic

<span class="c"># If you just want to change the default filesystem to something</span>
<span class="c"># else, you can do that without providing a full recipe.</span>

<span class="c"># This makes partman automatically partition without confirmation, provided</span>
<span class="c"># that you told it what to do using one of the methods above.</span>
d-i partman/confirm_write_new_label boolean <span class="nb">true
</span>d-i partman/choose_partition <span class="k">select </span>finish
d-i partman/confirm boolean <span class="nb">true
</span>d-i partman/confirm_nooverwrite boolean <span class="nb">true</span>

<span class="c"># User settings</span>
d-i passwd/root-password-crypted password _My_Password_
user-setup-udeb passwd/root-login boolean <span class="nb">true
</span>d-i passwd/make-user boolean <span class="nb">false
</span>user-setup-udeb passwd/make-user boolean <span class="nb">false</span>

<span class="c"># If we are using Katello for content management, then we do not want to use</span>
<span class="c"># upstream mirrors prior to Katello registration.</span>
d-i apt-setup/use_mirror boolean <span class="nb">false
</span>d-i apt-setup/service-select multiselect
d-i apt-setup/services-select multiselect

<span class="c"># Install minimal task set (see tasksel --task-packages minimal)</span>
tasksel tasksel/first multiselect minimal, ssh-server, openssh-server

<span class="c"># Install some base packages</span>
d-i pkgsel/include string lsb-release wget python3
d-i pkgsel/update-policy <span class="k">select </span>unattended-upgrades
d-i pkgsel/upgrade <span class="k">select </span>none

popularity-contest popularity-contest/participate boolean <span class="nb">false</span>

<span class="c"># Boot loader settings</span>
<span class="c">#grub-pc grub-pc/hidden_timeout boolean false</span>
<span class="c">#grub-pc grub-pc/timeout string 10</span>
d-i grub-installer/only_debian boolean <span class="nb">true
</span>d-i grub-installer/with_other_os boolean <span class="nb">true
</span>d-i finish-install/reboot_in_progress note

d-i preseed/late_command string wget <span class="nt">-Y</span> off http://foreman.example.com/unattended/finish <span class="nt">-O</span> /target/tmp/finish.sh <span class="o">&amp;&amp;</span> <span class="k">in</span><span class="nt">-target</span> <span class="nb">chmod</span> +x /tmp/finish.sh <span class="o">&amp;&amp;</span> <span class="k">in</span><span class="nt">-target</span> /tmp/finish.sh
</code></pre></div></div>

<h4 id="preseed-autoinstall-cloud-init-user-data-template">Preseed Autoinstall Cloud-init user data template</h4>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#cloud-config</span>
<span class="na">autoinstall</span><span class="pi">:</span>
  <span class="na">version</span><span class="pi">:</span> <span class="m">1</span>
  <span class="na">apt</span><span class="pi">:</span>
    <span class="na">geoip</span><span class="pi">:</span> <span class="no">false</span>
    <span class="na">preserve_sources_list</span><span class="pi">:</span> <span class="no">false</span>
    <span class="na">primary</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">arches</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">amd64</span><span class="pi">,</span> <span class="nv">i386</span><span class="pi">]</span>
        <span class="na">uri</span><span class="pi">:</span> <span class="s">http://foreman.example.com:80/pub/installation_media/ubuntu/22.04-x86_64/</span>
    <span class="na">disable_components</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">multiverse</span><span class="pi">]</span>
    <span class="na">disable_suites</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">backports</span><span class="pi">,</span><span class="nv">security</span><span class="pi">,</span><span class="nv">updates</span><span class="pi">]</span>
  <span class="na">user-data</span><span class="pi">:</span>
    <span class="na">disable_root</span><span class="pi">:</span> <span class="no">false</span>
    <span class="na">fqdn</span><span class="pi">:</span> <span class="s">ubuntu2204.example.com</span>
    <span class="na">users</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">root</span>
      <span class="na">gecos</span><span class="pi">:</span> <span class="s">root</span>
      <span class="na">lock-passwd</span><span class="pi">:</span> <span class="no">false</span>
      <span class="na">hashed_passwd</span><span class="pi">:</span> <span class="s">_My_Password_</span>
      <span class="na">ssh_authorized_keys</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">ssh-rsa</span><span class="nv"> </span><span class="s">_My_Foreman_Proxy_SSH_Key_</span><span class="nv"> </span><span class="s">foreman-proxy@foreman.example.com"</span><span class="pi">]</span>
  <span class="na">keyboard</span><span class="pi">:</span>
    <span class="na">layout</span><span class="pi">:</span> <span class="s">us</span>
    <span class="na">toggle</span><span class="pi">:</span> <span class="no">null</span>
    <span class="na">variant</span><span class="pi">:</span> <span class="s1">'</span><span class="s">'</span>
  <span class="na">locale</span><span class="pi">:</span> <span class="s">en_US.UTF-8</span>
  <span class="na">network</span><span class="pi">:</span>
    <span class="na">version</span><span class="pi">:</span> <span class="m">2</span>
    <span class="na">ethernets</span><span class="pi">:</span>
      <span class="na">ens160</span><span class="pi">:</span>
        <span class="na">dhcp4</span><span class="pi">:</span> <span class="no">true</span>
        <span class="na">dhcp6</span><span class="pi">:</span> <span class="no">false</span>
  <span class="na">ssh</span><span class="pi">:</span>
    <span class="na">allow-pw</span><span class="pi">:</span> <span class="no">true</span>
    <span class="na">install-server</span><span class="pi">:</span> <span class="no">true</span>
  <span class="na">updates</span><span class="pi">:</span> <span class="s">security</span>

  <span class="na">storage</span><span class="pi">:</span>
    <span class="na">layout</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">lvm</span>
  <span class="na">late-commands</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">wget -Y off http://foreman.example.com/unattended/finish -O /target/tmp/finish.sh</span>
  <span class="pi">-</span> <span class="s">curtin in-target -- chmod +x /tmp/finish.sh</span>
  <span class="pi">-</span> <span class="s">curtin in-target -- /tmp/finish.sh</span>
</code></pre></div></div>

<h2 id="behind-the-scenes">Behind the Scenes</h2>

<p>Behind the scenes, there are changes in Ubuntu, Foreman, and the provisioning workflow.</p>

<h3 id="new-installer">New Installer</h3>

<p>With Ubuntu 20.04.3+, the server installer changed from <code class="language-plaintext highlighter-rouge">debian-installer</code> to <code class="language-plaintext highlighter-rouge">Subiquity</code> installer.
This installer brings various changes:</p>

<ul>
  <li>UEFI/BIOS boot templates require different Kernel parameters</li>
  <li>Installation media file layout changed, for example the file structure in the ISO image</li>
  <li>Unattended installations require a different config file format</li>
</ul>

<p>This means that Foreman has to search for the boot files in different paths depending on the Ubuntu version and provisioning method to provide the boot files during the host deployment.
This is technically independent of the used installation mechanism, but the provisioning templates associated with the OS and the installation mechanism of the OS have to match.</p>

<p>Overall, provisioning hosts running Ubuntu 20.04.3+ requires different provisioning templates, a way to handle the ISO image and boot files on Foreman Server and Smart Proxy Servers, and a user data template for Autoinstall.</p>

<h3 id="changes-in-foreman">Changes in Foreman</h3>

<ul>
  <li>With <code class="language-plaintext highlighter-rouge">Autoinstall</code>, you need a new type of template called “user data template” similar to cloud deployments. (before: <code class="language-plaintext highlighter-rouge">Preseed</code> templates)</li>
  <li>Provide the ISO image and extracted ISO image. (before: installation with <code class="language-plaintext highlighter-rouge">debian-installer</code> was based on a repository)</li>
</ul>

<p>With these two changes, the location of the ISO image and the Autoinstall template must be passed to the Kernel.
Therefore, the new <code class="language-plaintext highlighter-rouge">PXELinux Autoinstall</code> and <code class="language-plaintext highlighter-rouge">PXEGrub2 Autoinstall</code> templates contain the URLs where to find the user data template and ISO image.</p>

<h3 id="boot-files-linux-kernel-and-initrd">Boot Files: Linux Kernel and <code class="language-plaintext highlighter-rouge">initrd</code></h3>

<ul>
  <li>For Ubuntu with major OS version <code class="language-plaintext highlighter-rouge">18.04</code> or <code class="language-plaintext highlighter-rouge">20.04.z</code> with minor OS version <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">1</code>, or <code class="language-plaintext highlighter-rouge">2</code>: Foreman searches for <code class="language-plaintext highlighter-rouge">initrd.gz</code> and <code class="language-plaintext highlighter-rouge">linux</code> in <code class="language-plaintext highlighter-rouge">dists/bionic/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64/</code> for 18.04 and <code class="language-plaintext highlighter-rouge">dists/focal/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64/</code> for 20.04.
This means that you have to use <code class="language-plaintext highlighter-rouge">Preseed</code> templates suitable for the <code class="language-plaintext highlighter-rouge">debian-installer</code> mechanism.</li>
  <li>For Ubuntu with major OS version <code class="language-plaintext highlighter-rouge">20.04</code> with minor OS version <code class="language-plaintext highlighter-rouge">3</code> or above, or <code class="language-plaintext highlighter-rouge">22.04.z</code>: Foreman searches for <code class="language-plaintext highlighter-rouge">initrd</code> and <code class="language-plaintext highlighter-rouge">vmlinuz</code> in <code class="language-plaintext highlighter-rouge">casper/</code>.
This means that you have to use <code class="language-plaintext highlighter-rouge">Autoinstall</code> templates suitable for the <code class="language-plaintext highlighter-rouge">Subiquity</code> installer.</li>
</ul>

<p>When you create a host, Foreman retrieves the boot files from the URL of the installation media.
For Debian and Ubuntu prior to 20.04.3, you could use <code class="language-plaintext highlighter-rouge">http://archive.ubuntu.com</code> and Foreman would find the required files based on the code name configured for the OS entry.
For Ubuntu 20.04.3+, those files are no longer present in the official upstream repositories.
Therefore, you have to extract the ISO image and make it accessible for Foreman Server or Smart Proxy Server during provisioning.
For example, you can place it in <code class="language-plaintext highlighter-rouge">FQDN/pub/installation_media/ubuntu/20.04/</code>.</p>

<h3 id="provisioning-debianubuntu-compared-to-enterprise-linux">Provisioning Debian/Ubuntu Compared to Enterprise Linux</h3>

<p>In contrast to Enterprise Linux such as Red Hat Enterprise Linux or AlmaLinux, you cannot provision Ubuntu based on synchronized content.
This is due to the missing Linux Kernel and initrd files in the synchronized Pulp repositories.
The alternative for both Debian and Ubuntu has mostly been to either use the upstream repositories (downside: you need access to the internet), or by extracting the installation files from the ISO image and providing them under <code class="language-plaintext highlighter-rouge">pub/</code> on your Foreman Server (downside: depends on the z-release).</p>

<h3 id="provisioning-process">Provisioning process</h3>

<ul>
  <li>Foreman provides the rendered user data template on <code class="language-plaintext highlighter-rouge">FQDN/userdata/</code>.
This interface is already in use for all image-based deployments that use <code class="language-plaintext highlighter-rouge">cloud-init</code> templates.</li>
  <li>Because the ISO image is also required for the deployment but Foreman does not provide any dedicated interface for this, we have documented a way to place the ISO image into the <code class="language-plaintext highlighter-rouge">FQDN/pub/installation_media</code> directory on Foreman Server.
This means Foreman serves the ISO image over <code class="language-plaintext highlighter-rouge">http</code>.
If you want to deploy a host from a Smart Proxy Server, you have to copy the ISO image to your Smart Proxy Server.</li>
  <li>Ubuntu Autoinstall deployments also require the extracted ISO image.
You have to place the extracted ISO image in <code class="language-plaintext highlighter-rouge">FQDN/pub/installation_media/</code> on your Foreman Server and name the directory identical to the ISO image without the <code class="language-plaintext highlighter-rouge">.iso</code> file ending.
If you want to deploy a host from a Smart Proxy Server, you have to copy the extracted ISO image to your Smart Proxy Server.</li>
</ul>

<p>Ensure that you provide the ISO and extracted ISO under the same name, for example <code class="language-plaintext highlighter-rouge">22_04.iso</code> and <code class="language-plaintext highlighter-rouge">22_04/</code>, to use the URL for the installation media as path for both.
For more information, see <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#Creating_an_Installation_Medium_for_Ubuntu_22_04_provisioning">Creating an Installation Medium for Ubuntu 22.04</a> in <em>Provisioning Hosts</em>.</p>

<h4 id="preseed_kernel_options_autoinstallerb">preseed_kernel_options_autoinstall.erb</h4>

<p>The <code class="language-plaintext highlighter-rouge">preseed_kernel_options_autoinstall.erb</code> template sets the path to the ISO image based on the URL of the installation media and configure the Kernel parameters.</p>

<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;%#
kind: snippet
name: preseed_kernel_options_autoinstall
model: ProvisioningTemplate
snippet: true
description: options for the kernel / preseed startup initialization
oses:
- ubuntu
test_on:
- ubuntu_autoinst4dhcp
-%&gt;</span>
<span class="cp">&lt;%</span>
  <span class="o">...</span>
  <span class="n">image_path</span> <span class="o">=</span> <span class="vi">@preseed_path</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="sr">/\/?$/</span><span class="p">,</span> <span class="s1">'.iso'</span><span class="p">)</span>
  <span class="n">userdata_option</span> <span class="o">=</span> <span class="s2">"ds=nocloud-net;s=http://</span><span class="si">#{</span><span class="n">foreman_request_addr</span><span class="si">}</span><span class="s2">/userdata/"</span>
  <span class="n">options</span> <span class="o">=</span> <span class="p">[]</span>

  <span class="o">...</span>

  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"BOOTIF=</span><span class="si">#{</span><span class="n">mac</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="n">mac</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'ramdisk_size=1500000'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'fsck.mode=skip'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'autoinstall'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"url=http://</span><span class="si">#{</span><span class="vi">@preseed_server</span><span class="si">}#{</span><span class="n">image_path</span><span class="si">}</span><span class="s2">"</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'cloud-config-url=/dev/null'</span>
  <span class="k">if</span> <span class="vi">@add_userdata_quotes</span>
    <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"</span><span class="se">\"</span><span class="si">#{</span><span class="n">userdata_option</span><span class="si">}</span><span class="se">\"</span><span class="s2">"</span>
  <span class="k">else</span>
    <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="n">userdata_option</span>
  <span class="k">end</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'console-setup/ask_detect=false'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"locale=</span><span class="si">#{</span><span class="n">host_param</span><span class="p">(</span><span class="s1">'lang'</span><span class="p">)</span> <span class="o">||</span> <span class="s1">'en_US'</span><span class="si">}</span><span class="s2">"</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'localechooser/translation/warn-light=true'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s1">'localechooser/translation/warn-severe=true'</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"hostname=</span><span class="si">#{</span><span class="n">hostname</span><span class="si">}</span><span class="s2">"</span>
  <span class="n">options</span> <span class="o">&lt;&lt;</span> <span class="s2">"domain=</span><span class="si">#{</span><span class="n">domain</span><span class="si">}</span><span class="s2">"</span>
<span class="cp">%&gt;</span>
<span class="cp">&lt;%=</span> <span class="n">options</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span> <span class="cp">-%&gt;</span>
</code></pre></div></div>

<p>For more information, see <a href="https://github.com/theforeman/foreman/blob/develop/app/views/unattended/provisioning_templates/snippet/preseed_kernel_options_autoinstall.erb">app/views/unattended/provisioning_templates/snippet/preseed_kernel_options_autoinstall.erb</a> in the <em>foreman</em> repository.</p>

<p>To complete the provisioning process, the user data template configures a user, sets up remote access using authorized SSH keys, configures networking and the disk layout, and fetches the rendered finish data template from Foreman.
The <code class="language-plaintext highlighter-rouge">Preseed default finish</code> template installs <code class="language-plaintext highlighter-rouge">subscription-manager</code> and registers the host to Foreman.</p>

<h3 id="provisioning-templates">Provisioning Templates</h3>

<ul>
  <li>Debian 10 “Buster”, Debian 11 “Bullseye”, Debian 12 “Bookworm”, Ubuntu 18.04 “Bionic”, and Ubuntu 20.04, 20.04.1, 20.04.2 “Focal”: <code class="language-plaintext highlighter-rouge">Preseed default</code> provisioning templates</li>
  <li>Ubuntu 20.04 “Focal” and Ubuntu 22.04 “Jammy”: <code class="language-plaintext highlighter-rouge">Autoinstall</code> provisioning templates</li>
</ul>

<h4 id="provisioning-templates-for-preseed-and-autoinstall">Provisioning Templates for “Preseed” and “Autoinstall”</h4>

<table>
  <thead>
    <tr>
      <th>Template Type</th>
      <th>Preseed</th>
      <th>Autoinstall</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Finish template</td>
      <td>Preseed default finish</td>
      <td>Preseed default finish</td>
    </tr>
    <tr>
      <td>Host initial configuration template</td>
      <td>Linux host_init_config default</td>
      <td>Linux host_init_config default</td>
    </tr>
    <tr>
      <td>iPXE template</td>
      <td>Preseed default iPXE</td>
      <td>Preseed default iPXE Autoinstall</td>
    </tr>
    <tr>
      <td>Provisioning template</td>
      <td>Preseed default</td>
      <td>-</td>
    </tr>
    <tr>
      <td>PXEGrub template</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr>
      <td>PXEGrub2 template</td>
      <td>Preseed default PXEGrub2</td>
      <td>Preseed default PXEGrub2 Autoinstall</td>
    </tr>
    <tr>
      <td>PXELinux template</td>
      <td>Preseed default PXELinux</td>
      <td>Preseed default PXELinux Autoinstall</td>
    </tr>
    <tr>
      <td>User data template</td>
      <td>-</td>
      <td>Preseed Autoinstall cloud-init user data</td>
    </tr>
  </tbody>
</table>

<h2 id="example-workflow-provisioning-ubuntu-2204-through-a-smart-proxy-server">Example Workflow: Provisioning Ubuntu 22.04 through a Smart Proxy Server</h2>

<p>This example guides you through the extensive Foreman documentation and its <em>Provisioning Hosts</em> guide.
It assumes you have a running Foreman 3.9 with Katello 4.11 instance.</p>

<ol>
  <li>Create an operating system entry on your Foreman+Katello.
For more information, see <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#Creating_an_Operating_System_for_Ubuntu_provisioning">Creating an Operating System for Ubuntu</a>.
    <ul>
      <li>Set the <em>OS major version</em> to <code class="language-plaintext highlighter-rouge">22.04</code> for Ubuntu 22.04 “Jammy Jellyfish”.</li>
      <li>The <em>OS minor version</em> does not impact your OS deployment.</li>
      <li>Set the <em>Release Name</em> to <code class="language-plaintext highlighter-rouge">jammy</code>.</li>
      <li>Select the <code class="language-plaintext highlighter-rouge">Preseed default Autoinstall</code> templates and <code class="language-plaintext highlighter-rouge">Preseed Autoinstall cloud-init user data</code> as user data template.</li>
      <li>Ensure to use the <code class="language-plaintext highlighter-rouge">PXELinux Autoinstall</code> template as PXELinux template.</li>
    </ul>
  </li>
  <li>If you have made any changes to <code class="language-plaintext highlighter-rouge">Preseed default</code> templates, replicate those, if required, in the <code class="language-plaintext highlighter-rouge">Autoinstall</code> templates.
Be aware that customized templates in Foreman do not receive any updates.
For more information, see <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#Associating_Templates_with_Operating_Systems_provisioning">Associating Templates with Operating Systems</a>.</li>
  <li>Provide the Ubuntu 22.04 ISO image and extracted ISO image on your Foreman Server: <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#Creating_an_Installation_Medium_for_Ubuntu_22_04_provisioning">Creating an Installation Medium for Ubuntu 22.04</a>.
Ensure that the name of the ISO image and the directory of the extracted ISO image match as described above.</li>
  <li>Copy the ISO image and extracted ISO image to your Smart Proxy Server: <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#Provisioning_Ubuntu_Autoinstall_Through_Smart_Proxies_provisioning">Provisioning Ubuntu Autoinstall Through Smart Proxies</a>.</li>
  <li>Create two installation media entries and associate them with your operating system entry: <a href="https://docs.theforeman.org/3.9/Provisioning_Hosts/index-katello.html#adding-installation-media_provisioning">Adding Installation Media to Foreman</a>.
    <ul>
      <li>Create an installation media entry for the extracted ISO image on your Foreman Server.</li>
      <li>Create an installation media entry for the extracted ISO image on your Smart Proxy Server.</li>
    </ul>
  </li>
  <li>Synchronize the Foreman Client for Ubuntu 22.04 from oss.atix.de: <a href="https://docs.theforeman.org/3.9/Managing_Content/index-katello.html#Adding_Custom_DEB_Repository_Example_for_Ubuntu_22_04_content-management">Adding DEB Repository Example for Ubuntu 22.04</a>.
For more information, see <a href="https://oss.atix.de/">oss.atix.de</a>.
Ensure to add the Foreman Client repository to your content view.</li>
  <li>Tie everything together in a host group: <a href="https://docs.theforeman.org/3.9/Managing_Hosts/index-katello.html#Creating_a_Host_Group_managing-hosts">Creating a Host Group</a>.
Ensure that your host group uses the proper installation media entry to provision Ubuntu 22.04 through Smart Proxy Servers.</li>
  <li>Deploy a host. 🎉</li>
</ol>

<p>If you have any questions, please open a thread in the <a href="https://community.theforeman.org/">Foreman Community Forum</a>.</p>]]></content><author><name>Maximilian Kolb</name></author><category term="foreman" /><category term="provisioning" /><category term="ubuntu" /><category term="autoinstall" /><summary type="html"><![CDATA[Foreman supports provisioning hosts running Debian and Ubuntu on VMware, Proxmox, cloud providers such as Microsoft Azure, and bare metal hosts. With the Katello plug-in, provisioned and registered hosts receive versioned DEB content based on their lifecycle. This blog article is a short summary of what happened behind the scenes to provisioning hosts running Ubuntu 20.04.3+, why you need new templates, and how to use the new deployment mechanism.]]></summary></entry><entry><title type="html">Testing a foreman-installer patch with Packit and forklift</title><link href="https://theforeman.org/2023/11/testing-a-foreman-installer-patch-with-packit-and-forklift.html" rel="alternate" type="text/html" title="Testing a foreman-installer patch with Packit and forklift" /><published>2023-11-03T11:41:32+00:00</published><updated>2023-11-03T11:41:32+00:00</updated><id>https://theforeman.org/2023/11/testing-a-foreman-installer-patch-with-packit-and-forklift</id><content type="html" xml:base="https://theforeman.org/2023/11/testing-a-foreman-installer-patch-with-packit-and-forklift.html"><![CDATA[<p>Today I was working on a potential fix for the issue that <a href="https://github.com/theforeman/foreman-fapolicyd/issues/7">Puppetserver doesn’t start when deployed with fapolicyd in enforcing mode</a>.</p>

<p>I knew that the potential fix is to set <code class="language-plaintext highlighter-rouge">PrivateTmp=true</code> in the systemd unit, so the <a href="https://github.com/theforeman/puppet-puppet/pull/892">patch</a> was quickly written, but how would one verify it end to end?</p>

<!--more-->

<p>In Foreman, our releases (and nightlies!) are tested using <a href="https://github.com/theforeman/foreman">forklift</a>, a combination of <a href="https://www.vagrantup.com/">Vagrant</a> for managing VMs and <a href="https://www.ansible.com/">Ansible</a> for deploying Foreman in them and running <a href="https://github.com/bats-core/bats-core">bats</a>.</p>

<p>We can run the installation pipeline for Foreman nightly on CentOS Stream 8 like this:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">% ansible-playbook pipelines/install_pipeline.yml -e pipeline_os=centos8-stream -e pipeline_version=nightly -e pipeline_type=foreman
…
TASK [bats : Run bats] *************************************************************************************************************
</span><span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-verify-packages.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-foreman.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-puppet.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-backup.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-verify-selinux.bats<span class="o">)</span>
<span class="go">…
PLAY RECAP *************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0
pipe-foreman-server-nightly-centos8-stream : ok=62   changed=19   unreachable=0    failed=0    skipped=37   rescued=0    ignored=1
pipe-foreman-smoker-nightly-centos8-stream : ok=17   changed=12   unreachable=0    failed=0    skipped=3    rescued=0    ignored=0
</span></code></pre></div></div>

<p>As we see, the tests pass and everyone is happy.</p>

<p>We can destroy the setup again, and continue with our tasks:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">% ansible-playbook pipelines/install_pipeline.yml -e pipeline_os=centos8-stream -e pipeline_version=nightly -e pipeline_type=foreman -e forklift_state=destroy
</span></code></pre></div></div>

<p>The tests passed because we do not deploy fapolicyd by default as the integration is not yet fully ready.</p>

<p>To test the integration, there is a feature flag: <a href="https://github.com/theforeman/forklift/pull/1724"><code class="language-plaintext highlighter-rouge">foreman_fapolicyd</code></a> and if we enable it, the overall installation fails as expected:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">% ansible-playbook pipelines/install_pipeline.yml -e pipeline_os=centos8-stream -e pipeline_version=nightly -e pipeline_type=foreman -e foreman_fapolicyd=true
…
TASK [foreman_installer : Run installer] *******************************************************************************************
</span><span class="gp">fatal: [pipe-foreman-server-nightly-centos8-stream]: FAILED! =&gt;</span><span class="w"> </span><span class="nv">changed</span><span class="o">=</span><span class="nb">true</span>
<span class="go">…
    Error 1: Puppet Service resource 'puppetserver' failed. Logs:
      /Service[puppetserver]
        Starting to evaluate the resource (993 of 1266)
</span><span class="gp">        Skipping restart;</span><span class="w"> </span>service is not running
<span class="go">        Triggered 'refresh' from 2 events
        The container Class[Puppet::Server::Service] will propagate my refresh event
        Evaluated in 9.75 seconds
      /Stage[main]/Puppet::Server::Service/Service[puppetserver]/ensure
        change from 'stopped' to 'running' failed: Systemd start for puppetserver failed!
    journalctl log for puppetserver:
    -- Logs begin at Fri 2023-11-03 08:53:57 UTC, end at Fri 2023-11-03 09:01:28 UTC. --
    Nov 03 09:01:19 pipe-foreman-server-nightly-centos8-stream.tanso.example.com systemd[1]: Starting puppetserver Service...
</span><span class="gp">    Nov 03 09:01:22 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48125]: WARNING: abs already refers to: #</span><span class="s1">'clojure.core/abs in namespace: medley.core, being replaced by: #'</span>medley.core/abs
<span class="go">    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48125]: Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:387).
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48125]: org.jruby.ext.psych.PsychLibrary
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48125]: Full report at:
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48125]: /tmp/clojure-5697285534509071746.edn
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com puppetserver[48098]: Background process 48125 exited before start had completed
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com systemd[1]: puppetserver.service: Control process exited, code=exited status=1
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com systemd[1]: puppetserver.service: Failed with result 'exit-code'.
    Nov 03 09:01:28 pipe-foreman-server-nightly-centos8-stream.tanso.example.com systemd[1]: Failed to start puppetserver Service.

    1 error was detected during installation.
    Please address the errors and re-run the installer to ensure the system is properly configured.
    Failing to do so is likely to result in broken functionality.

    The full log is at /var/log/foreman-installer/foreman.log
</span><span class="gp">  stdout_lines: &lt;omitted&gt;</span><span class="w">
</span><span class="go">
PLAY RECAP *************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0
pipe-foreman-server-nightly-centos8-stream : ok=47   changed=12   unreachable=0    failed=1    skipped=28   rescued=0    ignored=1
</span></code></pre></div></div>

<p>Now that we know that we can reproduce the reported issue, let’s try to deploy the fix and see if it <em>actually</em> fixes things.</p>

<p>The <a href="https://github.com/theforeman/puppet-puppet/pull/892">patch</a> is against our Puppet module that is responsible for deploying the Puppetserver, but our installation procedure doesn’t call Puppet directly, it uses <code class="language-plaintext highlighter-rouge">foreman-installer</code> which under the hood uses Puppet. So to test the fix we need to build <code class="language-plaintext highlighter-rouge">foreman-installer</code> with the patched module and deploy the result during the installation pipeline, before Ansible calls the installer.</p>

<p>This sounds tedious and error prone, but luckily we have <a href="https://packit.dev/">Packit</a> integration in our <code class="language-plaintext highlighter-rouge">foreman-installer</code> repository and in <code class="language-plaintext highlighter-rouge">forklift</code>. That means that we need to create a <a href="https://github.com/theforeman/foreman-installer/pull/897">PR</a> against the installer repository, temporarily pointing at the patched Puppet module and once Packit has built the package can <a href="https://theforeman.github.io/forklift/development/#packit-pr-builds">instruct <code class="language-plaintext highlighter-rouge">forklift</code> to use that Packit repository during deployment</a>, validating the fix:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">% ansible-playbook pipelines/install_pipeline.yml -e pipeline_os=centos8-stream -e pipeline_version=nightly -e pipeline_type=foreman -e foreman_fapolicyd=true -e '{"packit_prs":["theforeman/foreman-installer/897"]}'
…
TASK [packit : setup packit copr] **************************************************************************************************
</span><span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>theforeman/foreman-installer/897<span class="o">)</span>
<span class="go">…
TASK [bats : Run bats] *************************************************************************************************************
</span><span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-verify-packages.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-foreman.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-puppet.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-test-backup.bats<span class="o">)</span>
<span class="gp">changed: [pipe-foreman-server-nightly-centos8-stream] =&gt;</span><span class="w"> </span><span class="o">(</span><span class="nv">item</span><span class="o">=</span>fb-verify-selinux.bats<span class="o">)</span>
<span class="go">…
</span></code></pre></div></div>

<p>And this is the story of how I could validate the fix while drinking a coffee instead of thinking how to inject the manually built package at the right time into the automated installation test.</p>]]></content><author><name>Evgeni Golov</name></author><category term="foreman" /><category term="packit" /><summary type="html"><![CDATA[Today I was working on a potential fix for the issue that Puppetserver doesn’t start when deployed with fapolicyd in enforcing mode. I knew that the potential fix is to set PrivateTmp=true in the systemd unit, so the patch was quickly written, but how would one verify it end to end?]]></summary></entry><entry><title type="html">Integrating Foreman with Event-Driven Ansible</title><link href="https://theforeman.org/2023/04/integrating-foreman-with-event-driven-ansible.html" rel="alternate" type="text/html" title="Integrating Foreman with Event-Driven Ansible" /><published>2023-04-13T08:00:00+00:00</published><updated>2023-04-13T08:00:00+00:00</updated><id>https://theforeman.org/2023/04/integrating-foreman-with-event-driven-ansible</id><content type="html" xml:base="https://theforeman.org/2023/04/integrating-foreman-with-event-driven-ansible.html"><![CDATA[<p><a href="https://www.ansible.com/use-cases/event-driven-automation">Event-Driven Ansible</a> is a new way of automation where your automation can dynamically react to events that happen in your environment.
Today, we want to show you how you can integrate that with Foreman using the <a href="https://github.com/theforeman/foreman_webhooks">Foreman Webhooks plugin</a>.</p>

<!--more-->

<p>As workflows and events one might want to react to will vary across different setups, we’ll show one example integration and let everyone adopt it to their needs.
The workflow in this example is to have machines in a group update once their content has been updated in Katello.
You can find a full list of <a href="https://docs.theforeman.org/nightly/Administering_Project/index-katello.html#webhooks-available-events_admin">available Webhook Events in the documentation</a>.</p>

<p>First of all, we need a Katello installation with the Foreman Webhooks plugin enabled.
This can be achieved by calling <code class="language-plaintext highlighter-rouge">foreman-installer --enable-foreman-plugin-webhooks</code> on an existing setup or passing <code class="language-plaintext highlighter-rouge">--enable-foreman-plugin-webhooks</code> during the initial installation.</p>

<p>Second, we need a place to run Ansible and Ansible-Rulebook.
An empty CentOS Stream 8 machine where we follow the <a href="https://ansible-rulebook.readthedocs.io/en/stable/installation.html">ansible-rulebook installation</a> and the <a href="https://github.com/ansible/event-driven-ansible">ansible.eda collection installation</a> guides will do:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">[root@eda] #</span><span class="w"> </span>dnf <span class="nb">install </span>java-17-openjdk python39-pip
<span class="gp">[user@eda ~]$</span><span class="w"> </span><span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span>/usr/lib/jvm/jre-17-openjdk
<span class="gp">[user@eda ~]$</span><span class="w"> </span>python3.9 <span class="nt">-m</span> venv ./eda-venv
<span class="gp">[user@eda ~]$</span><span class="w"> </span><span class="nb">.</span> ./eda-venv/bin/activate
<span class="gp">(eda-venv) [user@eda ~]$</span><span class="w"> </span>pip <span class="nb">install </span>ansible-rulebook ansible ansible-runner
<span class="gp">(eda-venv) [user@eda ~]$</span><span class="w"> </span>ansible-galaxy collection <span class="nb">install </span>ansible.eda
<span class="gp">(eda-venv) [user@eda ~]$</span><span class="w"> </span>pip <span class="nb">install</span> <span class="nt">-r</span> ~/.ansible/collections/ansible_collections/ansible/eda/requirements.txt
</code></pre></div></div>
<p>The only difference to the official guides is that we explicitly used Python 3.9, as the default Python in CentOS Stream 8 is Python 3.6 and that is too old for <code class="language-plaintext highlighter-rouge">ansible-rulebook</code> and <code class="language-plaintext highlighter-rouge">ansible-runner</code>.</p>

<p>Quickly check that the <code class="language-plaintext highlighter-rouge">ansible-rulebook</code> CLI is working:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">(eda-venv) [user@eda ~]$</span><span class="w"> </span>ansible-rulebook <span class="nt">--help</span>
<span class="go">usage: ansible-rulebook [-h] [-r RULEBOOK] [-e VARS] [-E ENV_VARS] [-v] [--version] [-S SOURCE_DIR] [-i INVENTORY] [-W WEBSOCKET_ADDRESS] [--id ID] [-w] [-T PROJECT_TARBALL] [--controller-url CONTROLLER_URL]
                        [--controller-token CONTROLLER_TOKEN] [--controller-ssl-verify CONTROLLER_SSL_VERIFY] [--print-events] [--shutdown-delay SHUTDOWN_DELAY] [--gc-after GC_AFTER]

optional arguments:
  -h, --help            show this help message and exit
  -r RULEBOOK, --rulebook RULEBOOK
                        The rulebook file or rulebook from a collection
  -e VARS, --vars VARS  Variables file
  -E ENV_VARS, --env-vars ENV_VARS
                        Comma separated list of variables to import from the environment
  -v, --verbose         Causes ansible-rulebook to print more debug messages. Adding multiple -v will increase the verbosity, the default value is 0. The maximum value is 2. Events debugging might require -vv.
  --version             Show the version and exit
  -S SOURCE_DIR, --source-dir SOURCE_DIR
                        Source dir
  -i INVENTORY, --inventory INVENTORY
                        Inventory
  -W WEBSOCKET_ADDRESS, --websocket-address WEBSOCKET_ADDRESS
                        Connect the event log to a websocket
  --id ID               Identifier
  -w, --worker          Enable worker mode
  -T PROJECT_TARBALL, --project-tarball PROJECT_TARBALL
                        A tarball of the project
  --controller-url CONTROLLER_URL
                        Controller API base url, e.g. https://host1:8080 can also be passed via the env var EDA_CONTROLLER_URL
  --controller-token CONTROLLER_TOKEN
                        Controller API authentication token, can also be passed via env var EDA_CONTROLLER_TOKEN
  --controller-ssl-verify CONTROLLER_SSL_VERIFY
</span><span class="gp">                        How to verify SSL when connecting to the controller, yes|no|&lt;path to a CA bundle&gt;</span>, default to <span class="nb">yes </span><span class="k">for </span>https connection.can also be passed via <span class="nb">env </span>var EDA_CONTROLLER_SSL_VERIFY
<span class="go">  --print-events        Print events to stdout, redundant and disabled with -vv
  --shutdown-delay SHUTDOWN_DELAY
                        Maximum number of seconds to wait after issuing a graceful shutdown, default: 60. The process will shutdown if all actions complete before this time period
  --gc-after GC_AFTER   Run the garbage collector after this number of events. It can be configured with the environment variable EDA_GC_AFTER
</span></code></pre></div></div>

<p>Now that we have Foreman/Katello and ansible-rulebook working, we need to integrate the two together.</p>

<p>The <a href="https://github.com/ansible/event-driven-ansible/"><code class="language-plaintext highlighter-rouge">ansible.eda</code> collection</a> comes with an <a href="https://github.com/ansible/event-driven-ansible/blob/main/plugins/event_source/webhook.py"><code class="language-plaintext highlighter-rouge">ansible.eda.webhook</code></a> event source plugin, which we can use as the receiver of the webhooks that Foreman Webhooks will send.
For that we create a new <a href="https://ansible-rulebook.readthedocs.io/en/latest/rulebooks.html">rulebook</a> (<code class="language-plaintext highlighter-rouge">rulebook.yml</code>) that configures the webhook and how to proceed with the received events:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Listen for events on a webhook</span>
  <span class="na">hosts</span><span class="pi">:</span> <span class="s">all</span>

  <span class="c1">## Define our source for events</span>

  <span class="na">sources</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">ansible.eda.webhook</span><span class="pi">:</span>
        <span class="na">host</span><span class="pi">:</span> <span class="s">0.0.0.0</span>
        <span class="na">port</span><span class="pi">:</span> <span class="m">5000</span>

  <span class="c1">## Define the conditions we are looking for</span>

  <span class="na">rules</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">check which content view was updated</span>
      <span class="na">condition</span><span class="pi">:</span> <span class="s">event.payload.content_view_name == "dev"</span>

  <span class="c1">## Define the action we should take should the condition be met</span>

      <span class="na">action</span><span class="pi">:</span>
        <span class="na">run_playbook</span><span class="pi">:</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">update.yml</span>
</code></pre></div></div>

<p>This rulebook means we start the <code class="language-plaintext highlighter-rouge">ansible.eda.webhook</code> plugin on <code class="language-plaintext highlighter-rouge">0.0.0.0:5000</code> and every time an event happens that has the <code class="language-plaintext highlighter-rouge">content_view_name</code> field in the payload set to <code class="language-plaintext highlighter-rouge">dev</code> we execute the <code class="language-plaintext highlighter-rouge">update.yml</code> playbook.</p>

<p>The <code class="language-plaintext highlighter-rouge">update.yml</code> playbook is rather short, just calling the <code class="language-plaintext highlighter-rouge">ansible.builtin.dnf</code> module on the <code class="language-plaintext highlighter-rouge">foreman_dev</code> group to update packages:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="pi">-</span> <span class="na">hosts</span><span class="pi">:</span> <span class="s">foreman_dev</span>
  <span class="na">tasks</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Upgrade all packages</span>
      <span class="na">ansible.builtin.dnf</span><span class="pi">:</span>
        <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">*"</span>
        <span class="na">state</span><span class="pi">:</span> <span class="s">latest</span>
</code></pre></div></div>

<p>Ideally, the <code class="language-plaintext highlighter-rouge">foreman_dev</code> group would come from the <a href="https://github.com/theforeman/foreman-ansible-modules/blob/develop/plugins/inventory/foreman.py"><code class="language-plaintext highlighter-rouge">theforeman.foreman.foreman</code> inventory plugin</a> we provide, but <a href="https://github.com/ansible/ansible-rulebook/issues/344"><code class="language-plaintext highlighter-rouge">ansible-rulebook</code> does not yet support inventory plugins</a>.
Instead, we create a static YAML inventory (<code class="language-plaintext highlighter-rouge">inventory.yml</code>):</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">foreman_dev</span><span class="pi">:</span>
  <span class="na">hosts</span><span class="pi">:</span>
    <span class="s">dev01.example.com</span>
</code></pre></div></div>

<p>We can now start <code class="language-plaintext highlighter-rouge">ansible-rulebook</code>:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">(eda-venv) [user@eda ~]$</span><span class="w"> </span>ansible-rulebook <span class="nt">--inventory</span> inventory.yml <span class="nt">--rulebook</span> rulebook.yml <span class="nt">--verbose</span>
<span class="go">2023-04-13 07:55:11,974 - ansible_rulebook.app - INFO - Starting sources
2023-04-13 07:55:11,974 - ansible_rulebook.app - INFO - Starting rules
2023-04-13 07:55:11,974 - ansible_rulebook.engine - INFO - run_ruleset
2023-04-13 07:55:11,974 - drools.ruleset - INFO - Using jar: /home/user/eda-venv/lib/python3.9/site-packages/drools/jars/drools-ansible-rulebook-integration-runtime-1.0.0-SNAPSHOT.jar
2023-04-13 07:55:12,308 - ansible_rulebook.engine - INFO - ruleset define: {"name": "Listen for events on a webhook", "hosts": ["all"], "sources": [{"EventSource": {"name": "ansible.eda.webhook", "source_name": "ansible.eda.webhook", "source_args": {"host": "0.0.0.0", "port": 5000}, "source_filters": []}}], "rules": [{"Rule": {"name": "check which content view was updated", "condition": {"AllCondition": [{"EqualsExpression": {"lhs": {"Event": "payload.content_view_name"}, "rhs": {"String": "dev"}}}]}, "actions": [{"Action": {"action": "run_playbook", "action_args": {"name": "update.yml"}}}], "enabled": true}}]}
2023-04-13 07:55:12,317 - ansible_rulebook.engine - INFO - load source
2023-04-13 07:55:12,621 - ansible_rulebook.engine - INFO - load source filters
2023-04-13 07:55:12,621 - ansible_rulebook.engine - INFO - loading eda.builtin.insert_meta_info
2023-04-13 07:55:12,909 - ansible_rulebook.engine - INFO - Calling main in ansible.eda.webhook
2023-04-13 07:55:12,911 - ansible_rulebook.engine - INFO - Waiting for all ruleset tasks to end
2023-04-13 07:55:12,911 - ansible_rulebook.rule_set_runner - INFO - Waiting for actions on events from Listen for events on a webhook
2023-04-13 07:55:12,911 - ansible_rulebook.rule_set_runner - INFO - Waiting for events, ruleset: Listen for events on a webhook
2023-04-13 07:55:12 912 [drools-async-evaluator-thread] INFO org.drools.ansible.rulebook.integration.api.io.RuleExecutorChannel - Async channel connected
</span></code></pre></div></div>

<p>A quick <code class="language-plaintext highlighter-rouge">curl</code> call shows us that things are responding – don’t worry about the “Method Not Allowed”, <code class="language-plaintext highlighter-rouge">curl</code> does a <code class="language-plaintext highlighter-rouge">GET</code> here, but the endpoint only accepts <code class="language-plaintext highlighter-rouge">POST</code>:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">% curl http://eda.example.com:5000/endpoint
405: Method Not Allowed
</span></code></pre></div></div>

<p>With the Ansible side done, we can move on to Foreman.</p>

<p>While Foreman Webhooks comes with a few <a href="https://github.com/theforeman/foreman_webhooks/tree/master/app/views/foreman_webhooks/webhook_templates">example webhook templates</a>,
none of these generate a JSON representation of a Content View Promotion event, so we need to create one ourselves under “Administer &gt; Webhook Templates”:</p>

<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;%#
name: Katello Promote JSON
description: JSON payload for actions.katello.content_view.promote_suceeded
snippet: false
model: WebhookTemplate
-%&gt;</span>
<span class="cp">&lt;%=</span>
  <span class="n">payload</span><span class="p">({</span>
    <span class="s2">"content_view_id"</span><span class="p">:</span> <span class="vi">@object</span><span class="p">.</span><span class="nf">content_view_id</span><span class="p">,</span>
    <span class="s2">"content_view_name"</span><span class="p">:</span> <span class="vi">@object</span><span class="p">.</span><span class="nf">content_view_name</span><span class="p">,</span>
    <span class="s2">"content_view_label"</span><span class="p">:</span> <span class="vi">@object</span><span class="p">.</span><span class="nf">content_view_label</span><span class="p">,</span>
  <span class="p">})</span>
<span class="cp">-%&gt;</span>
</code></pre></div></div>

<p>Once the template is created, we can create we webhook under “Administer &gt; Webhooks”, using it:</p>

<p><img src="/static/images/blog_images/2023-04-13-integrating-foreman-with-event-driven-ansible/create_webhook.png" alt="new webhook button" /></p>

<p><img src="/static/images/blog_images/2023-04-13-integrating-foreman-with-event-driven-ansible/create_webhook_form.png" alt="new webhook form" /></p>

<ul>
  <li>Subscribe to: Actions Katello Content View Promote Succeeded</li>
  <li>Name: ansible inform cv promote</li>
  <li>Target URL: <code class="language-plaintext highlighter-rouge">http://eda.example.com:5000/endpoint</code></li>
  <li>Template: Katello Promote JSON</li>
  <li>HTTP Method: POST</li>
  <li>Enabled: true</li>
</ul>

<p>Now, every time <em>any</em> content view is promoted, a webhook is sent to <code class="language-plaintext highlighter-rouge">eda.example.com</code>, which then filters based on the name of the content view and executes the <code class="language-plaintext highlighter-rouge">update.yml</code> playbook if the name was <code class="language-plaintext highlighter-rouge">dev</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2023-04-13 08:11:00,856 - aiohttp.access - INFO - 192.168.122.149 [13/Apr/2023:08:11:00 +0000] "POST /endpoint HTTP/1.1" 200 177 "-" "Ruby"
2023-04-13 08:11:00 937 [main] INFO org.drools.ansible.rulebook.integration.api.rulesengine.RegisterOnlyAgendaFilter - Activation of effective rule "check which content view was updated" with facts: {m={payload={content_view_id=2, content_view_name=dev, webhook_id=1, context={request=e86e61df-548b-4572-9c20-d534d2addad6, user_admin=true, org_id=1, org_label=Default_Organization, user_login=admin, loc_name=Default Location, org_name=Default Organization, loc_id=2}, content_view_label=dev, event_name=actions.katello.content_view.promote_succeeded.event.foreman}, meta={headers={Accept=*/*, X-Session-Id=c38e182d-b6bc-4ceb-9cc4-c8ad36dbbda2, X-Request-Id=e86e61df-548b-4572-9c20-d534d2addad6, User-Agent=Ruby, Connection=close, Host=centos8-stream-eda.tanso.example.com:5000, Accept-Encoding=gzip;q=1.0,deflate;q=0.6,identity;q=0.3, Content-Length=386, Content-Type=application/json}, endpoint=endpoint, received_at=2023-04-13T08:11:00.856103Z, source={name=ansible.eda.webhook, type=ansible.eda.webhook}, uuid=0bef4d63-df1c-4be1-b1f1-4956d2e6529b}}}
2023-04-13 08:11:00,962 - ansible_rulebook.rule_generator - INFO - calling check which content view was updated
2023-04-13 08:11:00,964 - ansible_rulebook.rule_set_runner - INFO - call_action run_playbook
2023-04-13 08:11:00,964 - ansible_rulebook.rule_set_runner - INFO - substitute_variables [{'name': 'update.yml'}] [{'event': {'payload': {'content_view_id': 2, 'content_view_name': 'dev', 'webhook_id': 1, 'context': {'request': 'e86e61df-548b-4572-9c20-d534d2addad6', 'user_admin': True, 'org_id': 1, 'org_label': 'Default_Organization', 'user_login': 'admin', 'loc_name': 'Default Location', 'org_name': 'Default Organization', 'loc_id': 2}, 'content_view_label': 'dev', 'event_name': 'actions.katello.content_view.promote_succeeded.event.foreman'}, 'meta': {'headers': {'Accept': '*/*', 'X-Session-Id': 'c38e182d-b6bc-4ceb-9cc4-c8ad36dbbda2', 'X-Request-Id': 'e86e61df-548b-4572-9c20-d534d2addad6', 'User-Agent': 'Ruby', 'Connection': 'close', 'Host': 'centos8-stream-eda.tanso.example.com:5000', 'Accept-Encoding': 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length': '386', 'Content-Type': 'application/json'}, 'endpoint': 'endpoint', 'received_at': '2023-04-13T08:11:00.856103Z', 'source': {'name': 'ansible.eda.webhook', 'type': 'ansible.eda.webhook'}, 'uuid': '0bef4d63-df1c-4be1-b1f1-4956d2e6529b'}}}]
2023-04-13 08:11:00,964 - ansible_rulebook.rule_set_runner - INFO - action args: {'name': 'update.yml'}
2023-04-13 08:11:00,964 - ansible_rulebook.builtin - INFO - running Ansible playbook: update.yml
2023-04-13 08:11:00,977 - ansible_rulebook.builtin - INFO - ruleset: Listen for events on a webhook, rule: check which content view was updated
2023-04-13 08:11:00,977 - ansible_rulebook.builtin - INFO - Calling Ansible runner

PLAY [foreman_dev] *************************************************************

TASK [Gathering Facts] *********************************************************
ok: [dev01.example.com]

TASK [Upgrade all packages] ****************************************************
changed: [dev01.example.com]

PLAY RECAP *********************************************************************
dev01.example.com          : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
2023-04-13 08:13:57,332 - ansible_rulebook.builtin - INFO - Ansible Runner Queue task cancelled
2023-04-13 08:13:57,333 - ansible_rulebook.builtin - INFO - Playbook rc: 0, status: successful
2023-04-13 08:13:57,333 - ansible_rulebook.rule_set_runner - INFO - Task action::run_playbook::Listen for events on a webhook::check which content view was updated finished, active actions 0
</code></pre></div></div>]]></content><author><name>Evgeni Golov</name></author><category term="foreman" /><category term="ansible" /><summary type="html"><![CDATA[Event-Driven Ansible is a new way of automation where your automation can dynamically react to events that happen in your environment. Today, we want to show you how you can integrate that with Foreman using the Foreman Webhooks plugin.]]></summary></entry><entry><title type="html">Using Personal Access Tokens with Ansible</title><link href="https://theforeman.org/2023/03/using-personal-access-tokens-with-ansible.html" rel="alternate" type="text/html" title="Using Personal Access Tokens with Ansible" /><published>2023-03-02T10:23:13+00:00</published><updated>2023-03-02T10:23:13+00:00</updated><id>https://theforeman.org/2023/03/using-personal-access-tokens-with-ansible</id><content type="html" xml:base="https://theforeman.org/2023/03/using-personal-access-tokens-with-ansible.html"><![CDATA[<p>When using Ansible to manage Foreman with the <a href="https://github.com/theforeman/foreman-ansible-modules">Foreman Ansible Modules</a>, we need to provide a username and a password for authentication.
But what happens if the user doesn’t have a password in Foreman, because external authentication (like LDAP or Kerberos) is used?</p>

<!--more-->

<p>In the case of LDAP we still can provide the LDAP password to Ansible, and things will work.
However, providing the LDAP password to Ansible also means that Ansible is now in the possession of a credential that can be used in other contexts than Foreman, which is something nobody really wants to do.
Some LDAP servers even require a kind of 2FA authentication, by requiring the password to be transferred as <code class="language-plaintext highlighter-rouge">&lt;password&gt;&lt;token&gt;</code> and thus the transferred password changes on each request.</p>

<p>Enter “<a href="https://en.wikipedia.org/wiki/Personal_access_token">Personal Access Tokens</a>” (PAT)! Foreman <a href="https://projects.theforeman.org/issues/21394">supports Personal Access Tokens since 1.17</a> and allows the use of PATs instead of the password when performing API requests. As Personal Access Tokens are stored and validated by Foreman, they can be used regardless of the requirements and constraints the “real” authentication method enforces.</p>

<p>To create a Personal Access Token, we go to the user’s profile</p>

<p><img src="/static/images/blog_images/2023-03-02-using-personal-access-tokens-with-ansible/01-my-profile.png" alt="Foreman menu showing the links to the user's profile" /></p>

<p>Select the “Personal Access Tokens” tab</p>

<p><img src="/static/images/blog_images/2023-03-02-using-personal-access-tokens-with-ansible/02-menu-pat.png" alt="Foreman user profile menu, Personal Access Tokens tab is selected" /></p>

<p>Click “Add Personal Access Token”</p>

<p><img src="/static/images/blog_images/2023-03-02-using-personal-access-tokens-with-ansible/03-add-pat.png" alt="Personal Access Token page, Add Personal Access Token button is selected" /></p>

<p>Fill out the form, the name is something that the token can be later be identified by, say “ansible” and the expiration date is optional</p>

<p><img src="/static/images/blog_images/2023-03-02-using-personal-access-tokens-with-ansible/04-pat-form.png" alt="Personal Access Token creation form, the name is filed in as &quot;ansible&quot;" /></p>

<p>Once the form is submitted, the newly created token is shown and can be used</p>

<p><img src="/static/images/blog_images/2023-03-02-using-personal-access-tokens-with-ansible/05-pat-success.png" alt="Personal Access Token page, newly created token is shown" /></p>

<p>Now the token can be used as the password in any Ansible playbook:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="pi">-</span> <span class="na">hosts</span><span class="pi">:</span> <span class="s">localhost</span>
  <span class="na">tasks</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">set instance title</span>
      <span class="na">theforeman.foreman.setting</span><span class="pi">:</span>
        <span class="na">server_url</span><span class="pi">:</span> <span class="s">https://foreman.example.com/</span>
        <span class="na">username</span><span class="pi">:</span> <span class="s">admin</span>
        <span class="na">password</span><span class="pi">:</span> <span class="s">hjYrjFXmRqi12uumRQPsbg</span>
        <span class="na">name</span><span class="pi">:</span> <span class="s">instance_title</span>
        <span class="na">value</span><span class="pi">:</span> <span class="s">the awesome and secure instance</span>
</code></pre></div></div>]]></content><author><name>Evgeni Golov</name></author><category term="foreman" /><category term="ansible" /><summary type="html"><![CDATA[When using Ansible to manage Foreman with the Foreman Ansible Modules, we need to provide a username and a password for authentication. But what happens if the user doesn’t have a password in Foreman, because external authentication (like LDAP or Kerberos) is used?]]></summary></entry><entry><title type="html">Foreman Community Newsletter (Jue 2022)</title><link href="https://theforeman.org/2022/06/foreman-community-newsletter-jue-2022.html" rel="alternate" type="text/html" title="Foreman Community Newsletter (Jue 2022)" /><published>2022-06-30T00:00:00+00:00</published><updated>2022-06-30T00:00:00+00:00</updated><id>https://theforeman.org/2022/06/foreman-community-newsletter-jue-2022</id><content type="html" xml:base="https://theforeman.org/2022/06/foreman-community-newsletter-jue-2022.html"><![CDATA[<p>50% through 2022 and through the Foreman 3.4 release. Here are the latest updates from around the Foreman community!</p>

<!--more-->

<h2 id="release-updates">Release updates</h2>

<h3 id="foreman-33-ga">Foreman 3.3 GA</h3>

<p>This month, Foreman 3.3 became generally available.
Upgrade to enjoy the latest features and bugfixes.
For more information see <a href="https://community.theforeman.org/t/foreman-3-3-0-ga-has-been-released/28989">Foreman 3.3.0 has been released!</a></p>

<h3 id="foreman-34-release-update">Foreman 3.4 release update</h3>

<p>We are halfway through the development phase for Foreman 3.4.</p>

<p><a href="https://community.theforeman.org/u/upadhyeammit">@upadhyeammit</a> gave us the latest update on this in the community demo. You can listen back here:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/6DPke5WZ9Ts?start=89" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h3 id="katello-45">Katello 4.5</h3>

<p>The Katello 4.5 release is imminent, expected to become GA during early next week (week starting July 3rd). You can keep up to date with the latest updates by keeping an eye on our <a href="https://community.theforeman.org/c/release-announcements/8">release announcements</a> on our community forum.</p>

<h2 id="debian-installations-and-foreman-maintain">Debian installations and foreman-maintain</h2>

<p>The <code class="language-plaintext highlighter-rouge">foreman-maintain</code> utility has been around for quite some time but only available to Foreman installations on Enterprise Linux. However, we have some good news. <a href="https://community.theforeman.org/u/upadhyeammit">@upadhyeammit</a> has been <a href="https://projects.theforeman.org/issues/34194">working away</a> behind the scenes to put together the different pieces to allow Debian and Ubuntu users to use <code class="language-plaintext highlighter-rouge">foreman-maintain</code>.</p>

<p>You can watch <a href="https://community.theforeman.org/u/upadhyeammit">@upadhyeammit</a> talk through his work and the benefits that <code class="language-plaintext highlighter-rouge">foreman-maintain</code> will bring for Foreman Debian and Ubuntu users in our latest demo:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/6DPke5WZ9Ts?start=129" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="foreman-on-el7-deprecation-updates">Foreman on El7 Deprecation updates</h2>

<p><a href="https://community.theforeman.org/u/ehelms">@ehelms</a> posted an update regarding the EL7</p>

<blockquote>
  <p>At this time we have dropped EL7 from our nightly testing pipelines. We are no longer generating EL7 nightly repositories nor testing installations or upgrade against EL7. We are continuing to work in this area to remove the nightly release repositories on EL7, as well as cleanup packaging to stop building all but client packages on EL7. Forklift has also been updated to drop EL7 as a nightly and development environment option.
Developers – this means that if you are using an EL7 based development environment, it is now out of date and will not be update-able - Please find time and move to an EL8 based setup. There is no in-place upgrade for development environments.</p>
</blockquote>

<p>For more information, see the <a href="https://community.theforeman.org/t/deprecation-plans-for-foreman-on-el7-debian-10-and-ubuntu-18-04/25008/20">Deprecation plans for Foreman on EL7, Debian 10 and Ubuntu 18.04</a> thread.</p>

<h2 id="do-you-append-domain-names-to-host-settings">Do you append domain names to host settings?</h2>

<p><a href="https://community.theforeman.org/u/Marek_Hulan">@Marek_Hulan</a> has put out a call to understand if there are use cases where appending domain names to host settings has been useful for Foreman users. Removing this might help simplify things, especially around Ansible workflows.</p>

<p>If you are using this setting (<strong>Append domain names to the host</strong> from <strong>Settings &gt; General</strong>), please <a href="https://community.theforeman.org/t/can-we-drop-the-append-domain-names-to-the-host-setting/29150">let us know</a> how and why this helps you.</p>

<h2 id="making-email-optional-for-foreman-user-accounts">Making email optional for Foreman user accounts?</h2>

<p>This month <a href="https://community.theforeman.org/u/nofaralfasi">@nofaralfasi</a> opened a discussion regarding user accounts and different requirements for email depending on whether you’re updating or creating a user in Foreman. She has proposed that we make adding a user email address optional in all scenarios.</p>

<p>For more information see <a href="https://community.theforeman.org/t/update-users-email-to-be-optional/29113">Update users email to be optional</a> and add your thoughts to the discussion, even if just to add a +1 to the suggestion.</p>

<h2 id="new-foreman-developer-guide">New Foreman developer guide</h2>

<p><a href="https://community.theforeman.org/u/nofaralfasi">@nofaralfasi</a> also created a new guide to help fellow Foreman developers install and get started with Foreman. She has an open PR with her work. Please test, and <a href="https://community.theforeman.org/t/adding-a-development-installation-guide-for-foreman/29142">let us know what you think</a>.</p>

<h2 id="community-demos">Community Demos</h2>

<p>We had two demos this month!</p>

<h4 id="demo-111">Demo #111</h4>

<iframe width="560" height="315" src="https://www.youtube.com/embed/1c2Rqa6By7I" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h4 id="demo-112">Demo #112</h4>

<iframe width="560" height="315" src="https://www.youtube.com/embed/6DPke5WZ9Ts" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="thank-you">Thank you!</h2>

<p>Thank you to everyone who asked and answered questions, opened issues, and made the Foreman community a vibrant place to be over the last month!</p>]]></content><author><name>Melanie Corr</name></author><category term="foreman" /><summary type="html"><![CDATA[50% through 2022 and through the Foreman 3.4 release. Here are the latest updates from around the Foreman community!]]></summary></entry><entry><title type="html">Foreman Community Newsletter (May 2022)</title><link href="https://theforeman.org/2022/05/foreman-community-newsletter-may-2022.html" rel="alternate" type="text/html" title="Foreman Community Newsletter (May 2022)" /><published>2022-05-30T00:00:00+00:00</published><updated>2022-05-30T00:00:00+00:00</updated><id>https://theforeman.org/2022/05/foreman-community-newsletter-may-2022</id><content type="html" xml:base="https://theforeman.org/2022/05/foreman-community-newsletter-may-2022.html"><![CDATA[<p>A news round up from around the Foreman community this last month!</p>

<!--more-->

<h2 id="foreman-33-rc-2">Foreman 3.3 RC 2</h2>

<p>The second release candidate for Foreman 3.3 has been released and is available for testing. If you use Foreman and would like to contribute to the project, installing and testing the release candidates is a great way to help out. Evaluating the release candidates is also a great way to familiarize yourself with changes in the upcoming release.</p>

<p>For more information about evaluating the 3.3 release candidate, see <a href="https://community.theforeman.org/t/foreman-3-3-0-rc2-is-ready-for-testing/28794?u=mcorr">Foreman 3.3.0 RC2 is ready for testing!</a></p>

<h2 id="ruby-25-deprecation-in-foreman-33">Ruby 2.5 deprecation in Foreman 3.3</h2>

<p>Ruby 2.5 will be deprecated as part of the release of Foreman 3.3 and removed with the release of Foreman 3.4.</p>

<p><a href="https://community.theforeman.org/u/evgeni">evgeni</a> has outlined the reasons behind the Ruby 2.5 deprecation and set out the timeline for this. For more information, check out <a href="https://community.theforeman.org/t/deprecation-of-ruby-2-5/28817">Deprecation of Ruby 2.5</a>.</p>

<h2 id="foreman-321">Foreman 3.2.1</h2>

<p>The first update to Foreman 3.2 was also released.
This release contains a number of bug fixes.</p>

<p>Update your Foreman 3.2 instance to enjoy all the latest fixes.</p>

<p>For more information, check out <a href="https://community.theforeman.org/t/foreman-3-2-1-has-been-released/28769">the release announcement</a>.</p>

<h2 id="313---final-update-to-the-31-series">3.1.3 - final update to the 3.1 series</h2>

<p>With the release of Foreman 3.3 in the offing, the 3.1.3 update will be the final update to 3.1. After 3.3 is released, the 3.1 version will no longer be supported. Consider updating to 3.2 today to ensure that you remain on an up-to-date Foreman version.</p>

<p>For more information, see <a href="https://community.theforeman.org/t/foreman-3-1-3-has-been-released/28710">Foreman 3.1.3 has been released!</a>.</p>

<h2 id="katello-45-update">Katello 4.5 update</h2>

<p>As part of our community demo, <a href="https://community.theforeman.org/u/cintrix84">cintrix84</a> updated us on the timeline and what we can expect as part of Katello 4.5:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yHmpHowebwY?start=235" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="upgrade-foreman-to-el-8">Upgrade Foreman to EL 8</h2>

<p><a href="https://community.theforeman.org/u/evgeni">evgeni</a> has been doing everything he can to highlight the importance of upgrading your Foreman instance from EL 7 to EL 8 as soon as possible.</p>

<p>On Foreman 3.2 and the upcoming release Foreman 3.3, you can perform this in-place. However, if you don’t upgrade to EL8 while using these versions of Foreman, you’ll have a much bigger job to do redeploying everything yourself.</p>

<p><a href="https://community.theforeman.org/u/evgeni">evgeni</a> came and demoed the upgrade process as part of the most recent community demo.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yHmpHowebwY?start=319" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>Documentation on this process is in progress and if you have any issues, please post to the community so that we can understand the issue and look for a solution.</p>

<h2 id="remote-execution-pull-provider-now-available-on-nightly">Remote Execution Pull Provider now available on nightly!</h2>

<p>From a user perspective, little will change with the remote execution workflow. However, behind the scenes, there have been some major changes that are now available on nightly and will hopefully make it in on time for the Foreman 3.3 release also.</p>

<p>In an effort to improve the way remote execution is handled, remote execution will take place via Pull MQTT rather than SSH.</p>

<p>For a comprehensive overview of what you can look forward to, let <a href="https://community.theforeman.org/u/aruzicka">aruzicka</a> walk you through the changes:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yHmpHowebwY?start=1587" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="katello-alternative-content-sources">Katello Alternative Content Sources</h2>

<p><a href="https://community.theforeman.org/u/iballou">iballou</a> has mentioned progress on Alternative Content Sources for Katello a few times over the past few months. You can watch him discussing this and providing a walkthrough of creating an alternative content source in the Foreman web UI and also with the Hammer CLI:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yHmpHowebwY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="save-the-date-for-osad-2022">Save the date for OSAD 2022</h2>

<p><a href="https://community.theforeman.org/u/maximilian">maximilian</a> added Open Source Automation Days (OSAD) dates to the Foreman calendar. Throughout the years, many Foreman community members have presented their work at OSAD. While the call for papers ends on May 31, save the date to enjoy the main conference either online or in Munich on <strong>October, 4th and 5th plus Workshops on October 6th 2022</strong></p>

<p>For more information, see <a href="https://community.theforeman.org/t/open-source-automation-days-2022/28462">Open Source Automation Days</a> Foreman calendar entry.</p>

<h2 id="foremankatello-performance-tuning-guide">Foreman/Katello Performance Tuning Guide</h2>

<p>Getting the most out of very large Foreman deployments might require some tuning. <a href="https://community.theforeman.org/u/maximilian">maximilian</a> has open sourced the Red Hat Satellite Performance Tuning source to create a guide that is useful for Foreman and Katello users. We need your contributions to make this guide useful and helpful to other community members so they can get the most out of their larger Foreman deployments. For more information, watch <a href="https://community.theforeman.org/u/maximilian">maximilian</a>’s presentation at the latest community demo:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yHmpHowebwY?start=4084" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="thank-you">Thank you!</h2>

<p>Thank you to everyone who asked and answered questions, opened issues, and made the Foreman community a vibrant place to be over the last month!</p>]]></content><author><name>Melanie Corr</name></author><category term="newsletter" /><summary type="html"><![CDATA[A news round up from around the Foreman community this last month!]]></summary></entry></feed>