<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.7.4">Jekyll</generator><link href="http://theforeman.org/feed.xml" rel="self" type="application/atom+xml" /><link href="http://theforeman.org/" rel="alternate" type="text/html" /><updated>2018-10-31T13:21:38+00:00</updated><id>http://theforeman.org/</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">Foreman Community Newsletter - September 2018</title><link href="http://theforeman.org/2018/09/foreman-community-newsletter-september-2018.html" rel="alternate" type="text/html" title="Foreman Community Newsletter - September 2018" /><published>2018-09-30T13:59:04+00:00</published><updated>2018-09-30T13:59:04+00:00</updated><id>http://theforeman.org/2018/09/foreman-community-newsletter---september-2018</id><content type="html" xml:base="http://theforeman.org/2018/09/foreman-community-newsletter-september-2018.html">&lt;h3 id=&quot;releases&quot;&gt;Releases&lt;/h3&gt;

&lt;p&gt;Since 1.19.0 went out &lt;a href=&quot;https://theforeman.org/2018/08/foreman-community-newsletter-august-2018.html&quot;&gt;right at the end of August&lt;/a&gt;, it’s a bit quiet
for releases just now. However, &lt;a href=&quot;https://community.theforeman.org/t/foreman-1-18-2-has-been-released/11033/2&quot;&gt;1.18.2&lt;/a&gt; has been released, containing
9 bug fixes for the 1.18 series. Do upgrade if you’re still on 1.18!&lt;/p&gt;

&lt;p&gt;Also, as mentioned in the previous newsletter, &lt;a href=&quot;https://community.theforeman.org/t/katello-3-8-0-released/11014/2&quot;&gt;Katello 3.8.0&lt;/a&gt; was
indeed close to release - in fact, it was made available on Sep 6th! With ~50
improvements, and of course compatibility with Foreman 1.19, you’ll want to get
that upgrade in as well.&lt;/p&gt;

&lt;p&gt;As ever, many thanks to the contributors to these releases - coders, RC testers,
documentation writers, and bug/feature reporters. Foreman wouldn’t be what it
is without you! If you do find issues with, please do &lt;a href=&quot;https://projects.theforeman.org/&quot;&gt;report them!&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;critical-security-issue-in-remote-execution-plugin&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/t/critical-security-issue-in-foreman-remote-execution-and-foreman-ansible/11184&quot;&gt;Critical Security issue in Remote Execution plugin&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;If you use the Remote Execution plugin, you’ll want to make sure you’ve seen
&lt;a href=&quot;https://access.redhat.com/security/cve/cve-2018-14643&quot;&gt;CVE-2018-14643&lt;/a&gt; and the associated &lt;a href=&quot;https://community.theforeman.org/t/critical-security-issue-in-foreman-remote-execution-and-foreman-ansible/11184&quot;&gt;updates on the forum&lt;/a&gt;.
This is an &lt;strong&gt;arbitrary code execution&lt;/strong&gt; flaw on hosts managed by Foreman, so
please do take this seriously.&lt;/p&gt;

&lt;p&gt;Updates are available for the affected packages from Foreman 1.15+, see the
forum post for details.&lt;/p&gt;

&lt;h3 id=&quot;rfcs-for-comment&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/development/rfcs&quot;&gt;RFCs for comment&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;As usual, I like to call out some RFCs for wider attention. Here’s this month’s selection:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/rfc-simple-callback-system-for-users/11242/4&quot;&gt;Replacing Foreman-hooks with something built in to core&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/rfc-add-managed-into-interface-overview/11230/3&quot;&gt;Adding a ‘Managed’ flag to the NIC overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/rfc-add-puma-as-the-default-smart-proxy-server/10975/36&quot;&gt;Using Puma as the default Smart-proxy web server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, I’ll again mention the large set of RFCs regarding our approach to
making Foreman able to run in a (set of) container(s) - lots of good discussion
is happening here, but more voices are welcome. Start with the
&lt;a href=&quot;https://community.theforeman.org/t/containerizing-the-foreman-ecosystem/10948&quot;&gt;overview&lt;/a&gt;
and then dive into the details RFCs from there.&lt;/p&gt;

&lt;h3 id=&quot;new-community-stats-dashboard&quot;&gt;&lt;a href=&quot;https://stats.theforeman.org&quot;&gt;New Community stats dashboard&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;One of my long-term to-do items as community lead has been to create a metrics
dashboard that we can use to track various things that matter to us as a
community. That’s been on the back burner for a while, but I’ve now had time to
get started on it. You can find the current version &lt;a href=&quot;https://stats.theforeman.org&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The current version is somewhat alpha, and only covers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Total Open / Total Closed / Net Open bug (all projects or for one project)&lt;/li&gt;
  &lt;li&gt;Open bugs by project / category / triage status&lt;/li&gt;
  &lt;li&gt;Community demographics (age of Redmine account for people who created/commented on a bug in the last 6 months)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Already this helps us to see the state of the community, track it’s evolution,
and hopefully focus on certain bug categories. I have more charts and
interactive tools in development - if you know the “R” language and would like
to help, I’m reachable &lt;a href=&quot;https://community.theforeman.org/u/gwmngilfen&quot;&gt;here&lt;/a&gt; :)&lt;/p&gt;

&lt;h3 id=&quot;hacktoberfest-via-digitalocean-and-github&quot;&gt;Hacktoberfest (via DigitalOcean and GitHub)&lt;/h3&gt;

&lt;p&gt;If you’re looking for that extra incentive to get you contributing, it seems
that DigitalOcean &amp;amp; GitHub are again running a Hacktoberfest Event. You can get
the full details &lt;a href=&quot;https://hacktoberfest.digitalocean.com/&quot;&gt;over there&lt;/a&gt; but
essentially, 5 separate (and not spammy) PRs to &lt;em&gt;any&lt;/em&gt; GitHub repos will count. So,
that means our repos too :). It appears they have 50,000 t-shirts to give away
to those who manage 5 PRs during the month of October. Get contributing!&lt;/p&gt;

&lt;h3 id=&quot;upcoming-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/calendar&quot;&gt;Upcoming Events&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;All Foreman events are available via &lt;a href=&quot;https://community.theforeman.org/calendar&quot;&gt;the forum
calendar&lt;/a&gt; - hit the Subscribe button
(which will give you an ICS link). You can also use the Add To Calendar button
on specific events if you don’t wish to import the whole thing.&lt;/p&gt;

&lt;p&gt;Future community demos will now be created much further in advance, so you
should be able to keep up with upcoming demos there.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-51&quot;&gt;Community Demo #51&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the usual goodness from the community, rounded up and presented for your viewing pleasure.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/open-source-automation-day/10318&quot;&gt;Open Source Automation Day&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On October 16, 2018 the Open Source Automation Day of ATIX AG will take place
in the Mercedes-Benz Tower in Munich.&lt;/p&gt;

&lt;p&gt;At one of Munich’s largest open source conferences we offer you an appealing
program with lectures, live demos, talks and discussions. We focus on a mix of
business and technical topics. The focus here is on possibilities for the
simple and automatic operation of data centres. A special focus is on the
latest technologies.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-techday-after-osad-event/10979&quot;&gt;Foreman TechDay - after OSAD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We at ATIX think, that it’s a good time to hold a Foreman TechDay the day after
the OSAD conference in Munich. The Foreman TechDay is targeted at software
developers who already have knowledge of software development in Foreman or
similar solutions like Ansible module development. Feel free to add suggestions
for topics!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/open-source-summit-eu-2018-edinburgh-october/10081&quot;&gt;Open Source Summit, Europe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll be at OSS-EU on Oct 22-24th - I have two talks there in the community
track (which aren’t really about Foreman, but about community work in general),
and I’ll spend a lot of my time hanging out at the Red Hat stand. Come find me
if you want to chat! :)&lt;/p&gt;

&lt;h4 id=&quot;past-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/latest&quot;&gt;Past Events&lt;/a&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-50&quot;&gt;Community Demo #50&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hammer, Ansible variables, content changes, and a quick overview of the new
stats dashboard. Click the link to see the full agenda!&lt;/p&gt;

&lt;h3 id=&quot;plugin-news&quot;&gt;Plugin news&lt;/h3&gt;

&lt;p&gt;New Plugins:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ianballou/foreman_m2&quot;&gt;Foreman M2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integration of the M2 (Malleable Metal as a Service) with Foreman. Check out the
&lt;a href=&quot;https://community.theforeman.org/t/rfc-bare-metal-provisioning-with-m2-in-foreman/10061&quot;&gt;forum post&lt;/a&gt;
for more details.&lt;/p&gt;

&lt;p&gt;Updated plugins:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_ansible&quot;&gt;foreman_ansible&lt;/a&gt; updated to 2.2.9&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_chef&quot;&gt;foreman_chef&lt;/a&gt; updated to 0.8.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_openscap&quot;&gt;foreman_openscap&lt;/a&gt; updated to 0.10.3&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_remote_execution&quot;&gt;foreman_remote_execution&lt;/a&gt; updated to 1.6.3&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_userdata&quot;&gt;foreman_userdata&lt;/a&gt;to 0.1.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman_tasks&quot;&gt;hammer_cli_foreman_tasks&lt;/a&gt; updated to 0.0.13&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman_templates&quot;&gt;hammer_cli_foreman_templates&lt;/a&gt; updated to 0.1.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Katello/hammer-cli-katello&quot;&gt;hammer_cli_katello&lt;/a&gt; updated to 0.14.1&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;

&lt;p&gt;Thanks to everyone who contributes to the Foreman community - patches, plugins,
testing, bug reports, translations, interviews, presentations, meetups and
everything else. Your efforts are very much appreciated!&lt;/p&gt;</content><author><name>Greg Sutcliffe</name><uri>gwmngilfen</uri></author><category term="foreman" /><category term="newsletter" /><category term="community" /><summary type="html">1.18.2 and Katello 3.8, a CVE in Remote execution, new stats dashboard, and Hacktoberfest!</summary></entry><entry><title type="html">Foreman Community Newsletter - August 2018</title><link href="http://theforeman.org/2018/08/foreman-community-newsletter-august-2018.html" rel="alternate" type="text/html" title="Foreman Community Newsletter - August 2018" /><published>2018-08-31T15:17:00+00:00</published><updated>2018-08-31T15:17:00+00:00</updated><id>http://theforeman.org/2018/08/foreman-community-newsletter---august-2018</id><content type="html" xml:base="http://theforeman.org/2018/08/foreman-community-newsletter-august-2018.html">&lt;h3 id=&quot;releases-for-everyone&quot;&gt;Releases for everyone!&lt;/h3&gt;

&lt;p&gt;We’ve had a lot of releases this month, so I’ll group them all together. We’ve released:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-1-19-0-has-been-released/10945&quot;&gt;Foreman 1.19.0&lt;/a&gt; was released on the very last day of August,
featuring support for Ubuntu Bionic, syslog logging, reporting failed builds,
and more.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-1-17-4-has-been-released/10939&quot;&gt;1.17.3 and 1.17.4&lt;/a&gt; bug fix releases. If you are still on 1.17, be
sure to upgrade to 1.17.4 before upgrading to 1.18!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/katello-3-8-rc3-available-for-testing/10874/2&quot;&gt;Katello 3.8 RC 2 &amp;amp; 3&lt;/a&gt; - do give the RC a try and let us know how you find it :)&lt;/li&gt;
  &lt;li&gt;Katello 3.8 appears to be in the release process &lt;a href=&quot;https://github.com/theforeman/foreman-packaging/commit/473f1d9c4030112be8420f224d54359a83a9c9e0&quot;&gt;right now&lt;/a&gt; so stay tuned for that!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the release of 1.19.0, this marks 1.17.X as now unmaintained - 1.17.4 will
be the last release in the 1.17 series. Please do upgrade as soon as you can.&lt;/p&gt;

&lt;p&gt;As ever, many thanks to the contributors to these releases - coders, RC testers,
documentation writers, and bug/feature reporters. Foreman wouldn’t be what it
is without you! If you do find issues with, please do [report them!][issues]&lt;/p&gt;

&lt;p&gt;Big thanks also to Ondrej, Ewoud, and Tomer for their effort in bringing these
releases out at this rate, there’s been a &lt;em&gt;lot&lt;/em&gt; of work behind the scenes.&lt;/p&gt;

&lt;h3 id=&quot;new-rfcs-for-container-work&quot;&gt;New RFCs for container work&lt;/h3&gt;

&lt;p&gt;In the &lt;a href=&quot;https://www.theforeman.org/2018/06/2018-foreman-survey-analysis.html&quot;&gt;survey
analysis&lt;/a&gt;
I posted earlier this year, I called attention to the idea of supporting
Foreman being run in a container, and that more would come on this later. That
time is now :)&lt;/p&gt;

&lt;p&gt;Eric has spent a lot of time working through the implications of this, and has
now posted a set of RFCs to the Development board for review. There’s a &lt;em&gt;lot&lt;/em&gt;
to read here, so it’s broken down into multiple posts. You can get the
top-level over on &lt;a href=&quot;https://community.theforeman.org/t/containerizing-the-foreman-ecosystem/10948&quot;&gt;this forum
post&lt;/a&gt;
and then dive into details from there.&lt;/p&gt;

&lt;p&gt;I’d recommend for &lt;em&gt;anyone&lt;/em&gt; with an interest in the future direction of Foreman
to read over these, and give their thoughts on any part of it which interests
you. Thanks!&lt;/p&gt;

&lt;h3 id=&quot;foreman-at-froscon&quot;&gt;Foreman at FrOSCon&lt;/h3&gt;

&lt;p&gt;Thanks to the awesome work of Matthias, Bernhard, and the rest of the ATIX
team, Foreman had a community presence at FrOSCon at the University of Applied
Sciences Bonn-Rhein-Sieg this year. Whilst I didn’t get to go myself, I heard
that it was a great event, lots of traffic to the booth, and good discussions
with other collaborators.&lt;/p&gt;

&lt;p&gt;You can read all about it on &lt;a href=&quot;https://www.atix.de/atix-froscon13/#English&quot;&gt;the ATIX blog
post&lt;/a&gt;! Thanks as always to you all
for your support!&lt;/p&gt;

&lt;h3 id=&quot;redmine-upgrade-continued&quot;&gt;Redmine upgrade (continued)&lt;/h3&gt;

&lt;p&gt;Whilst the Redmine &lt;em&gt;upgrade&lt;/em&gt; was completed last month, Ewoud and I have
continued to improve it. This month we cleaned up the project hierarchy, moving
plugins to their own top-level project, and keeping just “core” projects
grouped under Foreman. The main reason for this is so that we can re-enable
Version sharing without cluttering the bug tracker.&lt;/p&gt;

&lt;p&gt;A consequence of this affect the &lt;em&gt;roles&lt;/em&gt; that users have on each project. If
you had Developer or Manager roles on a project, then you should refer to &lt;a href=&quot;https://community.theforeman.org/t/action-needed-redmine-permissions-cleanup/10826&quot;&gt;this
post&lt;/a&gt;
for instructions on what to check.&lt;/p&gt;

&lt;h3 id=&quot;upcoming-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/calendar&quot;&gt;Upcoming Events&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The Foreman Community has now fully embraced Discourse as the source of its
event data - if you’ve been using the old &lt;code class=&quot;highlighter-rouge&quot;&gt;/events/all.ics&lt;/code&gt; in your own
calendar, you’ll need to head over to &lt;a href=&quot;https://community.theforeman.org/calendar&quot;&gt;the forum
calendar&lt;/a&gt; and hit the Subscribe
button (which will give you an ICS link). You can also use the Add To Calendar
button on specific events if you don’t wish to import the whole thing.&lt;/p&gt;

&lt;p&gt;Future community demos will now be created much further in advance, so you
should be able to keep up with upcoming demos there.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-50/10227&quot;&gt;Community Demo #50&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the usual goodness from the community, rounded up and presented for your viewing pleasure.&lt;/p&gt;

&lt;h4 id=&quot;past-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/latest&quot;&gt;Past Events&lt;/a&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-48/9826&quot;&gt;Community Demo #48&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A short demo, with Docker, dev changes, an analysis of the impact Discourse has
had, and some chat about how to improve our docs.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-49/10109&quot;&gt;Community Demo #49&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A busy and Katello-centric demo containing lots of new content changes. Also
seeding and Bash completion in Hammer!&lt;/p&gt;

&lt;h3 id=&quot;plugin-news&quot;&gt;Plugin news&lt;/h3&gt;

&lt;p&gt;Updated plugins:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_ansible&quot;&gt;foreman_ansible&lt;/a&gt; updated to 2.2.6&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_discovery&quot;&gt;foreman_discovery&lt;/a&gt; updated to 13.0.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_host_extra_validator&quot;&gt;foreman_host_extra_validator&lt;/a&gt; updated to 0.1.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_remote_execution&quot;&gt;foreman_remote_execution&lt;/a&gt; updated to 1.6.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ATIX-AG/foreman_scc_manager&quot;&gt;foreman_scc_manager&lt;/a&gt;to 1.4.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_tasks&quot;&gt;foreman_tasks&lt;/a&gt; updated to 0.14.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman&quot;&gt;hammer_cli_foreman&lt;/a&gt; updated to 0.14.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli&quot;&gt;hammer_cli&lt;/a&gt; updated to 0.14.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Katello/katello-host-tools&quot;&gt;katello_host_tools&lt;/a&gt; updated to 3.3.5&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/smart_proxy_omaha&quot;&gt;smart_proxy_omaha&lt;/a&gt; updated to 0.0.5&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;

&lt;p&gt;Thanks to everyone who contributes to the Foreman community - patches, plugins,
testing, bug reports, translations, interviews, presentations, meetups and
everything else. Your efforts are very much appreciated!&lt;/p&gt;</content><author><name>Greg Sutcliffe</name><uri>gwmngilfen</uri></author><category term="foreman" /><category term="newsletter" /><category term="community" /><summary type="html">New releases! Oh, so many releases....</summary></entry><entry><title type="html">Deploying ESXi through Foreman</title><link href="http://theforeman.org/2018/08/deploying-esxi-through-foreman.html" rel="alternate" type="text/html" title="Deploying ESXi through Foreman" /><published>2018-08-09T14:25:45+00:00</published><updated>2018-08-09T14:25:45+00:00</updated><id>http://theforeman.org/2018/08/deploying-esxi-through-foreman</id><content type="html" xml:base="http://theforeman.org/2018/08/deploying-esxi-through-foreman.html">&lt;p&gt;At the time of writing this (Foreman v1.18), ESXi deployment through Foreman is not supported natively. The problem is exacerbated by the fact that the ESXi Legacy BIOS bootloader depends on an older Syslinux (v3.86) and &lt;a href=&quot;https://communities.vmware.com/thread/463818?start=15&amp;amp;tstart=0&quot;&gt;GRUB2 not being able to chainload the ESXi EFI bootloader&lt;/a&gt;. However there are &lt;a href=&quot;http://blog.reversion.org/sysadmin/deploying-esxi-with-satellite-6/&quot;&gt;quite&lt;/a&gt; &lt;a href=&quot;http://www.c0t0d0s0.de/esxwithforeman/esxwithforeman.html&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;https://beryju.org/en/blog/getting-started-foreman-part-3&quot;&gt;few&lt;/a&gt; articles on the Internet that have attempted to work around these issues.&lt;br /&gt;
This post is an attempt to bring all the information together in one place, simplify the process and most importantly, support both Legacy BIOS and UEFI modes of installation.&lt;br /&gt;
Huge thanks to the foreman developers for helping me out whenever I was stuck.&lt;/p&gt;

&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;A fully working Foreman instance. Follow the &lt;a href=&quot;https://theforeman.org/manuals/latest/index.html#3.InstallingForeman&quot;&gt;manual&lt;/a&gt; to install Foreman. After installation, please configure Foreman so that a Linux OS (for e.g. Centos) can be deployed successfully through Foreman.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Please make sure the Bootfile Handoff section in &lt;code class=&quot;highlighter-rouge&quot;&gt;dhcpd.conf&lt;/code&gt; looks like this:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  # Bootfile Handoff
  next-server 127.0.0.1;
  option architecture code 93 = unsigned integer 16 ;
  if option architecture = 00:06 {
    filename &quot;grub2/bootia32.efi&quot;;
  } elsif option architecture = 00:07 {
    filename &quot;grub2/bootx64.efi&quot;;
  } elsif option architecture = 00:09 {
    filename &quot;grub2/bootx64.efi&quot;;
  } else {
    filename &quot;pxelinux.0&quot;;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_hooks&quot;&gt;Foreman-Hooks&lt;/a&gt;. Run the following command to install:&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;foreman-installer --enable-foreman-plugin-hooks&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/3.xx/syslinux-3.86.tar.gz&quot;&gt;Syslinux version 3.86&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;An &lt;a href=&quot;https://my.vmware.com/en/group/vmware/evalcenter&quot;&gt;ESXi ISO&lt;/a&gt;. For this demo we will use &lt;code class=&quot;highlighter-rouge&quot;&gt;VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso&lt;/code&gt; but the same process will work on any version of ESXi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: This demo is run on a Ubuntu system. The paths may be different for other OSes. Please refer to the documentation for details.&lt;/p&gt;

&lt;h3 id=&quot;1-create-an-entry-for-the-esxi-os-in-foreman&quot;&gt;1: Create an entry for the ESXi OS in Foreman&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;1.1: Create the OS Medium&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Open https://{foreman-url}/media and click on &lt;strong&gt;Create Medium&lt;/strong&gt;.&lt;br /&gt;
  Now create a dummy entry for ESXi since each OS entry in Foreman needs an installation media.
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/dummy_esxi_media.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.2: Create the OS&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Open https://{foreman-url}/operatingsystems and click on &lt;strong&gt;Create Operating System&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Under Operating System, enter the following:&lt;br /&gt;
Name            -  ESXi-6.7.0-8169922 (ESXi-{&lt;strong&gt;OS Version&lt;/strong&gt;}-{&lt;strong&gt;Build Number&lt;/strong&gt;})&lt;br /&gt;
Major version   -  6&lt;br /&gt;
Minor version   -  7&lt;br /&gt;
Family          -  Redhat&lt;br /&gt;
Root pass hash  -  &lt;a href=&quot;https://www.virtuallyghetto.com/2018/05/quick-tip-what-hashing-algorithm-is-supported-for-esxi-kickstart-password.html&quot;&gt;SHA512&lt;/a&gt;&lt;br /&gt;
Architectures   -  x86_64
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/new_esxi_os.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Partition Table - Kickstart default&lt;br /&gt;
Note: We are using Kickstart default for the sake of simplicity. The actual partitioning will be controlled from the kickstart file. It is also possible to create a new ptable for ESXi and use it here.
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/new_esxi_os_ptable.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Installation Media - Select the dummy media created above
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/new_esxi_os_media.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Press Submit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.3: Create provisioning templates&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;1.3.1:&lt;/strong&gt; Create the PXELinux template
    &lt;ul&gt;
      &lt;li&gt;Open https://{foreman-url}/templates/provisioning_templates and click on &lt;strong&gt;Create Template&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;Name - ESXi-6.7.0-8169922&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Template contents:&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DEFAULT ESXi
NOHALT 1
LABEL ESXi
KERNEL ../boot/ESXi-6.7.0-8169922/mboot.c32
APPEND -c ../boot-ESXi-6.7.0-8169922.cfg
IPAPPEND 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/esxi_pxelinux_template_new.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;

    &lt;p&gt;Note: The &lt;strong&gt;KERNEL&lt;/strong&gt; and &lt;strong&gt;APPEND&lt;/strong&gt; lines start with “../”. I will explain why in Section 2.4. These values will be used when we actually mount the ISO image.&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;Template Type - &lt;strong&gt;PXELinux Template&lt;/strong&gt;
        &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/esxi_pxelinux_template_new_type.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Template Association - Select &lt;strong&gt;“ESXi 6.7 Build 8169922”&lt;/strong&gt;
        &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/esxi_pxelinux_template_new_assn.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Click Submit&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;1.3.2:&lt;/strong&gt; Create the Kickstart Template
    &lt;ul&gt;
      &lt;li&gt;Click on &lt;strong&gt;Create Template&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;Name - ESXi Minimal Kickstart&lt;/li&gt;
      &lt;li&gt;A sample template:
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vmaccepteula
keyboard 'US Default'
reboot
rootpw --iscrypted &amp;lt;%= root_pass %&amp;gt;
install --firstdisk --overwritevmfs --novmfsondisk

# Set the network to DHCP on the first network adapter
network --bootproto=dhcp --device=&amp;lt;%= @host.mac %&amp;gt;

%post --interpreter=busybox
# Add temporary DNS resolution so the foreman call works
echo &quot;nameserver &amp;lt;%= @host.subnet.dns_primary %&amp;gt;&quot; &amp;gt;&amp;gt; /etc/resolv.conf

# Inform Foreman that we are done.
wget -O /dev/null &amp;lt;%= foreman_url('built') %&amp;gt;
echo &quot;Done with Foreman call&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;Template Type - &lt;strong&gt;Provisioning template&lt;/strong&gt;
        &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/esxi_ks_template_new_type.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Template Association - Select &lt;strong&gt;“ESXi 6.7 Build 8169922”&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;Click Submit&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.4: Set default provisioning templates&lt;/strong&gt;&lt;br /&gt;
  Now that the templates are created, we need to set those as default.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Navigate to https://{foreman-url}/operatingsystems and click on the newly created ESXi OS &lt;strong&gt;“ESXi 6.7 Build 8169922”&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Open the “Templates” tab&lt;/li&gt;
  &lt;li&gt;Select the newly created provisioning templates from the drop down boxes and press Submit.
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/os_default_templates.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-esxi-installation-in-legacy-bios-mode&quot;&gt;2: ESXi installation in Legacy BIOS mode&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;The ESXi PXELinux mboot.c32 module only supports syslinux bootloader (pxelinux.0) version 3.86. You may replace the newer pxelinux.0 file that comes with the default Foreman installation with pxelinux.0 v3.86 but then you might face issues with newer OSes. So we will use a different approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.1: Prepare the bootloader&lt;/strong&gt;&lt;br /&gt;
We will create a new directory under the tftp root directory (typically &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/lib/tftpboot&lt;/code&gt;) and place the syslinux v3.86 pxelinux.0 along with the c32 modules there.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /tmp/

  wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/3.xx/syslinux-3.86.tar.gz

  &lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;xvf syslinux-3.86.tar.gz

  mkdir /var/lib/tftpboot/syslinux386

  cp syslinux-3.86/core/pxelinux.0 /var/lib/tftpboot/syslinux386/

  find syslinux-3.86/com32/ &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\*&lt;/span&gt;.c32 &lt;span class=&quot;nt&quot;&gt;-exec&lt;/span&gt; cp &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; /var/lib/tftpboot/syslinux386 &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# Create a symlink to the default pxelinux.cfg directory inside new directory&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/lib/tftpboot/

  ln &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; ../pxelinux.cfg syslinux386/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2.2: Create the bootloader entry in Foreman&lt;/strong&gt;&lt;br /&gt;
Now comes the interesting part. We will create a new PXELoader entry in Foreman for &lt;code class=&quot;highlighter-rouge&quot;&gt;pxelinux-3.86.0&lt;/code&gt;. Huge thanks to Lukáš Zapletal for &lt;a href=&quot;https://community.theforeman.org/t/edit-dhcpd-leases-through-a-foreman-hook-script/9957/2&quot;&gt;pointing this out&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;2.2.1:&lt;/strong&gt; Edit the file -   &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/foreman/app/models/concerns/pxe_loader_support.rb&lt;/code&gt;
    &lt;pre&gt;&lt;code&gt;
def all_loaders_map(precision = 'x64')
  {
    &quot;None&quot; =&amp;gt; &quot;&quot;,
    &quot;PXELinux BIOS&quot; =&amp;gt; &quot;pxelinux.0&quot;,
    &quot;PXELinux UEFI&quot; =&amp;gt; &quot;pxelinux.efi&quot;,
    &lt;b&gt;&quot;PXELinux Alt BIOS&quot; =&amp;gt; &quot;syslinux386/pxelinux.0&quot;,&lt;/b&gt; # Add this line
    ...
&amp;lt;/pre&amp;gt;&lt;/code&gt;

&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;2.2.2:&lt;/strong&gt; Restart httpd/apache2 for the changes to be reflected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.3: Mount the ESXi ISO&lt;/strong&gt;&lt;br /&gt;
We will mount the ESXi ISO under &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/lib/tftpboot/boot/ESXi-6.7.0-8169922&lt;/code&gt;. Note that this path corresponds to the &lt;strong&gt;KERNEL&lt;/strong&gt; entry in the PXELinux template.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/lib/tftpboot/

  mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; boot/ESXi-6.7.0-8169922

  mount ~/Desktop/VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso boot/ESXi-6.7.0-8169922
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2.4: Edit boot.cfg&lt;/strong&gt;&lt;br /&gt;
Copy the boot.cfg file from the mountpoint to tftproot and edit it to add a prefix to the ISO mountpoint. Make sure to use the same filename as the one specified in the &lt;strong&gt;APPEND&lt;/strong&gt; line of the PXELinux template.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/lib/tftpboot/

  cp boot/ESXi-6.7.0-8169922/boot.cfg boot-ESXi-6.7.0-8169922.cfg

  sed &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s#/##g&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;3s#^#prefix=../boot/ESXi-6.7.0-8169922&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; boot-ESXi-6.7.0-8169922.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Since the host boots into &lt;code class=&quot;highlighter-rouge&quot;&gt;syslinux386/pxelinux.0&lt;/code&gt;, the TFTP root dir will be set to &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/lib/tftpboot/syslinux386&lt;/code&gt;. So all paths need to be relative to this path. This is why all paths need to be prefixed with “../”.&lt;/li&gt;
  &lt;li&gt;Instead of mounting the ISO, you can also extract the ISO contents to the directory and edit the boot.cfg directly inside that directory. Remember to change the PXELinux template accordingly. I chose this approach because it is a tad cleaner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we are ready to deploy this OS on to a host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.5:&lt;/strong&gt; Open https://{foreman-url}/hosts/ and edit the host on which you want to deploy ESXi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.6:&lt;/strong&gt; Under the ‘Operating System’ tab, select the following values:&lt;/p&gt;

&lt;p&gt;Operating System : ESXi 6.7 Build 8169922&lt;br /&gt;
  Media : ESXi Dummy&lt;br /&gt;
  Partition table: Kickstart default&lt;br /&gt;
  PXE Loader : PXELinux Alt BIOS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.7:&lt;/strong&gt; Press ‘Resolve’ beside Provisioning templates and you should see the ESXi PXELinux and Kickstart templates.&lt;/p&gt;
&lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
    &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/edit_host_legacy_bios.png&quot; width=&quot;400&quot; /&gt;
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.8:&lt;/strong&gt; Press ‘Build’ and reboot the host to PXE. If all goes well, you should see ESXi installer load up and perform an automated installation.&lt;/p&gt;
&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
    &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/esxi_installer_loading.png&quot; width=&quot;400&quot; /&gt;
  &lt;/p&gt;

&lt;p&gt;Once installation is complete, the host will reboot to PXE and will be presented with the default PXE menu.&lt;/p&gt;
&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/localboot.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;Upon timeout, it will attempt a Localboot and boot to ESXi.&lt;/p&gt;

&lt;h3 id=&quot;3-esxi-installation-in-uefi-mode&quot;&gt;&lt;strong&gt;3:&lt;/strong&gt; ESXi installation in UEFI mode&lt;/h3&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.1: Prepare the bootloader&lt;/strong&gt;&lt;br /&gt;
In UEFI mode the bootloader is &lt;code class=&quot;highlighter-rouge&quot;&gt;mboot.efi&lt;/code&gt; which is just a renamed version of &lt;code class=&quot;highlighter-rouge&quot;&gt;efi/boot/bootx64.efi&lt;/code&gt; from the ESXi ISO image. The same mboot.efi can be used for booting different ESXi versions but it is recommended to use the latest one. &lt;br /&gt;
Let’s create the bootloader.&lt;/p&gt;

    &lt;p&gt;Assuming the ESXi ISO is mounted under &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/lib/tftpboot/boot/ESXi-6.7.0-8169922&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /var/lib/tftpboot/boot/ESXi-6.7.0-8169922/efi/boot/bootx64.efi /var/lib/tftpboot/mboot.efi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;3.2: Create the bootloader entry in Foreman&lt;/strong&gt;&lt;br /&gt;
Now we have to create an entry for this bootloader in the Foreman UI just like we did in Legacy BIOS mode.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Edit the file:   &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/foreman/app/models/concerns/pxe_loader_support.rb&lt;/code&gt;&lt;/p&gt;

        &lt;pre&gt;&lt;code&gt;
def all_loaders_map(precision = 'x64')
  {
    &quot;None&quot; =&amp;gt; &quot;&quot;,
    &quot;PXELinux BIOS&quot; =&amp;gt; &quot;pxelinux.0&quot;,
    &quot;PXELinux UEFI&quot; =&amp;gt; &quot;pxelinux.efi&quot;,
    &quot;PXELinux Alt BIOS&quot; =&amp;gt; &quot;syslinux386/pxelinux.0&quot;,
    &lt;b&gt;&quot;mboot UEFI&quot; =&amp;gt; &quot;mboot.efi&quot;,&lt;/b&gt; # Add this line
    ...
&amp;lt;/pre&amp;gt;&lt;/code&gt;

&lt;/pre&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Restart httpd/apache2 to register the changes&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.3:&lt;/strong&gt; Once the host loads mboot.efi, it will look for a boot.cfg file under tftproot/01-{MAC address of host}. Once it is located, the installer loads up and performs the installation. So each time we need to deploy ESXi in UEFI mode we need to create this directory and copy over the boot.cfg file. This can be quite tedious when we are deploying at scale.&lt;/p&gt;

    &lt;p&gt;Here is where Foreman-Hooks comes in handy.
From the &lt;a href=&quot;https://github.com/theforeman/foreman_hooks#foreman_hooks&quot;&gt;Foreman-Hooks Github repo&lt;/a&gt;:&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;Foreman Hooks allows you to trigger scripts and commands on the Foreman server at any point in an object’s lifecycle in Foreman. This lets you run scripts when a host is created, or finishes provisioning etc.&lt;/p&gt;
    &lt;/blockquote&gt;

    &lt;p&gt;Once the host is set to build mode, the MAC directory along with the boot.cfg file should be created automatically.  For this we need to hook into the after_build event.&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /usr/share/foreman/config/hooks

mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; host/managed/after_build

&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;host/managed/after_build

&lt;span class=&quot;c&quot;&gt;# Symlink the hook_functions file.&lt;/span&gt;
ln &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /usr/share/foreman/vendor/ruby/2.3.0/gems/foreman_hooks-0.3.14/examples/bash/hook_functions.sh &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Now create the script&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOT&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &amp;gt;&amp;gt; /host/managed/after_build/01-prep-esxi-uefimode.sh
#!/bin/bash

# Import the functions
. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;/hook_functions.sh

# event name (create, before_destroy etc.)
# orchestration hooks must obey this to support rollbacks (create/update/destroy)
event=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOOK_EVENT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

# to_s representation of the object, e.g. host's fqdn
object=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOOK_OBJECT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

exec &amp;gt;&amp;gt; /tmp/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;.log
exec 2&amp;gt;&amp;amp;1

system_name=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.name&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; # Yes it is host.host.&amp;lt;attribute&amp;gt; instead of host.&amp;lt;attribute&amp;gt; due to this open issue: https://github.com/theforeman/foreman_hooks/issues/46
system_mac=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.mac&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_pxe_loader=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.pxe_loader&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_operatingsystem_name=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.operatingsystem_name&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

echo &quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;: received &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; on &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
echo &quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_operatingsystem_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_pxe_loader&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
if [[ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_operatingsystem_name&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; == ESXi* ]] &amp;amp;&amp;amp; [[ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_pxe_loader&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; == &quot;mboot UEFI&quot; ]]; then
    echo &quot;ESXi UEFI mode detected&quot;

    # Create MAC Address directory under tftproot after substituting : with -
    macdir=&quot;01-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;//&lt;/span&gt;:/-&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
    mkdir -p /var/lib/tftpboot/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;macdir&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

    # Copy the boot.cfg file from the ISO mountpoint to tftproot and edit it to add a prefix to the ISO mountpoint.
    cp boot/ESXi-6.7.0-8169922/boot.cfg &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$macdir&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;/
    # The mountpoint can also be parsed from &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_operatingsystem_name&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;. Useful for deploying multiple ESXi builds.
    sed -e &quot;s#/##g&quot; -e &quot;3s#^#prefix=/boot/ESXi-6.7.0-8169922\n#&quot; -i &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$macdir&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;/boot.cfg
fi
# exit code is important on orchestration tasks
exit 0
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOT

&lt;/span&gt;chmod u+x 01-prep-esxi-uefimode.sh

&lt;span class=&quot;c&quot;&gt;# Make it accessible to Foreman&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /usr/share/foreman/config/hooks
chown &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; foreman:foreman host/

&lt;span class=&quot;c&quot;&gt;# Register the hook script in Foreman by restarting Apache&lt;/span&gt;
service apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; after_build hook scripts are not run on newly created hosts. These are only run when build mode is enabled on an existing host.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.4:&lt;/strong&gt; Now we are ready to deploy the host. Edit the host entry in Foreman and set the following:&lt;/p&gt;

    &lt;p&gt;Operating System : ESXi 6.7 Build 8169922&lt;br /&gt;
Media : ESXi Dummy&lt;br /&gt;
Partition table: Kickstart default&lt;br /&gt;
PXE Loader : mboot UEFI&lt;/p&gt;
    &lt;p float=&quot;left&quot; align=&quot;left&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-08-16-deploying-esxi-through-foreman/edit_host_uefi.png&quot; width=&quot;400&quot; /&gt;
&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.5:&lt;/strong&gt; Press ‘Resolve’ beside Provisioning templates and you should see the ESXi PXELinux and Kickstart templates.&lt;/p&gt;

    &lt;p&gt;Note: The PXELinux template is irrelevant as it does not play any role in UEFI mode. So we are keeping it as is.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.6:&lt;/strong&gt; Press ‘Build’, change the host’s boot mode to UEFI and reboot the host to PXE. You should see the ESXi installer load up.&lt;/p&gt;

    &lt;p&gt;Once the installation is complete and the host reboots, it will load mboot.efi from the DHCP Server again and the installation will restart. However since the host is not in build mode, it will not be able to fetch the kickstart file from Foreman and will throw an error and freeze at the installer screen. &lt;br /&gt;
To solve this we have to manually change the host PXE Loader to &lt;strong&gt;None&lt;/strong&gt; in Foreman.&lt;br /&gt;
OR we can use Foreman-Hooks to do it automatically!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;3.7: Using Foreman-Hooks to solve host not able to perform local boot from PXE&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Once the host informs Foreman that build is completed, we will run a script that checks the host’s OS and PXELoader and changes the PXELoader to None. For this we need to hook into the before_provision event.&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /usr/share/foreman/config/hooks

mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; host/managed/before_provision

&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;host/managed/before_provision

&lt;span class=&quot;c&quot;&gt;# Symlink the hook_functions file.&lt;/span&gt;
ln &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /usr/share/foreman/vendor/ruby/2.3.0/gems/foreman_hooks-0.3.14/examples/bash/hook_functions.sh &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Now create the script&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOT&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &amp;gt;&amp;gt; 01-esxi-unset-pxeloaders.sh
#!/bin/bash
. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;/hook_functions.sh
event=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOOK_EVENT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
object=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HOOK_OBJECT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

exec &amp;gt;&amp;gt; /tmp/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;.log
exec 2&amp;gt;&amp;amp;1

system_name=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.name&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_mac=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.mac&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_id=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.id&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_pxe_loader=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.pxe_loader&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
system_operatingsystem_name=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;hook_data host.host.operatingsystem_name&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;

echo &quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;: received &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; on &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
echo &quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_operatingsystem_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system_pxe_loader&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;

if [[ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_operatingsystem_name&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; == ESXi* ]] &amp;amp;&amp;amp; [[ &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_pxe_loader&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; == &quot;mboot UEFI&quot; ]]; then
    echo &quot;ESXi in UEFI mode detected. Changing PXE Loader to None&quot;
    hammer -u admin -p foreman host update --id &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$system_id&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; --pxe-loader 'None'  # Change the credentials
fi

exit 0
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOT

&lt;/span&gt;chmod u+x 01-esxi-unset-pxeloaders.sh

&lt;span class=&quot;c&quot;&gt;# Make it accessible to Foreman&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /usr/share/foreman/config/hooks
chown &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; foreman:foreman host/

&lt;span class=&quot;c&quot;&gt;# Register the hook script in Foreman by restarting Apache&lt;/span&gt;
service apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Check production.log to verify if the hook script is loaded.&lt;/p&gt;

    &lt;p&gt;Now when a host finishes OS installation and sends a build complete call to Foreman, its PXE Loader will be automatically changed to “None”. So when the host boots it will try to load ‘grub2/bootx64.efi’ from the DHCP server. Since this bootloader does not exist (unless you have modified a default installation), it will boot into the next entry which ideally will be the ESXi boot medium.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these steps you can have a fully automated ESXi deployment through Foreman in both Legacy BIOS and UEFI modes.&lt;/p&gt;</content><author><name>Amardeep Kahali</name></author><category term="foreman" /><category term="esxi" /><category term="vmware" /><summary type="html">At the time of writing this (Foreman v1.18), ESXi deployment through Foreman is not supported natively. The problem is exacerbated by the fact that the ESXi Legacy BIOS bootloader depends on an older Syslinux (v3.86) and GRUB2 not being able to chainload the ESXi EFI bootloader. However there are quite a few articles on the Internet that have attempted to work around these issues. This post is an attempt to bring all the information together in one place, simplify the process and most importantly, support both Legacy BIOS and UEFI modes of installation. Huge thanks to the foreman developers for helping me out whenever I was stuck. Requirements A fully working Foreman instance. Follow the manual to install Foreman. After installation, please configure Foreman so that a Linux OS (for e.g. Centos) can be deployed successfully through Foreman. Please make sure the Bootfile Handoff section in dhcpd.conf looks like this: # Bootfile Handoff next-server 127.0.0.1; option architecture code 93 = unsigned integer 16 ; if option architecture = 00:06 { filename &quot;grub2/bootia32.efi&quot;; } elsif option architecture = 00:07 { filename &quot;grub2/bootx64.efi&quot;; } elsif option architecture = 00:09 { filename &quot;grub2/bootx64.efi&quot;; } else { filename &quot;pxelinux.0&quot;; } Foreman-Hooks. Run the following command to install: foreman-installer --enable-foreman-plugin-hooks Syslinux version 3.86. An ESXi ISO. For this demo we will use VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso but the same process will work on any version of ESXi. Note: This demo is run on a Ubuntu system. The paths may be different for other OSes. Please refer to the documentation for details. 1: Create an entry for the ESXi OS in Foreman 1.1: Create the OS Medium Open https://{foreman-url}/media and click on Create Medium. Now create a dummy entry for ESXi since each OS entry in Foreman needs an installation media. 1.2: Create the OS Open https://{foreman-url}/operatingsystems and click on Create Operating System Under Operating System, enter the following: Name - ESXi-6.7.0-8169922 (ESXi-{OS Version}-{Build Number}) Major version - 6 Minor version - 7 Family - Redhat Root pass hash - SHA512 Architectures - x86_64 Partition Table - Kickstart default Note: We are using Kickstart default for the sake of simplicity. The actual partitioning will be controlled from the kickstart file. It is also possible to create a new ptable for ESXi and use it here. Installation Media - Select the dummy media created above Press Submit 1.3: Create provisioning templates 1.3.1: Create the PXELinux template Open https://{foreman-url}/templates/provisioning_templates and click on Create Template Name - ESXi-6.7.0-8169922 Template contents: DEFAULT ESXi NOHALT 1 LABEL ESXi KERNEL ../boot/ESXi-6.7.0-8169922/mboot.c32 APPEND -c ../boot-ESXi-6.7.0-8169922.cfg IPAPPEND 2 Note: The KERNEL and APPEND lines start with “../”. I will explain why in Section 2.4. These values will be used when we actually mount the ISO image. Template Type - PXELinux Template Template Association - Select “ESXi 6.7 Build 8169922” Click Submit 1.3.2: Create the Kickstart Template Click on Create Template Name - ESXi Minimal Kickstart A sample template: vmaccepteula keyboard 'US Default' reboot rootpw --iscrypted &amp;lt;%= root_pass %&amp;gt; install --firstdisk --overwritevmfs --novmfsondisk # Set the network to DHCP on the first network adapter network --bootproto=dhcp --device=&amp;lt;%= @host.mac %&amp;gt; %post --interpreter=busybox # Add temporary DNS resolution so the foreman call works echo &quot;nameserver &amp;lt;%= @host.subnet.dns_primary %&amp;gt;&quot; &amp;gt;&amp;gt; /etc/resolv.conf # Inform Foreman that we are done. wget -O /dev/null &amp;lt;%= foreman_url('built') %&amp;gt; echo &quot;Done with Foreman call&quot; Template Type - Provisioning template Template Association - Select “ESXi 6.7 Build 8169922” Click Submit 1.4: Set default provisioning templates Now that the templates are created, we need to set those as default. Navigate to https://{foreman-url}/operatingsystems and click on the newly created ESXi OS “ESXi 6.7 Build 8169922” Open the “Templates” tab Select the newly created provisioning templates from the drop down boxes and press Submit. 2: ESXi installation in Legacy BIOS mode The ESXi PXELinux mboot.c32 module only supports syslinux bootloader (pxelinux.0) version 3.86. You may replace the newer pxelinux.0 file that comes with the default Foreman installation with pxelinux.0 v3.86 but then you might face issues with newer OSes. So we will use a different approach. 2.1: Prepare the bootloader We will create a new directory under the tftp root directory (typically /var/lib/tftpboot) and place the syslinux v3.86 pxelinux.0 along with the c32 modules there. cd /tmp/ wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/3.xx/syslinux-3.86.tar.gz tar xvf syslinux-3.86.tar.gz mkdir /var/lib/tftpboot/syslinux386 cp syslinux-3.86/core/pxelinux.0 /var/lib/tftpboot/syslinux386/ find syslinux-3.86/com32/ -name \*.c32 -exec cp {} /var/lib/tftpboot/syslinux386 \; # Create a symlink to the default pxelinux.cfg directory inside new directory cd /var/lib/tftpboot/ ln -s ../pxelinux.cfg syslinux386/ 2.2: Create the bootloader entry in Foreman Now comes the interesting part. We will create a new PXELoader entry in Foreman for pxelinux-3.86.0. Huge thanks to Lukáš Zapletal for pointing this out. 2.2.1: Edit the file - /usr/share/foreman/app/models/concerns/pxe_loader_support.rb def all_loaders_map(precision = 'x64') { &quot;None&quot; =&amp;gt; &quot;&quot;, &quot;PXELinux BIOS&quot; =&amp;gt; &quot;pxelinux.0&quot;, &quot;PXELinux UEFI&quot; =&amp;gt; &quot;pxelinux.efi&quot;, &quot;PXELinux Alt BIOS&quot; =&amp;gt; &quot;syslinux386/pxelinux.0&quot;, # Add this line ... &amp;lt;/pre&amp;gt; 2.2.2: Restart httpd/apache2 for the changes to be reflected. 2.3: Mount the ESXi ISO We will mount the ESXi ISO under /var/lib/tftpboot/boot/ESXi-6.7.0-8169922. Note that this path corresponds to the KERNEL entry in the PXELinux template. cd /var/lib/tftpboot/ mkdir -p boot/ESXi-6.7.0-8169922 mount ~/Desktop/VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso boot/ESXi-6.7.0-8169922 2.4: Edit boot.cfg Copy the boot.cfg file from the mountpoint to tftproot and edit it to add a prefix to the ISO mountpoint. Make sure to use the same filename as the one specified in the APPEND line of the PXELinux template. cd /var/lib/tftpboot/ cp boot/ESXi-6.7.0-8169922/boot.cfg boot-ESXi-6.7.0-8169922.cfg sed -e &quot;s#/##g&quot; -e &quot;3s#^#prefix=../boot/ESXi-6.7.0-8169922\n#&quot; -i boot-ESXi-6.7.0-8169922.cfg Note: Since the host boots into syslinux386/pxelinux.0, the TFTP root dir will be set to /var/lib/tftpboot/syslinux386. So all paths need to be relative to this path. This is why all paths need to be prefixed with “../”. Instead of mounting the ISO, you can also extract the ISO contents to the directory and edit the boot.cfg directly inside that directory. Remember to change the PXELinux template accordingly. I chose this approach because it is a tad cleaner. Now we are ready to deploy this OS on to a host. 2.5: Open https://{foreman-url}/hosts/ and edit the host on which you want to deploy ESXi. 2.6: Under the ‘Operating System’ tab, select the following values: Operating System : ESXi 6.7 Build 8169922 Media : ESXi Dummy Partition table: Kickstart default PXE Loader : PXELinux Alt BIOS 2.7: Press ‘Resolve’ beside Provisioning templates and you should see the ESXi PXELinux and Kickstart templates. 2.8: Press ‘Build’ and reboot the host to PXE. If all goes well, you should see ESXi installer load up and perform an automated installation. Once installation is complete, the host will reboot to PXE and will be presented with the default PXE menu. Upon timeout, it will attempt a Localboot and boot to ESXi. 3: ESXi installation in UEFI mode 3.1: Prepare the bootloader In UEFI mode the bootloader is mboot.efi which is just a renamed version of efi/boot/bootx64.efi from the ESXi ISO image. The same mboot.efi can be used for booting different ESXi versions but it is recommended to use the latest one. Let’s create the bootloader. Assuming the ESXi ISO is mounted under /var/lib/tftpboot/boot/ESXi-6.7.0-8169922: cp /var/lib/tftpboot/boot/ESXi-6.7.0-8169922/efi/boot/bootx64.efi /var/lib/tftpboot/mboot.efi 3.2: Create the bootloader entry in Foreman Now we have to create an entry for this bootloader in the Foreman UI just like we did in Legacy BIOS mode. Edit the file: /usr/share/foreman/app/models/concerns/pxe_loader_support.rb def all_loaders_map(precision = 'x64') { &quot;None&quot; =&amp;gt; &quot;&quot;, &quot;PXELinux BIOS&quot; =&amp;gt; &quot;pxelinux.0&quot;, &quot;PXELinux UEFI&quot; =&amp;gt; &quot;pxelinux.efi&quot;, &quot;PXELinux Alt BIOS&quot; =&amp;gt; &quot;syslinux386/pxelinux.0&quot;, &quot;mboot UEFI&quot; =&amp;gt; &quot;mboot.efi&quot;, # Add this line ... &amp;lt;/pre&amp;gt; Restart httpd/apache2 to register the changes 3.3: Once the host loads mboot.efi, it will look for a boot.cfg file under tftproot/01-{MAC address of host}. Once it is located, the installer loads up and performs the installation. So each time we need to deploy ESXi in UEFI mode we need to create this directory and copy over the boot.cfg file. This can be quite tedious when we are deploying at scale. Here is where Foreman-Hooks comes in handy. From the Foreman-Hooks Github repo: Foreman Hooks allows you to trigger scripts and commands on the Foreman server at any point in an object’s lifecycle in Foreman. This lets you run scripts when a host is created, or finishes provisioning etc. Once the host is set to build mode, the MAC directory along with the boot.cfg file should be created automatically. For this we need to hook into the after_build event. cd /usr/share/foreman/config/hooks mkdir -p host/managed/after_build cd host/managed/after_build # Symlink the hook_functions file. ln -s /usr/share/foreman/vendor/ruby/2.3.0/gems/foreman_hooks-0.3.14/examples/bash/hook_functions.sh . # Now create the script cat &amp;lt;&amp;lt;EOT &amp;gt;&amp;gt; /host/managed/after_build/01-prep-esxi-uefimode.sh #!/bin/bash # Import the functions . $(dirname $0)/hook_functions.sh # event name (create, before_destroy etc.) # orchestration hooks must obey this to support rollbacks (create/update/destroy) event=${HOOK_EVENT} # to_s representation of the object, e.g. host's fqdn object=${HOOK_OBJECT} exec &amp;gt;&amp;gt; /tmp/${event}.log exec 2&amp;gt;&amp;amp;1 system_name=$(hook_data host.host.name) # Yes it is host.host.&amp;lt;attribute&amp;gt; instead of host.&amp;lt;attribute&amp;gt; due to this open issue: https://github.com/theforeman/foreman_hooks/issues/46 system_mac=$(hook_data host.host.mac) system_pxe_loader=$(hook_data host.host.pxe_loader) system_operatingsystem_name=$(hook_data host.host.operatingsystem_name) echo &quot;$(date): received ${event} on ${object}&quot; echo &quot;${system_name} ${system_mac} ${system_operatingsystem_name} ${system_pxe_loader}&quot; if [[ $system_operatingsystem_name == ESXi* ]] &amp;amp;&amp;amp; [[ $system_pxe_loader == &quot;mboot UEFI&quot; ]]; then echo &quot;ESXi UEFI mode detected&quot; # Create MAC Address directory under tftproot after substituting : with - macdir=&quot;01-${system_mac//:/-}&quot; mkdir -p /var/lib/tftpboot/${macdir} # Copy the boot.cfg file from the ISO mountpoint to tftproot and edit it to add a prefix to the ISO mountpoint. cp boot/ESXi-6.7.0-8169922/boot.cfg $macdir/ # The mountpoint can also be parsed from $system_operatingsystem_name. Useful for deploying multiple ESXi builds. sed -e &quot;s#/##g&quot; -e &quot;3s#^#prefix=/boot/ESXi-6.7.0-8169922\n#&quot; -i $macdir/boot.cfg fi # exit code is important on orchestration tasks exit 0 EOT chmod u+x 01-prep-esxi-uefimode.sh # Make it accessible to Foreman cd /usr/share/foreman/config/hooks chown -R foreman:foreman host/ # Register the hook script in Foreman by restarting Apache service apache2 restart Important Note: after_build hook scripts are not run on newly created hosts. These are only run when build mode is enabled on an existing host. 3.4: Now we are ready to deploy the host. Edit the host entry in Foreman and set the following: Operating System : ESXi 6.7 Build 8169922 Media : ESXi Dummy Partition table: Kickstart default PXE Loader : mboot UEFI 3.5: Press ‘Resolve’ beside Provisioning templates and you should see the ESXi PXELinux and Kickstart templates. Note: The PXELinux template is irrelevant as it does not play any role in UEFI mode. So we are keeping it as is. 3.6: Press ‘Build’, change the host’s boot mode to UEFI and reboot the host to PXE. You should see the ESXi installer load up. Once the installation is complete and the host reboots, it will load mboot.efi from the DHCP Server again and the installation will restart. However since the host is not in build mode, it will not be able to fetch the kickstart file from Foreman and will throw an error and freeze at the installer screen. To solve this we have to manually change the host PXE Loader to None in Foreman. OR we can use Foreman-Hooks to do it automatically! 3.7: Using Foreman-Hooks to solve host not able to perform local boot from PXE Once the host informs Foreman that build is completed, we will run a script that checks the host’s OS and PXELoader and changes the PXELoader to None. For this we need to hook into the before_provision event. cd /usr/share/foreman/config/hooks mkdir -p host/managed/before_provision cd host/managed/before_provision # Symlink the hook_functions file. ln -s /usr/share/foreman/vendor/ruby/2.3.0/gems/foreman_hooks-0.3.14/examples/bash/hook_functions.sh . # Now create the script cat &amp;lt;&amp;lt;EOT &amp;gt;&amp;gt; 01-esxi-unset-pxeloaders.sh #!/bin/bash . $(dirname $0)/hook_functions.sh event=${HOOK_EVENT} object=${HOOK_OBJECT} exec &amp;gt;&amp;gt; /tmp/${event}.log exec 2&amp;gt;&amp;amp;1 system_name=$(hook_data host.host.name) system_mac=$(hook_data host.host.mac) system_id=$(hook_data host.host.id) system_pxe_loader=$(hook_data host.host.pxe_loader) system_operatingsystem_name=$(hook_data host.host.operatingsystem_name) echo &quot;$(date): received ${event} on ${object}&quot; echo &quot;${system_name} ${system_mac} ${system_operatingsystem_name} ${system_pxe_loader}&quot; if [[ $system_operatingsystem_name == ESXi* ]] &amp;amp;&amp;amp; [[ $system_pxe_loader == &quot;mboot UEFI&quot; ]]; then echo &quot;ESXi in UEFI mode detected. Changing PXE Loader to None&quot; hammer -u admin -p foreman host update --id $system_id --pxe-loader 'None' # Change the credentials fi exit 0 EOT chmod u+x 01-esxi-unset-pxeloaders.sh # Make it accessible to Foreman cd /usr/share/foreman/config/hooks chown -R foreman:foreman host/ # Register the hook script in Foreman by restarting Apache service apache2 restart Check production.log to verify if the hook script is loaded. Now when a host finishes OS installation and sends a build complete call to Foreman, its PXE Loader will be automatically changed to “None”. So when the host boots it will try to load ‘grub2/bootx64.efi’ from the DHCP server. Since this bootloader does not exist (unless you have modified a default installation), it will boot into the next entry which ideally will be the ESXi boot medium. With these steps you can have a fully automated ESXi deployment through Foreman in both Legacy BIOS and UEFI modes.</summary></entry><entry><title type="html">Foreman Community Newsletter - July 2018</title><link href="http://theforeman.org/2018/07/foreman-community-newsletter-july-2018.html" rel="alternate" type="text/html" title="Foreman Community Newsletter - July 2018" /><published>2018-07-31T15:17:00+00:00</published><updated>2018-07-31T15:17:00+00:00</updated><id>http://theforeman.org/2018/07/foreman-community-newsletter---july-2018</id><content type="html" xml:base="http://theforeman.org/2018/07/foreman-community-newsletter-july-2018.html">&lt;h3 id=&quot;foreman-1180-released&quot;&gt;Foreman 1.18.0 released&lt;/h3&gt;

&lt;p&gt;The next stable release of Foreman (1.18.0) was &lt;a href=&quot;https://community.theforeman.org/t/1-18-0-has-been-released/10462&quot;&gt;released on July
19th&lt;/a&gt;, with many &lt;a href=&quot;https://theforeman.org/manuals/1.18/index.html#Headlinefeatures&quot;&gt;new features&lt;/a&gt; and &lt;a href=&quot;https://theforeman.org/manuals/1.18/index.html#BugFixes&quot;&gt;bug fixes&lt;/a&gt;.
Everyone is encouraged to schedule their upgrades, especially if you’re still
on the (now unmaintained) 1.16 series.&lt;/p&gt;

&lt;p&gt;As ever, many thanks to the contributors to this release - coders, RC testers,
documentation writers, and bug/feature reporters. Foreman wouldn’t be what it
is without you! If you do find issues with, please do &lt;a href=&quot;https://projects.theforeman.org/issues&quot;&gt;report them!&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;katello-37-released&quot;&gt;Katello 3.7 released&lt;/h3&gt;

&lt;p&gt;Hard on the heels of the 1.18 release of Foreman core, the Katello team brought
you &lt;a href=&quot;https://community.theforeman.org/t/katello-3-7-0-released/10564&quot;&gt;version 3.7&lt;/a&gt; on Jul 27th, with &lt;em&gt;far&lt;/em&gt; too many
&lt;a href=&quot;https://theforeman.org/plugins/katello/3.7/release_notes/release_notes.html&quot;&gt;features&lt;/a&gt; and &lt;a href=&quot;https://github.com/Katello/katello/blob/KATELLO-3.7/CHANGELOG.md#bug-fixes&quot;&gt;bug fixes&lt;/a&gt; to list. If you’re upgrading a
Katello install, do be sure to read the &lt;a href=&quot;https://theforeman.org/plugins/katello/3.7/installation/index.html&quot;&gt;upgrade notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Huge thanks to all the contributors to this release - as with core, we couldn’t
put out these releases without you! Further issues with Katello should be
&lt;a href=&quot;https://projects.theforeman.org/projects/katello/issues&quot;&gt;reported&lt;/a&gt;, as always.&lt;/p&gt;

&lt;h3 id=&quot;119-rc1-katello-38-rc1-and-test-week-event&quot;&gt;1.19 RC1, Katello 3.8 RC1, and test week event&lt;/h3&gt;

&lt;p&gt;Since we’re trying to make up time for the slow releases over the last year or
so, the next releases of Foreman and Katello are already being prepared.
Release candidates for &lt;a href=&quot;https://community.theforeman.org/t/foreman-1-19-0-rc1-has-been-released/10531&quot;&gt;1.19&lt;/a&gt; and &lt;a href=&quot;https://community.theforeman.org/t/katello-3-8-rc1-available-for-testing/10536&quot;&gt;3.8&lt;/a&gt; are already
available, and as always we’d like you help to test them!&lt;/p&gt;

&lt;p&gt;To give a little structure to this, we’ve again organised a &lt;a href=&quot;https://community.theforeman.org/t/foreman-1-19-test-week-event/10534&quot;&gt;test week
event&lt;/a&gt; during which we’d like to see as many of our end-user
scenarios tested as possible. If any of these fit your workflow, and you’re
willing to give the RC a spin, please do! Be sure to &lt;a href=&quot;https://community.theforeman.org/t/foreman-1-19-test-week/10533&quot;&gt;let us know how it
went&lt;/a&gt; and of course &lt;a href=&quot;https://projects.theforeman.org/issues&quot;&gt;report any bugs&lt;/a&gt; that you find.
Thanks!&lt;/p&gt;

&lt;h3 id=&quot;foremans-9th-birthday&quot;&gt;Foreman’s 9th Birthday&lt;/h3&gt;

&lt;p&gt;July is our birthday month, this year we are 9! Everyone who’s a part of this
lovely community deserves a $beverage-of-choice, we wouldn’t be here today
without you.&lt;/p&gt;

&lt;p&gt;To celebrate, we teamed up with our friends at &lt;a href=&quot;https://atix.de&quot;&gt;Atix&lt;/a&gt; for a
9th birthday party hackday. You can read all about the good times &lt;a href=&quot;https://www.atix.de/recap-the-foreman-birthday-party-atix&quot;&gt;over on
their blog&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;6-months-of-discourse&quot;&gt;6 months of Discourse&lt;/h3&gt;

&lt;p&gt;The start of this month also marked a full 6 months since our migration to
Discourse. It’s had a noticeable effect on both the user and dev communities,
and in a good way. To mark the occasion, I wrote a short blog post analysing
some of the data Discourse generates, looking at trends in community growth and
amount of discussion. &lt;a href=&quot;https://theforeman.org/2018/07/discourse-6-months-on-impact-assesment.html&quot;&gt;Check it
out&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;redmine-upgrade&quot;&gt;Redmine upgrade&lt;/h3&gt;

&lt;p&gt;The Redmine instance completed its upgrade path last week, we are now fully up
to date. Thanks to everyone for their patience during the chaos that caused.&lt;/p&gt;

&lt;h3 id=&quot;rfcs-needing-attention&quot;&gt;RFCs needing attention&lt;/h3&gt;

&lt;p&gt;Here’s this month’s selection of open discussion areas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/introduce-a-foreman-client-repository/10235&quot;&gt;Foreman Client Repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/rfc-drop-c-flag-from-wget-on-tftp-proxy/10010&quot;&gt;Drop -c from TFTP wget calls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/exposing-capabilities-in-the-smart-proxy/9860/5&quot;&gt;Smart Proxy Capabilities&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/pulp-3-migration/10474/17&quot;&gt;Pulp 3 Migration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;upcoming-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/calendar&quot;&gt;Upcoming Events&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The Foreman Community has now fully embraced Discourse as the source of its
event data - if you’ve been using the old &lt;code class=&quot;highlighter-rouge&quot;&gt;/events/all.ics&lt;/code&gt; in your own
calendar, you’ll need to head over to &lt;a href=&quot;https://community.theforeman.org/calendar&quot;&gt;the forum
calendar&lt;/a&gt; and hit the Subscribe
button (which will give you an ICS link). You can also use the Add To Calendar
button on specific events if you don’t wish to import the whole thing.&lt;/p&gt;

&lt;p&gt;Future community demos will now be created much further in advance, so you
should be able to keep up with upcoming demos there.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-48/9826&quot;&gt;Community Demo #48&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the usual goodness from the community, rounded up and presented for your viewing pleasure.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/devconf-india-2018/10309&quot;&gt;DevConf India 2018&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Foreman Project will have a huge appearance at DevConf India ’18.  We have two
talks lined up on the very first day of the conference, as well as a booth at
the conference, so drop by and say hello! We’ll have very exciting goodies and
t-shirts at the Foreman booth, make sure you grab them before they are gone
:slight_smile:&lt;/p&gt;

&lt;h4 id=&quot;past-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/latest&quot;&gt;Past Events&lt;/a&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-47&quot;&gt;Community Demo #47&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Subscriptions, Jenkins, live images, and an &lt;em&gt;awesome&lt;/em&gt; new reporting engine from Marek. Do watch!&lt;/p&gt;

&lt;h3 id=&quot;plugin-news&quot;&gt;Plugin news&lt;/h3&gt;

&lt;p&gt;New plugins:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman_ansible&quot;&gt;hammer_cli_foreman_ansible&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dropped plugins (unmaintained, no longer working):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;ABRT&lt;/li&gt;
  &lt;li&gt;Azure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Updated plugins:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Katello/hammer-cli-katello&quot;&gt;hammer_cli_katello&lt;/a&gt; updated to 0.13.4&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman&quot;&gt;hammer_cli_foreman&lt;/a&gt; updated to 0.13.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_discovery&quot;&gt;foreman_discovery&lt;/a&gt; updated to 12.0.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_salt&quot;&gt;foreman_salt&lt;/a&gt; updated to 10.1.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_templates&quot;&gt;foreman_templates&lt;/a&gt;to 6.0.3&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_remote_execution&quot;&gt;foreman_remote_execution&lt;/a&gt; updated to 1.5.4&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_openscap&quot;&gt;foreman_openscap&lt;/a&gt; updated to 0.10.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_ansible&quot;&gt;foreman_ansible&lt;/a&gt; updated to 2.2.5&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_maintain&quot;&gt;foreman_maintain&lt;/a&gt; updated to 0.2.5&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/smart_proxy_ansible&quot;&gt;smart_proxy_ansible&lt;/a&gt; updated to 2.0.3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;

&lt;p&gt;Thanks to everyone who contributes to the Foreman community - patches, plugins,
testing, bug reports, translations, interviews, presentations, meetups and
everything else. Your efforts are very much appreciated!&lt;/p&gt;</content><author><name>Greg Sutcliffe</name><uri>gwmngilfen</uri></author><category term="foreman" /><category term="newsletter" /><category term="community" /><summary type="html">Foreman 1.18.0 &amp; 1.19 RC1, Katello 3.7 &amp; 3.8 RC1, birthdays, YouTube, even some stats!</summary></entry><entry><title type="html">Recap: The Foreman Birthday Party @ATIX</title><link href="http://theforeman.org/2018/07/recap-foreman-birthday-party-at-atix.html" rel="alternate" type="text/html" title="Recap: The Foreman Birthday Party @ATIX" /><published>2018-07-31T14:25:45+00:00</published><updated>2018-07-31T14:25:45+00:00</updated><id>http://theforeman.org/2018/07/recap-foreman-birthday-party-at-atix</id><content type="html" xml:base="http://theforeman.org/2018/07/recap-foreman-birthday-party-at-atix.html">&lt;p&gt;This year it was our pleasure to host Foreman’s 9th birthday party.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;once-upon-a-time-&quot;&gt;Once upon a time …&lt;/h2&gt;

&lt;p&gt;On the 13th of July in 2009 Ohad Levy gave birth to a new project which was
later to be named “The Foreman”&lt;/p&gt;

&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/first-commit.png&quot; width=&quot;200&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;Nine years later The Foreman is grown up and famous for managing and automating
a huge number of IT infrastructures with several thousands of servers. Today,
Foreman is also a major part of enterprise system management solutions like Red
Hat Satellite 6 and orcharhino.&lt;/p&gt;

&lt;h1 id=&quot;were-celebrating&quot;&gt;We’re celebrating&lt;/h1&gt;

&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/swag.jpg&quot; width=&quot;200&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;The party started at 10 am with birthday presents for all party guests.
Everybody got t-shirts, stickers and foreman party helmets.  After a short
introduction we started our hack and try sessions. Powered by mate–tea and
cola, three groups worked very successfully on foreman-ansible, foreman-probing
and chat integration for foreman messaging. Only interrupted by a very short
lunch break the sessions went until 14:30 when the „official“ part started.&lt;/p&gt;

&lt;p&gt;This time we could listen to very interesting talks: Bernhard and Markus from
ATIX showed us the possibilities of securing software repositories with gpg
keys. Dirk Götz from NETWAYS gave a very good overview and demo about his
favorite foreman plugins. Foreman Community-Developer Adam presented the latest
enhancements of the remote execution plugin and Ansible integration.&lt;/p&gt;

&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party1.jpeg&quot; width=&quot;200&quot; /&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party2.jpeg&quot; width=&quot;200&quot; /&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party3.jpeg&quot; width=&quot;200&quot; /&gt;
&lt;/p&gt;

&lt;h2 id=&quot;whats-a-birthday-party-without-a-cake-nothing&quot;&gt;What’s a birthday party without a cake? Nothing!&lt;/h2&gt;

&lt;p&gt;The Foreman turned nine – so we had a big birthday cake with nine candles!
After the Happy birthday song, Adam was chosen to blow out the candles and make
some well wishes for the birthday boy.&lt;/p&gt;

&lt;p&gt;The party went on with interesting discussions over pizza, beer.&lt;/p&gt;

&lt;p float=&quot;left&quot; align=&quot;center&quot;&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party4.jpg&quot; width=&quot;200&quot; /&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party5.jpg&quot; width=&quot;200&quot; /&gt;
  &lt;img src=&quot;/static/images/blog_images/2018-atix-birthday/party6.jpg&quot; width=&quot;200&quot; /&gt;
&lt;/p&gt;

&lt;h2 id=&quot;the-end&quot;&gt;The end…&lt;/h2&gt;

&lt;p&gt;All guest enjoyed the party and working together with other community members.
New friendships were made and everybody is living happily ever after :)&lt;/p&gt;</content><author><name>Mark Hlawatschek</name><uri>hlawatschek</uri></author><category term="foreman" /><category term="event" /><category term="meetup" /><category term="birthday" /><category term="atix" /><summary type="html">This year it was our pleasure to host Foreman’s 9th birthday party.</summary></entry><entry><title type="html">Discourse, 6 months on: Impact Assessment</title><link href="http://theforeman.org/2018/07/discourse-6-months-on-impact-assesment.html" rel="alternate" type="text/html" title="Discourse, 6 months on: Impact Assessment" /><published>2018-07-26T00:00:00+00:00</published><updated>2018-07-26T00:00:00+00:00</updated><id>http://theforeman.org/2018/07/discourse-6-months-on-impact-assesment</id><content type="html" xml:base="http://theforeman.org/2018/07/discourse-6-months-on-impact-assesment.html">&lt;p&gt;It’s been 6 months since the Foreman community switched to Discourse, so I
wanted to revisit some of the graphs I &lt;a href=&quot;https://community.theforeman.org/t/feedback-wanted-migrate-mailing-lists-to-a-forum/7571&quot;&gt;drew in
November&lt;/a&gt;
(when I was justifying the migration) and see if its had a positive impact.
Spoiler alert! It has :)&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Back in November, I made a big deal about not only how our mailing list was
failing, but also about how a more modern medium could help us achieve our
goals better. Six months in, it seemed appropriate to try and evaluate a few of
those things. We’ll take a look at overall post count, active user count, and
the interaction between the two.&lt;/p&gt;

&lt;h2 id=&quot;the-data&quot;&gt;The data&lt;/h2&gt;

&lt;p&gt;Thanks to importing all the mailing list posts into Discourse, we have
post/topic/user data going right back to the creation of the mailing list some
8 years ago. Discourse itself generates &lt;em&gt;far&lt;/em&gt; more metrics we could look at,
but since we want to compare to the old lists, we’ll have to restrict ourselves
to these.&lt;/p&gt;

&lt;p&gt;Since we want to compare like to like, we’ll also &lt;em&gt;only&lt;/em&gt; use the first 6 months
of 2017. Obviously we have &lt;em&gt;all&lt;/em&gt; of 2017, but there’s complications in using it.
Firstly, it’s a different time period, so seasonal effects may come into play
(e.g. it’s always quieter at Christmas), but more importantly, Discourse trials
begin in November, which would make interpretation very hard. So, we’ll use
2017-01-01 to 2017-06-30 (and likewise for 2018).&lt;/p&gt;

&lt;p&gt;We do have the data per day, but that causes zero-inflation issues - our
community is always very quiet on Saturdays, and somewhat quiet on Fridays and
Sundays too. To avoid modelling issues with this, we’ll aggregate the data by
week - look at this graph to see the difference:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/images/blog_images/2018-discourse-impact/zero-inflation.jpeg&quot; alt=&quot;&quot; /&gt;&lt;!-- --&gt;&lt;/p&gt;

&lt;p&gt;As you can see, grouping by week makes for a more “normally distributed” data
set, which is better for modelling (yes, I could use a Poisson GLM or something
here, but I don’t think it affects the result).&lt;/p&gt;

&lt;p&gt;So, we’ll have 26 data points per year, one for each week, and both the count
forum posts for that week, and the number of active users for that week (this
isn’t a simple sum, but a form of SELECT DISTINCT on all the post authors for
each week).&lt;/p&gt;

&lt;p&gt;We can break this down in a few ways - the whole data set, two groups by year,
two groups by list (foreman-users and foreman-dev), or a 2x2 matrix of both.&lt;/p&gt;

&lt;h3 id=&quot;post-and-user-count&quot;&gt;Post and user count&lt;/h3&gt;

&lt;p&gt;Let’s start by seeing the raw post count by week for each of the lists. This is
simply the &lt;code class=&quot;highlighter-rouge&quot;&gt;forum_posts&lt;/code&gt; column, one graph per channel, and with the two year’s
data overlaid:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/images/blog_images/2018-discourse-impact/posts-by-channel.jpeg&quot; alt=&quot;&quot; /&gt;&lt;!-- --&gt;&lt;/p&gt;

&lt;p&gt;The lines are a linear fit, the shaded area is the uncertainty in that fit.&lt;/p&gt;

&lt;p&gt;We can see that in both cases, the 2017 data shows the mailing lists were not
doing well - dev was growing &lt;em&gt;slowly&lt;/em&gt; but users was declining. 2018 looks
&lt;em&gt;much&lt;/em&gt; better! We can also look at this from an averages view:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;data %&amp;gt;% group_by(year,buffer) %&amp;gt;% summarise(mean_posts_per_day = mean(forum_posts)) %&amp;gt;% kable()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;style type=&quot;text/css&quot;&gt;
table {
	color:#333333;
	border-width: 1px;
	border-color: #666666;
	border-collapse: collapse;
}
table th {
	border-width: 1px;
	padding: 8px;
	border-style: solid;
	border-color: #666666;
	background-color: #dedede;
}
table td {
	border-width: 1px;
	padding: 8px;
	border-style: solid;
	border-color: #666666;
	background-color: #ffffff;
}
&lt;/style&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;year&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;buffer&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;mean posts per day&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2017&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;theforeman&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;8.311111&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2018&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;theforeman&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;17.928177&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2017&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;theforeman-dev&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.153846&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2018&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;theforeman-dev&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;9.213483&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In both cases, the mean posts per day has more than doubled, which is a big
deal, I think. However, there’s a catch….&lt;/p&gt;

&lt;p&gt;We also talked about attracting a &lt;em&gt;wider&lt;/em&gt; community as part of our move, so
let’s look at this data and include the &lt;em&gt;number of users&lt;/em&gt; too. You might well
expect to see the number of posts grow if the number of users is growing.
Here’s the same plot, but now we’ll make the “point size” relative to the
number of active users that week:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/images/blog_images/2018-discourse-impact/posts-and-users-by-channel-2018.jpeg&quot; alt=&quot;&quot; /&gt;&lt;!-- --&gt;&lt;/p&gt;

&lt;p&gt;I’ve just plotted 2018 here, for clarity, but 2017 is similar. So, yes! We do
see a rise in the number of users - this is great news! We wanted to widen the
community, and we seem to be achieving that. We can actually test that, for
foreman-users:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;t.test(d_18_usr$forum_users, d_17_usr$forum_users, paired = F, var.equal = F)

t = 6.6282, df = 49.737, p-value = 2.344e-08
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  5.709454 10.675162
sample estimates:
mean of x mean of y
 21.42308  13.23077
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The things to focus on here are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The averages (means) at the end - 2018 has nearly double the mean number of &lt;em&gt;post authors&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;The confidence interval for the &lt;em&gt;difference of means&lt;/em&gt;
    &lt;ul&gt;
      &lt;li&gt;it doesn’t contain 0, so it’s very unlikely that this shift is due to chance&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can do the same for the foreman-dev:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;t.test(d_18_dev$forum_users, d_17_dev$forum_users, paired = F, var.equal = F)


t = 6.6509, df = 44.602, p-value = 3.5e-08
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 10.08103 18.84204
sample estimates:
mean of x mean of y
 43.26923  28.80769
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Same results - large difference in mean, and the confidence interval is even further from zero.&lt;/p&gt;

&lt;h1 id=&quot;accounting-for-users&quot;&gt;Accounting for users&lt;/h1&gt;

&lt;p&gt;So we know the number of users has increased - what does this mean for the
number of posts. Happily, we can use some statistical modelling to account for
that. We’ll use a model like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;forum_posts ~ week_num + forum_users
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So we’re saying that posts is some combination of the time (&lt;code class=&quot;highlighter-rouge&quot;&gt;week_num&lt;/code&gt;) and the
number of authors (&lt;code class=&quot;highlighter-rouge&quot;&gt;forum_users&lt;/code&gt;), plus some constant. Using this model, we can
try to make a statement about what we would expect the effect of &lt;code class=&quot;highlighter-rouge&quot;&gt;week_num&lt;/code&gt; to
be &lt;em&gt;while holding the number of users constant&lt;/em&gt;. Let’s try that.&lt;/p&gt;

&lt;p&gt;Here’s a graph of &lt;code class=&quot;highlighter-rouge&quot;&gt;forum_posts&lt;/code&gt; divided by &lt;code class=&quot;highlighter-rouge&quot;&gt;forum_users&lt;/code&gt; for each week - that’s
not &lt;em&gt;quite&lt;/em&gt; the same as the model above, but it gives us a way to view the
data. Over the top I’ve laid a simple linear fit to that normalized post count;
you can see that for 3 of the graphs, it’s pretty much flat:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/images/blog_images/2018-discourse-impact/post-increase-from-users.jpeg&quot; alt=&quot;&quot; /&gt;&lt;!-- --&gt;&lt;/p&gt;

&lt;p&gt;However, the Dev 2018 graph is not flat. If we investigate the model more
closely there, we can see an interesting result. Here’s the model output:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lm(formula = forum_posts ~ week_num + forum_users, data = d_18_dev)

Coefficients:
            Estimate Std. Error t value Pr(&amp;gt;|t|)
(Intercept) -46.3843    10.7805  -4.303 0.000265 ***
week_num      0.8893     0.2915   3.051 0.005674 **
forum_users   4.5491     0.5196   8.755 8.83e-09 ***
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve trimmed the output to just the coefficients. What this tells us is that we
expect to see an increase in the number of posts to the Development category
over time, &lt;em&gt;even while holding the number of users constant&lt;/em&gt;. Specifically, we
expect between 0.3 and 1.5 more posts week-on-week, even if the number of users
doesn’t change. That’s to a 95% confidence level (i.e. there’s a 5% chance I’m
wrong, and this is all by chance).&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;There’s clear evidence of an increase in posts and number of users since the
move to Discourse. I don’t think that’s surprising - I’ve certainly felt the
impact, and I believe others have too. I’ve spent much more of my time replying
to posts than I used to on the mailing list. However, that the mean number of
posts has more than doubled for both categories is a surprise even to me. In
terms of raw numbers, that’s quite a turnaround (and less than 1/1,000,000
chance of it being a freak accident and nothing has really changed).&lt;/p&gt;

&lt;p&gt;However, it’s the result for the Development category that I really like. One
of the arguments I made for Discourse that seems to resonate with people is
that it would bring better tools for the &lt;em&gt;developers&lt;/em&gt; to discuss the project
and come to consensus on how to move forward. While this data says nothing
about consensus specifically (we could all be arguing more :P), it does show
that we’re all talking to each other &lt;em&gt;more&lt;/em&gt; as time goes on. Speaking as a
long-time remotee, I like it when I see communication between people
&lt;em&gt;increasing&lt;/em&gt; :)&lt;/p&gt;

&lt;p&gt;Can we attribute this to Discourse? Well, there’s an age-old saying that
&lt;a href=&quot;https://www.xkcd.com/552&quot;&gt;correlation does not mean causation&lt;/a&gt;. However,
thanks to &lt;a href=&quot;https://www.kdnuggets.com/2017/02/hill-data-scientist-xkcd-story.html&quot;&gt;Hill’s criteria for causal
relationships&lt;/a&gt;,
we can still draw some conclusions. Most applicable is the fact that no other
large event took place in our community that could plausibly cause such a
change, and the mechanism by which Discourse &lt;em&gt;could&lt;/em&gt; cause a change is also
fairly clear. I’m going to go out on a limb and say these two things are linked
:)&lt;/p&gt;

&lt;p&gt;So, six months in and it’s looking pretty good. How are &lt;em&gt;you&lt;/em&gt; finding Discourse?&lt;/p&gt;

&lt;p&gt;P.S. If you want to check my working, I’ll happily share the code :)&lt;/p&gt;</content><author><name>Greg Sutcliffe</name><uri>gwmngilfen</uri></author><category term="foreman" /><category term="discourse" /><category term="data-science" /><summary type="html">It’s been 6 months since the Foreman community switched to Discourse, so I wanted to revisit some of the graphs I drew in November (when I was justifying the migration) and see if its had a positive impact. Spoiler alert! It has :)</summary></entry><entry><title type="html">Monitoring and telemetry of Foreman 1.18</title><link href="http://theforeman.org/2018/07/monitoring-and-telemetry-of-foreman-118.html" rel="alternate" type="text/html" title="Monitoring and telemetry of Foreman 1.18" /><published>2018-07-20T13:26:15+00:00</published><updated>2018-07-20T13:26:15+00:00</updated><id>http://theforeman.org/2018/07/monitoring-and-telemetry-of-foreman-118</id><content type="html" xml:base="http://theforeman.org/2018/07/monitoring-and-telemetry-of-foreman-118.html">&lt;p&gt;Performance Co-Pilot (PCP) is an open source framework and toolkit for monitoring and analyzing live and historical system performance. It provides high-resolution live monitoring from local or remote hosts (with optional auto-discovery) and instrumented software. PCP can be integrated with monitoring solutions like Graphite (Carbon/Whisper), InfluxDB, Zabbix or Nagios, or configured to store historical data into archive files which is a unique feature we want to take advantage from.&lt;/p&gt;

&lt;p&gt;PCP follows UNIX tradition by providing a relatively large collection of small utilities which do their job well. There are several APIs available to write collecting agents called PMDAs or to instrument existing applications to gather “telemetry” data. APIs are available mostly in C, Python and Perl out of box with extra wrappers or native libraries in Java, Rust and Golang. PCP is a compact package (under one megabyte) with minimum dependencies and part of standard RHEL7 base repositories.&lt;/p&gt;

&lt;p&gt;The article covers PCP installation, basic operating system monitoring configuration with extra monitoring of key processes and PostgreSQL and Apache httpd. It also shows how to setup Foreman Ruby on Rails monitoring to read internal metrics from Foreman 1.18 core application. Major areas covered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;basic system monitoring (load, memory, IO)&lt;/li&gt;
  &lt;li&gt;hot processes (memory and cpu utilization)&lt;/li&gt;
  &lt;li&gt;Apache httpd monitoring&lt;/li&gt;
  &lt;li&gt;PostgreSQL monitoring&lt;/li&gt;
  &lt;li&gt;Foreman Rails application instrumentation&lt;/li&gt;
  &lt;li&gt;all relevant metrics archival for retrospective troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Second part of the article covers analysis of results using PCP CLI and web UI tools and retrospective analysis.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;If you’d like to watch a video of this process, you can view that &lt;a href=&quot;https://youtu.be/Zgg6Ta5tO9A&quot;&gt;on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The article assumes a Red Hat based distro (Centos etc), version 7.6+. It will likely work for older versions, or other distros such as Debian, with appropriate changes to the paths (e.g. where the Apache config files are located, etc.). Due to a &lt;a href=&quot;https://bugzilla.redhat.com/show_bug.cgi?id=1586051&quot;&gt;known bug&lt;/a&gt; PCP 4.1+ is recommended.&lt;/p&gt;

&lt;p&gt;The following packages needs to be installed and enabled:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum -y install pcp pcp-pmda-apache pcp-pmda-postgresql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Make sure there is enough space for &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/pcp&lt;/code&gt;. Our testing showed about 100-500 MB per archive file (per day) but on busy servers this can go up to several gigabytes per day. Default PCP retention policy is to keep 14 days of compressed archives, the article shows how to change this setting below. We recommend at least 20 GB of free space and continuous monitoring for the first few weeks.&lt;/p&gt;

&lt;p&gt;By default, PCP collects basic system metrics but not all processes, to get memory information from key processes let’s configure hotproc monitoring which will include CPU time spent, RSS, swap and virtual memory, file descriptors opened and bytes read and written:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;gt;/var/lib/pcp/pmdas/proc/hotproc.conf &amp;lt;&amp;lt;EOF
#pmdahotproc
Version 1.0

fname == &quot;java&quot; ||
fname ~ /(qdrouterd|qpidd)/ ||
(fname == &quot;postgres&quot; &amp;amp;&amp;amp; psargs ~ /-D/) ||
fname == &quot;mongod&quot; ||
fname ~ /^dynflow/ ||
psargs ~ /Passenger RackApp/ ||
fname ~ /^wsgi:pulp/ ||
psargs ~ /celery (beat|worker)/ ||
psargs ~ /pulp_streamer/ ||
psargs ~ /smart-proxy/ ||
psargs ~ /squid.conf/
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the next step, we will make sure those metrics also gets logged into archive files.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p /var/lib/pcp/config/pmlogconf/foreman-hotproc
cat &amp;gt;/var/lib/pcp/config/pmlogconf/foreman-hotproc/summary &amp;lt;&amp;lt; EOF
#pmlogconf-setup 2.0
ident   foreman hotproc metrics
probe   hotproc.control.config != &quot;&quot; ? include : exclude
        hotproc.psinfo.psargs
        hotproc.psinfo.cnswap
        hotproc.psinfo.nswap
        hotproc.psinfo.rss
        hotproc.psinfo.vsize
        hotproc.psinfo.cstime
        hotproc.psinfo.cutime
        hotproc.psinfo.stime
        hotproc.psinfo.utime
        hotproc.io.write_bytes
        hotproc.io.read_bytes
        hotproc.schedstat.cpu_time
        hotproc.fd.count
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enable proc agent to collection more per-process details.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /var/lib/pcp/pmdas/proc
./Install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above configuration only stores interesting process data, it does not archive any details from Apache or PostgreSQL agents. Use &lt;code class=&quot;highlighter-rouge&quot;&gt;pminfo&lt;/code&gt; to list all available metrics and add those to the summary configuration file when needed.&lt;/p&gt;

&lt;p&gt;Apache agent collects basic information from Apache, but it needs the &lt;code class=&quot;highlighter-rouge&quot;&gt;mod_status&lt;/code&gt; plugin to be enabled in Apache (which requires restart of the service). PostgreSQL agent gets basic information about SQL server health, it does not need any restart to be enabled.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /var/lib/pcp/pmdas/apache
./Install
cd /var/lib/pcp/pmdas/postgresql
./Install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For Apache PMDA to work, extended status Apache module must be loaded. Only perform this if you installed the apache PMDA above:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;gt;/etc/httpd/conf.d/01-status.conf &amp;lt;&amp;lt;EOF
ExtendedStatus On
LoadModule status_module modules/mod_status.so

&amp;lt;Location &quot;/server-status&quot;&amp;gt;
PassengerEnabled off
SetHandler server-status
Order deny,allow
Deny from all
Allow from localhost
&amp;lt;/Location&amp;gt;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Foreman installer (Puppet) will delete this file, to prevent this from happening add the following line into &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/foreman-installer/custom-hiera.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apache::purge_configs: false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart of Apache is needed for this, again this can be skipped if Apache PMDA is not being installed.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl restart httpd pmcd pmlogger
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Foreman Rails application provides telemetry data via two endpoints - prometheus and statsd. The former one can be only used in single process environment at the moment, in our case we will configure Rails workers to send metrics via statsd protocol into pcp-mmvstatsd daemon which will provide aggregation and export into PCP MMV API. Monitoring will work the following way:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmcd -&amp;gt; pmda-mmv -&amp;gt; memory mapped file &amp;lt;- pcp-mmvstatsd &amp;lt;- PassengerWorker(s)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install required packages:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum -y install foreman-telemetry pcp-mmvstatsd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enable telemetry support in Foreman settings file /etc/foreman/settings.yaml:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;:telemetry:
  :prefix: 'fm_rails'
  :statsd:
    :enabled: true
    :host: '127.0.0.1:8125'
    :protocol: 'statsd'
  :prometheus:
    :enabled: false
  :logger:
    :enabled: false
    :level: 'INFO'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Keep other exporters (prometheus, logger) disabled and note the port is 8125. Do not use host names in the host setting, make sure it’s set to localhost via IP address 127.0.0.1 for optimal performance. Starting from Foreman 1.19, foreman-installer is getting puppet parameters and CLI options for setting up all options in the settings.yaml file.&lt;/p&gt;

&lt;p&gt;Enable and start the statsd aggregation service:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl enable pcp-mmvstatsd pmcd pmlogger
systemctl start pcp-mmvstatsd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Apache httpd (Passenger) may now be restarted to reload Foreman new configuration - at this point, telemetry data is started to be collected.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the pcp-mmvstatsd daemon listens on all interfaces by default, this can be further hardened via /etc/default/pcp-mmvstatsd or via firewall.&lt;/p&gt;

&lt;p&gt;Dynamic metrics won’t appear automatically in archive files until pmlogger is told to start logging them. This can be performed daily, it’s a fast operation. We recommend to run this on a daily basis:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;gt;/etc/cron.daily/refresh_mmv &amp;lt;&amp;lt;EOF
#!/bin/bash
echo &quot;log mandatory on 1 minute mmv&quot; | /usr/bin/pmlc -P
EOF
chmod +x /etc/cron.daily/refresh_mmv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;user-interface-and-exporting-options&quot;&gt;User interface and exporting options&lt;/h2&gt;

&lt;p&gt;Metrics can now be listed via &lt;code class=&quot;highlighter-rouge&quot;&gt;pminfo&lt;/code&gt; command. Along with other system metrics like CPU, memory, kernel, xfs, disk or network, there are the following metrics which were configured above:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;hotproc.*&lt;/code&gt; - basic metrics of key processes configured above&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;apache.*&lt;/code&gt; - apache httpd server metrics (if configured)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;postgresql.*&lt;/code&gt; - basic postgresql statistics (if configured)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mmv.fm_rails_*&lt;/code&gt; - Foreman Rails metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optionally, to get lists of metrics reported from Rails with descriptions:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;foreman-rake telemetry:metrics
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Resulting table markdown-formatted, here is the result:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Metric name&lt;/th&gt;
      &lt;th&gt;Labels&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_activerecord_instances&lt;/td&gt;
      &lt;td&gt;class&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of instances of ActiveRecord models&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_bruteforce_locked_ui_logins&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of blocked logins via bruteforce protection&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_failed_ui_logins&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of failed logins in total&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_http_request_db_duration&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Time spent in database for a request&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_http_request_total_duration&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Total duration of controller action&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_http_request_view_duration&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Time spent in view for a request&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_http_requests&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;A counter of HTTP requests made&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_importer_facts_count_input&lt;/td&gt;
      &lt;td&gt;type&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of facts before imports starts per importer type&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_importer_facts_count_interfaces&lt;/td&gt;
      &lt;td&gt;type&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of changed interfaces per importer type&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_importer_facts_count_processed&lt;/td&gt;
      &lt;td&gt;type,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of facts processed per importer type&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_importer_facts_import_duration&lt;/td&gt;
      &lt;td&gt;type&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Duration of fact import (ms) per importer type&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_importer_facts_populate_duration&lt;/td&gt;
      &lt;td&gt;type&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Duration of fields population (ms) per importer type&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_proxy_api_duration&lt;/td&gt;
      &lt;td&gt;method&lt;/td&gt;
      &lt;td&gt;histogram&lt;/td&gt;
      &lt;td&gt;Time spent waiting for Proxy (ms)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_proxy_api_response_code&lt;/td&gt;
      &lt;td&gt;code&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of Proxy API responses per HTTP code&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_ruby_gc_allocated_objects&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Ruby GC statistics per req (total_allocated_objects)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_ruby_gc_count&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Ruby GC statistics per request (count)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_ruby_gc_freed_objects&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Ruby GC statistics per request (total_freed_objects)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_ruby_gc_major_count&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Ruby GC statistics per request (major_gc_count)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_ruby_gc_minor_count&lt;/td&gt;
      &lt;td&gt;controller,action&lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Ruby GC statistics per request (minor_gc_count)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fm_rails_successful_ui_logins&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;counter&lt;/td&gt;
      &lt;td&gt;Number of successful logins in total&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There are three types of metrics reported by Rails (this only applies to mmv.* metrics):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;counter - increasing counter, PCP converts this to rate (hits per second)&lt;/li&gt;
  &lt;li&gt;gauge - value observation&lt;/li&gt;
  &lt;li&gt;duration - approximation of time spent using HDR histogram algorithm with instances: mean, min, max, variance and standard_deviation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use PCP tools to monitor deployment live or offline via recorded archive files. A couple of examples now follow. To see instance creation rate of ActiveRecord object User at rate of instancer per second (counter metric):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval mmv.fm_rails_activerecord_instances.User
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see minimum, maximum and average (mean) total duration of dashboard controller index action (duration metric):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval mmv.fm_rails_http_request_total_duration.dashboard_controller.index
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To access remotely, a port needs to be opened:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;firewall-cmd --add-port=44321/tcp
firewall-cmd --permanent --add-port=44321/tcp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then connect remotely (no authorization by default - SSL or password can be set):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo -h remote.host.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are several existing web apps available for PCP to monitor live or archived data using standard web browser: Grafana and Vector. Although PCP core application is in base repository, the web applications are in “optional” repository:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;subscription-manager repos --enable rhel-7-server-optional-rpms
yum -y install pcp-webapi pcp-webapp-grafana pcp-webapp-vector
systemctl start pmwebd
systemctl enable pmwebd
firewall-cmd --add-port=44323/tcp
firewall-cmd --permanent --add-port=44323/tcp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To access the applications, visit the following URLs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;http://foreman:44323/grafana&lt;/li&gt;
  &lt;li&gt;http://foreman:44323/vector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three applications are static JavaScript only apps accessing PCP archival data via a web API - it will only show metrics which are configured to be archived via pmlogger. Beware, Foreman sets HTST flag which forces browsers to HTTPS which is not supported by the built in PCP web server. To workaround that, use different browser or make a DNS alias in order to access those web apps.&lt;/p&gt;

&lt;p&gt;Vector app connect to PCP daemon directly and only shows live data while Grafana app reads archive files and shows historical data up to one year back. For this reason, there is a slight lag of several minutes until values appear in Grafana. Dynamic metrics (MMV) will not appear in archives until refresh_mmv cron job mentioned above is executed.&lt;/p&gt;

&lt;p&gt;PCP data can be exported into external Graphite, InfluxDB or Zabbix applications, consult RHEL and PCP.IO documentation on how to configure that (packages named pcp-export-pcp2graphite, pcp-export-pcp2influxdb and pcp-export-zabbix-agent).&lt;/p&gt;

&lt;p&gt;There is a powerful engine called pmie for taking actions on various events (e.g. process is utilizing CPU or memory too much). This can be used to send e-mails or trigger events (e.g. restart process). Read more about it in the PCP documentation (man pmie).&lt;/p&gt;

&lt;p&gt;Collector daemon and all agents are logging into individual files, check those for errors. Note these log files are not archives of metric data, these are text files where you can find possible configuration errors or warnings:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tail /var/log/pcp/pmcd/*.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Logging daemon also has its own log file:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;less /var/log/pcp/pmlogger/$(hostname)/pmlogger.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s summarize all key daemons which were configured so far:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl status pmcd pmlogger pcp-mmvstatsd pmwebd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;pmcd - collector daemon&lt;/li&gt;
  &lt;li&gt;pmlogger - archiving daemon&lt;/li&gt;
  &lt;li&gt;pcp-mmvstatsd - statsd to MMV PCP aggregator&lt;/li&gt;
  &lt;li&gt;pmwebd - web API with Grafana/Vector (optional)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rest of the article introduces PCP and its tools in more detail.&lt;/p&gt;

&lt;h2 id=&quot;introduction-to-pcp-and-its-tools&quot;&gt;Introduction to PCP and its tools&lt;/h2&gt;

&lt;p&gt;By default, the PCP pmcd daemon collects a reasonable number of system metrics (load, memory, processes, I/O, XFS). Other collector agents (also called PMDAs) can be installed as separate packages. The default probing rate is one second for live monitoring, but when no client utility is connected pmcd idles in the background and consumes effectively no resources.&lt;/p&gt;

&lt;p&gt;When pmlogger daemon is running, the most important metrics are being archived into /var/log/pcp directory, for each day new archive file is created and old files are rotated. One day archive is roughly 25 MB in size (uncompressed data) with most metrics being sampled at one minute interval by default. By default PCP compresses the data and rotates archives every two weeks, highly loaded servers may consume up to 10 GB of historical data.&lt;/p&gt;

&lt;p&gt;To display PCP version, list of enabled agents and active logging archive:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pcp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To display all currently available metrics from the current host:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All metrics are stored in a tree-like structure, to view available metrics under specific subtree, let’s say all network related information, provide node on the command line:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo network
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each metric can be either a single value or a list of values called instances. Kernel load is typical example of metric with three instances (1, 5 and 15 minute average load). To display detailed information about a metric including its types and instances:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo -dfmtT kernel.all.load
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unique feature of PCP is metric metadata, extra information which is available for every metric. This includes expected things like description or data type, but also units and dimensions. This metadata allows one to correctly display data or create correct graphs combining various metrics together. For example, network interface speed has a unit of megabytes per second:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo -dfmtT network.interface.speed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A counter is monotonic increasing or decreasing integer. Thanks to the metadata, PCP can even convert counter values into rates. To monitor live disk write operations per partition using fixed point notation as a rate (operations per second):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -f 1 disk.partitions.write
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see raw counter values instead of rates:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -r disk.partitions.write
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Process data is captured by the proc PMDA (installed and enabled by default). Process ID is the instance name in this case. To monitor the number of open file descriptors of the process with PID 1 every two seconds:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -t 2sec 'proc.fd.count[1]'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s take a look on other utilities from the additional package called pcp-system-tools. Monitor system metrics in a top-like window:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum -y install pcp-system-tools
pcp atop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Monitor CPU-related system metrics and memory in a sar-like (System Activity Report) manner:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pcp atopsar -cm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Monitor system metrics in a sar-like fashion with two second interval:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmstat -t 2sec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Monitor system metrics in an iostat-like fashion with two second interval:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmiostat -t 2sec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Most of these tools operate on archives too, which is a unique feature. It is so easy to “go back in time” and inspect a system with pmstat-like or iostat-like experience easily. The key argument to remember is –archive or -a:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmstat -a /var/log/pcp/pmlogger/$(hostname)/20180503.08.58
pcp atop --archive /var/log/pcp/pmlogger/$(hostname)/20180503.08.58
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another interesting feature leveraged for monitoring of Foreman servers is “hotproc”, or hot processes monitoring. In short, it is possible to set up rules to start monitoring some processes in greater detail. The conditions can be as simple as “all java applications” or “all processes consuming more than 2 GB of memory”. There is a configuration file to store these rules, but it is also possible to enable these on the fly without restarting the PCP daemon:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmstore hotproc.control.config 'fname == &quot;java&quot;'
pminfo -f hotproc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hot process monitoring and logging into archives are flexible features of PCP. An example configuration below starts watching of all java applications running on the server and storing one key metric in archives (RSS memory):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;gt;/var/lib/pcp/pmdas/proc/hotproc.conf &amp;lt;EOF
#pmdahotproc
Version 1.0
fname == &quot;java&quot;
EOF

mkdir -p /var/lib/pcp/config/pmlogconf/my-hotproc
cat &amp;gt;/var/lib/pcp/config/pmlogconf/my-hotproc/summary &amp;lt;&amp;lt; EOF
#pmlogconf-setup 2.0
ident   my-hotproc metrics
probe   hotproc.control.config != &quot;&quot; ? include : exclude
        hotproc.psinfo.rss
EOF

systemctl restart pmcd pmlogger
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see a list of currently archived metrics, do:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;less /var/log/pcp/pmlogger/$(hostname)/pmlogger.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The log file also contains estimation on size, in the example above it is around 13 megabytes per day of uncompressed data. To identify currently active archive file, simply start command “pcp” which also shows other interesting information like number of CPUs, memory, pcp version and timezone.&lt;/p&gt;

&lt;p&gt;There is a low-level control utility for pmlogger that can interactively query current status or change what should be logged:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo status | pmlc -P
echo &quot;query mmv&quot; | pmlc -P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;logging-interval-retention-and-compression&quot;&gt;Logging interval, retention and compression&lt;/h3&gt;

&lt;p&gt;The default logging (sampling) interval is 60 seconds. This interval was chosen as a balance between logging volume and the level of detail needed for long term monitoring. To change that setting, edit /etc/pcp/pmlogger/control.d/local and append -t XXs to the line for LOCALHOSTNAME, and restart the pmlogger service.&lt;/p&gt;

&lt;p&gt;The default retention policy is to keep archives for the last 14 days, compressing archives older than one day with xz. To change these settings, edit /etc/cron.d/pcp-pmlogger file and use -x and -k options. For example, “-x 4 -k 7” options on the first line will compress archives after 4 days and delete after 7 days.&lt;/p&gt;

&lt;h3 id=&quot;retrospective-performance-analysis&quot;&gt;Retrospective Performance Analysis&lt;/h3&gt;

&lt;p&gt;PCP archive logs are located under /var/log/pcp/pmlogger/$(hostname) and they can be easily transferred for offline inspection. A simple utility which is able to dump raw data from archives is available. To check the host and the time period an archive covers:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AVE=/var/log/pcp/pmlogger/$(hostname)/20170918.13.59
pmdumplog -l $AVE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check PCP configuration at the time when an archive was created:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pcp -a $AVE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Display all enabled performance metrics at the time when an archive was created:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo -a $AVE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Display detailed information about a performance metric at the time when an archive was created:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pminfo -a $AVE -df mem.freemem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dump past disk write operations per partition in an archive using fixed point notation:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -a $AVE -f1 disk.partitions.write
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dump RSS memory consumed by two particular processes configured via hotproc above (the PIDs will be likely different):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -a $AVE hotproc.psinfo.rss -i 000768 -i 000977
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Replay past disk write operations per partition in an archive with two second interval using fixed point notation between 14:00 and 14:15:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmval -a $AVE -d -t 2sec -f 3 disk.partitions.write -S @14:00 -T @14:15
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Print subnet controller index action average total processing time with number of instances created for Subnet and Setting models and total number of Ruby allocation objects for the same controller and action (all on one line)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmrep mmv.statsd.fm_rails_http_request_total_duration.subnets_controller.index mmv.statsd.fm_rails_activerecord_instances.Subnet mmv.statsd.fm_rails_activerecord_instances.Setting mmv.statsd.fm_rails_ruby_gc_allocated_objects.subnets_controller.index
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Calculate average values of performance metrics in a time interval using tabular formatting including the time of minimum/maximum value and the actual minimum/maximum value:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmlogsummary -HlfiImM -S @14:00 -T @14:30 $AVE disk.partitions.write mem.freemem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Replay past system metrics in an archive in a top-like window starting at 2 PM:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pcp -a $AVE -S @14:00 atop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Most of the PCP utilities supports -a (–archive) option, including pmstat, pmiostat or pmchart, an interactive GUI application written in QT with plotting capabilities. A REST API exposing live or historical data can be installed for integration with other applications.&lt;/p&gt;

&lt;p&gt;The utility atop also supports hot processes via an explicit option which is very handy back-in-time top-like experience:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pcp -a $AVE -S @14:00 atop --hotproc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One important command can deliver quick calculation of average, min and max values:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pmlogsummary archive_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The pmdiff utility uses pmlogsummary to compare archives or time windows of interest, and reports those metric whose values have changed the most in the times being compared.&lt;/p&gt;

&lt;p&gt;PCP ships with a powerful GUI utility for plotting live or offline graphs called pmchart. It works under Linux and MacOS.&lt;/p&gt;

&lt;p&gt;We have just scratched the surface, PCP offers derived metrics via simple arithmetics, PMIE (metrics inference engine) for alerting (sending emails or executing arbitrary commands), application instrumentation and tracing APIs. For more information, use the official RHEL or PCP documentation.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-performance_monitoring_tools-performance_co_pilot_pcp&lt;/li&gt;
  &lt;li&gt;https://access.redhat.com/articles/1145953&lt;/li&gt;
  &lt;li&gt;http://pcp.io/docs/guide.html&lt;/li&gt;
  &lt;li&gt;https://access.redhat.com/articles/2450251&lt;/li&gt;
  &lt;li&gt;https://access.redhat.com/videos/898313&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Lukáš Zapletal</name><uri>lzap</uri></author><category term="foreman" /><category term="telemetry" /><summary type="html">Performance Co-Pilot (PCP) is an open source framework and toolkit for monitoring and analyzing live and historical system performance. It provides high-resolution live monitoring from local or remote hosts (with optional auto-discovery) and instrumented software. PCP can be integrated with monitoring solutions like Graphite (Carbon/Whisper), InfluxDB, Zabbix or Nagios, or configured to store historical data into archive files which is a unique feature we want to take advantage from. PCP follows UNIX tradition by providing a relatively large collection of small utilities which do their job well. There are several APIs available to write collecting agents called PMDAs or to instrument existing applications to gather “telemetry” data. APIs are available mostly in C, Python and Perl out of box with extra wrappers or native libraries in Java, Rust and Golang. PCP is a compact package (under one megabyte) with minimum dependencies and part of standard RHEL7 base repositories. The article covers PCP installation, basic operating system monitoring configuration with extra monitoring of key processes and PostgreSQL and Apache httpd. It also shows how to setup Foreman Ruby on Rails monitoring to read internal metrics from Foreman 1.18 core application. Major areas covered: basic system monitoring (load, memory, IO) hot processes (memory and cpu utilization) Apache httpd monitoring PostgreSQL monitoring Foreman Rails application instrumentation all relevant metrics archival for retrospective troubleshooting Second part of the article covers analysis of results using PCP CLI and web UI tools and retrospective analysis.</summary></entry><entry><title type="html">Contributing to the Katello API</title><link href="http://theforeman.org/2018/07/katello-add-api-and-task.html" rel="alternate" type="text/html" title="Contributing to the Katello API" /><published>2018-07-03T12:00:00+00:00</published><updated>2018-07-03T12:00:00+00:00</updated><id>http://theforeman.org/2018/07/katello-add-api-and-task</id><content type="html" xml:base="http://theforeman.org/2018/07/katello-add-api-and-task.html">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;If you have used the Katello API a lot, you have almost certainly found areas where the API is difficult to use. Fortunately, it is easy to add a new API call, or add features to an existing call.&lt;/p&gt;

&lt;p&gt;This tutorial will show how to add a new API, and how to add a new asynchrnous task. Adding an asynchronous task is not always needed, but is a common requirement.&lt;/p&gt;

&lt;p&gt;You’ll need to write tests for any code you commit, which is outside the scope of this document.&lt;/p&gt;

&lt;h2 id=&quot;initial-setup&quot;&gt;Initial setup&lt;/h2&gt;

&lt;p&gt;You’ll need to run through a forklift development setup. Instructions are located in the &lt;a href=&quot;https://github.com/theforeman/forklift#quickstart&quot;&gt;forklift README&lt;/a&gt;. You’ll be running &lt;code class=&quot;highlighter-rouge&quot;&gt;foreman start&lt;/code&gt; in one terminal window, and making edits using another terminal window.&lt;/p&gt;

&lt;h2 id=&quot;making-an-api-call&quot;&gt;Making an API call&lt;/h2&gt;

&lt;p&gt;The first order of business is to make an existing API call in your development environment. This will ensure that your development environment is working, and it will show an example of how to make API calls with cURL.&lt;/p&gt;

&lt;p&gt;To make the call, simply run &lt;code class=&quot;highlighter-rouge&quot;&gt;curl -s -k https://admin:changeme@localhost/katello/api/v2/ping | python -mjson.tool&lt;/code&gt;. You should get this back:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
    &quot;services&quot;: {
        &quot;candlepin&quot;: {
            &quot;duration_ms&quot;: &quot;36&quot;,
            &quot;status&quot;: &quot;ok&quot;
        },
        &quot;candlepin_auth&quot;: {
            &quot;duration_ms&quot;: &quot;38&quot;,
            &quot;status&quot;: &quot;ok&quot;
        },
        &quot;foreman_tasks&quot;: {
            &quot;duration_ms&quot;: &quot;862&quot;,
            &quot;status&quot;: &quot;ok&quot;
        },
        &quot;pulp&quot;: {
            &quot;duration_ms&quot;: &quot;141&quot;,
            &quot;status&quot;: &quot;ok&quot;
        },
        &quot;pulp_auth&quot;: {
            &quot;duration_ms&quot;: &quot;124&quot;,
            &quot;status&quot;: &quot;ok&quot;
        }
    },
    &quot;status&quot;: &quot;ok&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;python -mjson.tool&lt;/code&gt; command simply reformats the JSON output into a more human-readable form.&lt;/p&gt;

&lt;h2 id=&quot;adding-code-to-an-existing-api-call&quot;&gt;Adding code to an existing API call&lt;/h2&gt;

&lt;p&gt;Now that we know everything is working, we can modify an existing call. If you are new at this, it’s good to work through everything one step at a time. This makes it easy to figure out what happened if something is broken. Let’s add a logging statement, and then see if it worked.&lt;/p&gt;

&lt;p&gt;In the Katello project, edit &lt;code class=&quot;highlighter-rouge&quot;&gt;./app/controllers/katello/api/v2/ping_controller.rb&lt;/code&gt; and add a logging statement like so:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;api&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/ping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;N_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Shows status of system and it's subcomponents&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;N_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;This service is only available for authenticated users&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ping!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# this is the line we added&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;respond_for_show&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Ping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ping&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After you make this change, you’ll need to hit &lt;code class=&quot;highlighter-rouge&quot;&gt;^C&lt;/code&gt; on your rails development server and reload it for the change to take effect.&lt;/p&gt;

&lt;p&gt;After the restart is complete, run the same curl command again. You’ll see this in the development server output:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;18:26:45 rails.1   | 2018-07-03T18:26:45 [W|app|9a453] ping! 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;adding-a-new-api-call&quot;&gt;Adding a new API call&lt;/h2&gt;

&lt;p&gt;We were able to add some example code to an existing API call. Let’s now add a new API call in the same controller.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE:&lt;/em&gt; This example is a bit different since we are adding a URL to the top-level, as a peer to “/ping”. You’ll usually want to add something underneath your controller’s top level URL, like “/ping/example” instead of “/example”.&lt;/p&gt;

&lt;p&gt;Pull up &lt;code class=&quot;highlighter-rouge&quot;&gt;./app/controllers/katello/api/v2/ping_controller.rb&lt;/code&gt; again, and add this. It is copied from the &lt;code class=&quot;highlighter-rouge&quot;&gt;index&lt;/code&gt; method, and we simply changed some references from “index” to “example”:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;api&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;N_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;An example API call&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;N_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;an example API call&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;example&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;example!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;respond_for_show&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Ping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ping&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Save the file, restart your dev server, and run &lt;code class=&quot;highlighter-rouge&quot;&gt;curl -s -k https://admin:changeme@localhost/katello/api/v2/example&lt;/code&gt;. Surprise! You got a 404. We need to also tell Katello about a new &lt;em&gt;route&lt;/em&gt; for your new API call.&lt;/p&gt;

&lt;p&gt;Edit &lt;code class=&quot;highlighter-rouge&quot;&gt;config/routes/api/v2.rb&lt;/code&gt; and make a change like so:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;n&quot;&gt;api_resources&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:only&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/status&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ping#server_status&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:via&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/example&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ping#example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:via&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# this is the line we added&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, restart your development server once more, run your curl command and it should return some json, along with printing the message &lt;code class=&quot;highlighter-rouge&quot;&gt;example!&lt;/code&gt; in the log file. Congrats!&lt;/p&gt;

&lt;h2 id=&quot;creating-a-task&quot;&gt;Creating a task&lt;/h2&gt;

&lt;p&gt;You can perform work either directly in Katello’s API code which will return synchronously, or via an asynchronous task. This section describes how to make a task and have it execute when your API is called.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE:&lt;/em&gt; If you are unsure if you need to create a task or not, feel free to ask on the &lt;a href=&quot;https://community.theforeman.org/c/development&quot;&gt;Community Forums&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;executing-an-existing-task-via-rake-console&quot;&gt;Executing an existing task via rake console&lt;/h2&gt;

&lt;p&gt;Let’s kick off a task via the rake console. Just run &lt;code class=&quot;highlighter-rouge&quot;&gt;rails console&lt;/code&gt; from the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/foreman&lt;/code&gt; directory on your development environment.&lt;/p&gt;

&lt;p&gt;First, let’s try to find a host that we can reference later. Try running &lt;code class=&quot;highlighter-rouge&quot;&gt;::Host::Managed.first&lt;/code&gt;. It will either raise an error, or return something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;=&amp;gt; #&amp;lt;Host::Managed id: 1, name: &quot;centos7-devel.example.com&quot;, last_compile: &quot;2018-06-22 12:57:44&quot;, last_report: nil, updated_at: &quot;2018-06-22 12:57:50&quot;, created_at: &quot;2018-06-15 14:45:39&quot;, root_pass: nil, architecture_id: 1, operatingsystem_id: nil, environment_id: nil, ptable_id: nil, medium_id: nil, build: false, comment: nil, disk: nil, installed_at: nil, model_id: 1, hostgroup_id: nil, owner_id: 4, owner_type: &quot;User&quot;, enabled: true, puppet_ca_proxy_id: nil, managed: false, use_image: nil, image_file: nil, uuid: nil, compute_resource_id: nil, puppet_proxy_id: nil, certname: nil, image_id: nil, organization_id: 1, location_id: 2, type: &quot;Host::Managed&quot;, otp: nil, realm_id: nil, compute_profile_id: nil, provision_method: nil, grub_pass: &quot;&quot;, content_view_id: nil, lifecycle_environment_id: nil, global_status: 1, lookup_value_matcher: &quot;fqdn=centos7-devel.example.com&quot;, pxe_loader: nil&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you get an error, it probably means that you simply need to register a host. Once a host is registered, it should work.&lt;/p&gt;

&lt;p&gt;Now, let’s kick off a task in the console:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ForemanTasks.async_task(::Actions::Katello::Host::GenerateApplicability, [::Host::Managed.first], false)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see a lot of output. If you go into the “tasks” page in the web UI, you’ll see that the task executed. Very cool!&lt;/p&gt;

&lt;h2 id=&quot;adding-your-own-task&quot;&gt;Adding your own task&lt;/h2&gt;

&lt;p&gt;Now that we know how to execute tasks, we can create our own and try to run it. Create a file in &lt;code class=&quot;highlighter-rouge&quot;&gt;app/lib/actions/katello/content_view/example.rb&lt;/code&gt; that looks something like this:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Actions&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Katello&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ContentView&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Example&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Actions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;plan&lt;/span&gt;
              &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;an example!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;c1&quot;&gt;# without this line, the task will not go into 'run' phase after planning.&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;plan_self&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
     
            &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;humanized_name&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, try this from the console:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ForemanTasks.async_task(::Actions::Katello::ContentView::Example)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If all went well, you should see your task get executed.&lt;/p&gt;

&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h2&gt;

&lt;p&gt;Now that you can create an API call, create a task and execute a task, you can put it all together into an API call that executes a task. This is left as an exercise to the reader, but one way to write the API method would be like this:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;example&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;example!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async_task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Actions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Katello&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;respond_for_async&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Try using your curl call on this, and the task should fire. Congratulations!&lt;/p&gt;</content><author><name>Christopher Duryee</name><uri>Chris_Duryee</uri></author><category term="foreman" /><summary type="html">Introduction If you have used the Katello API a lot, you have almost certainly found areas where the API is difficult to use. Fortunately, it is easy to add a new API call, or add features to an existing call. This tutorial will show how to add a new API, and how to add a new asynchrnous task. Adding an asynchronous task is not always needed, but is a common requirement. You’ll need to write tests for any code you commit, which is outside the scope of this document. Initial setup You’ll need to run through a forklift development setup. Instructions are located in the forklift README. You’ll be running foreman start in one terminal window, and making edits using another terminal window. Making an API call The first order of business is to make an existing API call in your development environment. This will ensure that your development environment is working, and it will show an example of how to make API calls with cURL. To make the call, simply run curl -s -k https://admin:changeme@localhost/katello/api/v2/ping | python -mjson.tool. You should get this back: { &quot;services&quot;: { &quot;candlepin&quot;: { &quot;duration_ms&quot;: &quot;36&quot;, &quot;status&quot;: &quot;ok&quot; }, &quot;candlepin_auth&quot;: { &quot;duration_ms&quot;: &quot;38&quot;, &quot;status&quot;: &quot;ok&quot; }, &quot;foreman_tasks&quot;: { &quot;duration_ms&quot;: &quot;862&quot;, &quot;status&quot;: &quot;ok&quot; }, &quot;pulp&quot;: { &quot;duration_ms&quot;: &quot;141&quot;, &quot;status&quot;: &quot;ok&quot; }, &quot;pulp_auth&quot;: { &quot;duration_ms&quot;: &quot;124&quot;, &quot;status&quot;: &quot;ok&quot; } }, &quot;status&quot;: &quot;ok&quot; } The python -mjson.tool command simply reformats the JSON output into a more human-readable form. Adding code to an existing API call Now that we know everything is working, we can modify an existing call. If you are new at this, it’s good to work through everything one step at a time. This makes it easy to figure out what happened if something is broken. Let’s add a logging statement, and then see if it worked. In the Katello project, edit ./app/controllers/katello/api/v2/ping_controller.rb and add a logging statement like so: api :GET, &quot;/ping&quot;, N_(&quot;Shows status of system and it's subcomponents&quot;) description N_(&quot;This service is only available for authenticated users&quot;) def index Rails.logger.warn(&quot;ping!&quot;) # this is the line we added respond_for_show :resource =&amp;gt; Ping.ping end After you make this change, you’ll need to hit ^C on your rails development server and reload it for the change to take effect. After the restart is complete, run the same curl command again. You’ll see this in the development server output: 18:26:45 rails.1 | 2018-07-03T18:26:45 [W|app|9a453] ping! Adding a new API call We were able to add some example code to an existing API call. Let’s now add a new API call in the same controller. NOTE: This example is a bit different since we are adding a URL to the top-level, as a peer to “/ping”. You’ll usually want to add something underneath your controller’s top level URL, like “/ping/example” instead of “/example”. Pull up ./app/controllers/katello/api/v2/ping_controller.rb again, and add this. It is copied from the index method, and we simply changed some references from “index” to “example”: api :GET, &quot;/example&quot;, N_(&quot;An example API call&quot;) description N_(&quot;an example API call&quot; def example Rails.logger.warn(&quot;example!&quot;) respond_for_show :resource =&amp;gt; Ping.ping end Save the file, restart your dev server, and run curl -s -k https://admin:changeme@localhost/katello/api/v2/example. Surprise! You got a 404. We need to also tell Katello about a new route for your new API call. Edit config/routes/api/v2.rb and make a change like so: api_resources :ping, :only =&amp;gt; [:index] match &quot;/status&quot; =&amp;gt; &quot;ping#server_status&quot;, :via =&amp;gt; :get match &quot;/example&quot; =&amp;gt; &quot;ping#example&quot;, :via =&amp;gt; :get # this is the line we added Now, restart your development server once more, run your curl command and it should return some json, along with printing the message example! in the log file. Congrats! Creating a task You can perform work either directly in Katello’s API code which will return synchronously, or via an asynchronous task. This section describes how to make a task and have it execute when your API is called. NOTE: If you are unsure if you need to create a task or not, feel free to ask on the Community Forums. Executing an existing task via rake console Let’s kick off a task via the rake console. Just run rails console from the ~/foreman directory on your development environment. First, let’s try to find a host that we can reference later. Try running ::Host::Managed.first. It will either raise an error, or return something like this: =&amp;gt; #&amp;lt;Host::Managed id: 1, name: &quot;centos7-devel.example.com&quot;, last_compile: &quot;2018-06-22 12:57:44&quot;, last_report: nil, updated_at: &quot;2018-06-22 12:57:50&quot;, created_at: &quot;2018-06-15 14:45:39&quot;, root_pass: nil, architecture_id: 1, operatingsystem_id: nil, environment_id: nil, ptable_id: nil, medium_id: nil, build: false, comment: nil, disk: nil, installed_at: nil, model_id: 1, hostgroup_id: nil, owner_id: 4, owner_type: &quot;User&quot;, enabled: true, puppet_ca_proxy_id: nil, managed: false, use_image: nil, image_file: nil, uuid: nil, compute_resource_id: nil, puppet_proxy_id: nil, certname: nil, image_id: nil, organization_id: 1, location_id: 2, type: &quot;Host::Managed&quot;, otp: nil, realm_id: nil, compute_profile_id: nil, provision_method: nil, grub_pass: &quot;&quot;, content_view_id: nil, lifecycle_environment_id: nil, global_status: 1, lookup_value_matcher: &quot;fqdn=centos7-devel.example.com&quot;, pxe_loader: nil&amp;gt; If you get an error, it probably means that you simply need to register a host. Once a host is registered, it should work. Now, let’s kick off a task in the console: ForemanTasks.async_task(::Actions::Katello::Host::GenerateApplicability, [::Host::Managed.first], false) You should see a lot of output. If you go into the “tasks” page in the web UI, you’ll see that the task executed. Very cool! Adding your own task Now that we know how to execute tasks, we can create our own and try to run it. Create a file in app/lib/actions/katello/content_view/example.rb that looks something like this: module Actions module Katello module ContentView class Example &amp;lt; Actions::Base def plan Rails.logger.warn(&quot;an example!&quot;) # without this line, the task will not go into 'run' phase after planning. plan_self end def humanized_name _(&quot;Example&quot;) end end end end end Then, try this from the console: ForemanTasks.async_task(::Actions::Katello::ContentView::Example) If all went well, you should see your task get executed. Putting it all together Now that you can create an API call, create a task and execute a task, you can put it all together into an API call that executes a task. This is left as an exercise to the reader, but one way to write the API method would be like this: def example Rails.logger.warn(&quot;example!&quot;) task = async_task(::Actions::Katello::ContentView::Example) respond_for_async :resource =&amp;gt; task end Try using your curl call on this, and the task should fire. Congratulations!</summary></entry><entry><title type="html">Foreman Community Newsletter - June 2018</title><link href="http://theforeman.org/2018/06/foreman-community-newsletter-june-2018.html" rel="alternate" type="text/html" title="Foreman Community Newsletter - June 2018" /><published>2018-06-28T10:17:00+00:00</published><updated>2018-06-28T10:17:00+00:00</updated><id>http://theforeman.org/2018/06/foreman-community-newsletter---june-2018</id><content type="html" xml:base="http://theforeman.org/2018/06/foreman-community-newsletter-june-2018.html">&lt;h3 id=&quot;foreman-118-rc1-and-rc2-and-test-week-event---rc3-next-week&quot;&gt;Foreman 1.18 RC1 and RC2 (and test week event) -&amp;gt; RC3 next week&lt;/h3&gt;

&lt;p&gt;The next major release for Foreman is undergoing final testing, and the first
release candidate &lt;a href=&quot;https://community.theforeman.org/t/1-18-0-rc1-has-been-released/9987&quot;&gt;came out&lt;/a&gt; on June 12th, with a ton of fixes and
updates. We then held a successful &lt;a href=&quot;https://community.theforeman.org/t/foreman-1-18-test-week/9989&quot;&gt;1.18 test week&lt;/a&gt; (kindly
organised by &lt;a href=&quot;https://community.theforeman.org/u/lzap&quot;&gt;Lukas&lt;/a&gt;) which aimed to cover a lot of the common scenarios
for RC testing. This was largely successful, and many bugs were logged and
looked at. Thanks to everyone for helping out!&lt;/p&gt;

&lt;p&gt;We’ve just released &lt;a href=&quot;https://community.theforeman.org/t/1-18-0-rc2-has-been-released/10147&quot;&gt;1.18 RC2&lt;/a&gt; for the next round of testing, so give
it a spin and let us know how you get on - and do &lt;a href=&quot;https://projects.theforeman.org/issues&quot;&gt;report issues&lt;/a&gt; as
you find them! We couldn’t do this without the testing we get from the
community, so thanks very much to you all!&lt;/p&gt;

&lt;p&gt;Late-breaking news! I’m told that RC3 will be out early next week, so you may
want to hold off a few days!&lt;/p&gt;

&lt;h3 id=&quot;katello-37-rc1&quot;&gt;Katello 3.7 RC1&lt;/h3&gt;

&lt;p&gt;To go with 1.18 RC1/2, there is also an RC1 release of the &lt;a href=&quot;https://community.theforeman.org/t/katello-3-7-rc1-available-for-testing/10060&quot;&gt;next Katello
version&lt;/a&gt;. Again, lots of bug fixes and new features are in this
release, so please do check it out, and &lt;a href=&quot;https://projects.theforeman.org/projects/katello/issues&quot;&gt;report issues&lt;/a&gt; if you find
any. Thanks!&lt;/p&gt;

&lt;h3 id=&quot;new-release-manager&quot;&gt;New Release Manager&lt;/h3&gt;

&lt;p&gt;It’s no secret that build stability has been an issue for some time in the
nightlies, and that’s had a knock-on effect on release schedules, etc.&lt;/p&gt;

&lt;p&gt;To try to address this, &lt;a href=&quot;https://community.theforeman.org/u/tbrisker&quot;&gt;Tomer Brisker&lt;/a&gt; has accepted the role of
Release Manager, and will be actively working to improve the state of the build
pipeline. You can read all about his &lt;a href=&quot;https://community.theforeman.org/t/releases-and-nightlies-stabilization-effort/10037&quot;&gt;new role
here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tomer’s long-time experience in the Foreman project, as his attention to
detail, is a welcome addition to this area of the project - I’m sure he’ll have
an impact. Thanks Tomer!&lt;/p&gt;

&lt;h3 id=&quot;survey-analysis&quot;&gt;Survey analysis&lt;/h3&gt;

&lt;p&gt;Earlier in the year we asked you all to fill in our survey, as we do every
year. I’ve had chance to at least do some descriptive analysis of the raw data,
and do some comparisons to the 2017 data. If you’re interested in the results,
check them out
&lt;a href=&quot;https://theforeman.org/2018/06/2018-foreman-survey-analysis.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;blog--forum-integration&quot;&gt;Blog &amp;amp; Forum integration&lt;/h3&gt;

&lt;p&gt;Staying with the blog, we’ve also enabled comments on the blog again (after a
&lt;em&gt;long&lt;/em&gt; absence), which now uses our
[forum][https://community.theforeman.org/c/blog] to store the comments. As a
side effect, you can now read the blog on our forum too, if that’s more your
style. Scroll to the bottom of this post to check it out!&lt;/p&gt;

&lt;h3 id=&quot;redmine-upgrade&quot;&gt;Redmine upgrade&lt;/h3&gt;

&lt;p&gt;In a short while, we’ll start the long-delayed upgrade to our bug tracker. This
has blocked for a long time because of the unmaintained plugins we were using,
but there is now &lt;a href=&quot;https://community.theforeman.org/t/redmine-plugin-spec/10012/7&quot;&gt;a
plan&lt;/a&gt; in place
to move past this. Work is scheduled to start soon, so you may see some
instability in the bug tracker at times - details will be posted to the forum,
of course.&lt;/p&gt;

&lt;h3 id=&quot;plugin-maintainers-wanted&quot;&gt;Plugin Maintainers wanted!&lt;/h3&gt;

&lt;p&gt;Many of our plugins suffer compatibility issues and/or changes in the projects
they integrate with over time - when Foreman changes, or (for example) Salt
released a new version, plugins can be affected. Sadly, several plugins hit by
this have not been maintained, and are now facing being retired from the plugin
repository.&lt;/p&gt;

&lt;p&gt;If you’re interesting in helping contribute to the community by helping to fix
a plugin you rely on, please get in touch! Currently we’d &lt;em&gt;love&lt;/em&gt; some help
with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ABRT&lt;/li&gt;
  &lt;li&gt;Chef&lt;/li&gt;
  &lt;li&gt;Salt&lt;/li&gt;
  &lt;li&gt;Compute resources:
    &lt;ul&gt;
      &lt;li&gt;Azure&lt;/li&gt;
      &lt;li&gt;GCE&lt;/li&gt;
      &lt;li&gt;EC2&lt;/li&gt;
      &lt;li&gt;Rackspace&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these plugins matter to you (or you want to contribute to &lt;em&gt;another&lt;/em&gt;
plugin!), but don’t know where to start, come &lt;a href=&quot;https://community.theforeman.org/u/gwmngilfen&quot;&gt;talk to me&lt;/a&gt; and I’ll help
you get started. You can also join the [dev discussion][plugins].&lt;/p&gt;

&lt;h3 id=&quot;rfcs-needing-attention&quot;&gt;RFCs needing attention&lt;/h3&gt;

&lt;p&gt;I’m going to start highlighting open RFCs that might benefit from more
eyeballs. Here’s this month’s selection:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/rfc-bare-metal-provisioning-with-m2-in-foreman/10061&quot;&gt;M2 MaaS provisioning&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/move-gce-to-a-plugin/10038&quot;&gt;Move GCE to a plugin&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/split-host-groups-and-puppet-classes-ansible-roles/9949&quot;&gt;Split Hostgroups and Puppet Classes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/drop-stable-link-in-deb-repos/9960&quot;&gt;Drop the ‘stable’ link in the DEB repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;upcoming-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/calendar&quot;&gt;Upcoming Events&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The Foreman Community has now fully embraced Discourse as the source of its
event data - if you’ve been using the old &lt;code class=&quot;highlighter-rouge&quot;&gt;/events/all.ics&lt;/code&gt; in your own
calendar, you’ll need to head over to &lt;a href=&quot;https://community.theforeman.org/calendar&quot;&gt;the forum
calendar&lt;/a&gt; and hit the Subscribe
button (which will give you an ICS link). You can also use the Add To Calendar
button on specific events if you don’t wish to import the whole thing.&lt;/p&gt;

&lt;p&gt;Future community demos will now be created much further in advance, so you
should be able to keep up with upcoming demos there (currently I’ve created
topics out to August :P)o&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/lets-celebrate-the-9th-anniversary-of-the-foreman-project/10079&quot;&gt;Foreman’s 9th Birthday @ ATIX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A one-day unconference / hack session in honour of our birthday, hosted by our
good friends at &lt;a href=&quot;https://www.atix.de&quot;&gt;ATIX&lt;/a&gt; - thanks!&lt;/p&gt;

&lt;p&gt;We’d like some more speakers for this, so please &lt;a href=&quot;https://community.theforeman.org/u/gwmngilfen&quot;&gt;get in touch&lt;/a&gt; if you
want to go along!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/open-source-summit-eu-2018-edinburgh-october/10081&quot;&gt;CFP closing for Open Source Summit EU, Edinburgh, October&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s going to be &lt;em&gt;some&lt;/em&gt; kind of Foreman presence at OSS-EU this year, but
the CFP for presentations closes &lt;em&gt;this week&lt;/em&gt; (SUnday 1st) - so if you want to
get your entry paid for, get your submissions in right away!&lt;/p&gt;

&lt;h4 id=&quot;past-events&quot;&gt;&lt;a href=&quot;https://community.theforeman.org/c/events/l/latest&quot;&gt;Past Events&lt;/a&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/open-source-camp-berlin-14-june/8738&quot;&gt;OpenSourceCamp.de&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our first ever Foreman-headlined conference was held earlier this month, and
was great fun - thanks to our partners at NETWAYS and Graylog for helping to
make this event happen. A full day of talks, hacking, and discussion,
thoroughly enjoyed by all (so I am told :P)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-45/9698&quot;&gt;Community Demo - 31st May&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Containers, backups, and oVirt, oh my! A return to force for the demo, with
great content from all the presenters.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-community-demo-46/9732&quot;&gt;Community Demo - 21st June&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A packed demo, covering the Redmine and Survey results mentioned above, as well
as foreman-hooks for content, more Docker support, better state handling for
unattended installs (awesome!) and more. One to watch.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.theforeman.org/t/foreman-usability-audits-ui/10093&quot;&gt;UX Dive on the Audits page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tereza Novotna took us through the proposed wireframes for the old Audits UI,
which has been in need of love for some time. We also had time for a solid
discussion around filtering vs sorting, and tables vs list views.&lt;/p&gt;

&lt;h3 id=&quot;plugin-news&quot;&gt;Plugin news&lt;/h3&gt;

&lt;p&gt;Updated plugins:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/hammer_cli_foreman_remote_execution&quot;&gt;hammer_cli_foreman_remote_execution&lt;/a&gt; updated to 0.1.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_chef&quot;&gt;foreman_chef&lt;/a&gt; updated to 0.8.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_tasks&quot;&gt;foreman_tasks&lt;/a&gt; updated to 0.13.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_remote_execution&quot;&gt;foreman_remote_execution&lt;/a&gt;to 1.5.3&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_discovery&quot;&gt;foreman_discovery&lt;/a&gt; updated to 12.0.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_docker&quot;&gt;foreman_docker&lt;/a&gt; updated to 4.1.0&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_openscap&quot;&gt;foreman_openscap&lt;/a&gt; updated to 0.10.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Katello/hammer-cli-katello&quot;&gt;hammer_cli_katello&lt;/a&gt; updated to 0.13.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_memcache&quot;&gt;foreman_memcache&lt;/a&gt; updated to 0.1.1&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/smart_proxy_monitoring&quot;&gt;smart_proxy_monitoring&lt;/a&gt; updated to 0.1.2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/smart_proxy_omaha&quot;&gt;smart_proxy_omaha&lt;/a&gt; updated to 0.0.4&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/theforeman/foreman_virt_who_configure&quot;&gt;foreman_virt_who_configure&lt;/a&gt; updated to 0.2.2&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;

&lt;p&gt;Thanks to everyone who contributes to the Foreman community - patches, plugins,
testing, bug reports, translations, interviews, presentations, meetups and
everything else. Your efforts are very much appreciated!&lt;/p&gt;</content><author><name>Greg Sutcliffe</name><uri>gwmngilfen</uri></author><category term="foreman" /><category term="newsletter" /><category term="community" /><summary type="html">Foreman 1.18 RC1,2 &amp; 3, Katello 3.7 RC1, survey data, Redmine, blog integration, and more!</summary></entry><entry><title type="html">Building Ubuntu Using Katello File Repo</title><link href="http://theforeman.org/2018/06/creating-ubuntu-repo-in-katello.html" rel="alternate" type="text/html" title="Building Ubuntu Using Katello File Repo" /><published>2018-06-20T00:00:00+00:00</published><updated>2018-06-20T00:00:00+00:00</updated><id>http://theforeman.org/2018/06/creating-ubuntu-repo-in-katello</id><content type="html" xml:base="http://theforeman.org/2018/06/creating-ubuntu-repo-in-katello.html">&lt;p&gt;&lt;em&gt;NOTE:&lt;/em&gt; This blog post describes how to use Katello 3.5 to host Ubuntu repos, and is aimed at those wanting to get Apt repo support going without upgrading. If you are using a later version of Katello, it may already support deb packages natively.&lt;/p&gt;

&lt;h1 id=&quot;building-ubuntu-using-katello-file-repo&quot;&gt;Building Ubuntu Using Katello File Repo&lt;/h1&gt;
&lt;p&gt;I have an offline network and need to build both RPM based systems and DEB based systems. Instead of installing Katello to handle rpms, and something else to handle debs, I set up Katello to handle both.&lt;/p&gt;

&lt;h2 id=&quot;get-local-copy-of-repo&quot;&gt;Get Local Copy of Repo&lt;/h2&gt;
&lt;p&gt;I created a script to do this for me, with following assumptions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Using box that has debmirror installed
    &lt;ul&gt;
      &lt;li&gt;Installing this on a Fedora box required me to remove /etc/debmirror.conf for this script to work&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Has rsync installed&lt;/li&gt;
  &lt;li&gt;Media is mounted at /mnt has enough space to copy the repo&lt;/li&gt;
  &lt;li&gt;The example is downloading xenial, but can be duplicated to do other releases.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;/mnt has a copy of &lt;a href=&quot;https://gist.github.com/jlsherrill/e7c72e1ed82379955c2208ac472b0be7&quot;&gt;file_repogen.rb&lt;/a&gt;&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
 &lt;span class=&quot;nv&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;amd64
 &lt;span class=&quot;nv&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;main,restricted,universe,multiverse,main/debain-installer,universe/debian-installer,multiver/debian-installer,restricted/debian-installer
 &lt;span class=&quot;nv&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;xenial,xenial-updates
 &lt;span class=&quot;nv&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;us.archive.ubuntu.com
 &lt;span class=&quot;nv&quot;&gt;inpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/ubuntu
 &lt;span class=&quot;nv&quot;&gt;outpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt/ubuntu/xenial

 debmirror &lt;span class=&quot;nt&quot;&gt;--arch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arch&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--no-source&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--section&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$section&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$server&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$release&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--di-dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;dists &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--di-arch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;arches &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$inpath&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--progress&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--ignore-release-gpg&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--no-check-gpg&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--exclude-deb-section&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;games &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--exclude&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;sid &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nt&quot;&gt;--method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;rsync &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 	    &lt;span class=&quot;nv&quot;&gt;$outpath&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

 	for i in $(echo $release | sed “s/,/ /g”); do
 		rsync -L –progress –exclude=*i386 -a rsync://$server/ubuntu/dists/$i $outpath/dists/
 	done

 	/mnt/file_repogen.rb /mnt/ubuntu/xenial
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;import-into-katello&quot;&gt;Import into Katello&lt;/h2&gt;
&lt;p&gt;Your repo has been downloaded and prepped with a pulp_manifest so it’s ready to be imported into Katello.&lt;/p&gt;

&lt;p&gt;I created a product called Ubuntu and made a repository for each Ubuntu Distro I was trying to use. In this case, I have a repo called xenial. The type is file and the url is pointed to the media I have made available on my system. Then I start the sync and slowly sync the repo.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Issues:  /var/spool/pulp stores a copy of the files as it syncs, which I did not give enough space to since it was not listed in the katello installer documentation.  Due to this, it takes many many failed syncs to sync all the files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;set-up-the-foreman-info&quot;&gt;Set up the Foreman Info&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Update the Ubuntu Mirror Installation media to &lt;code class=&quot;highlighter-rouge&quot;&gt;http://foreman/pulp/isos/Default_Organization-Ubuntu-$release/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Add your operating system to foreman&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;build-a-host&quot;&gt;Build a Host&lt;/h2&gt;
&lt;p&gt;You should now be able to build a host selecting Ubuntu as an operating system and it will build off your local media.&lt;/p&gt;</content><author><name>Leah Fisher</name></author><category term="katello" /><category term="ubuntu" /><category term="repo" /><summary type="html">NOTE: This blog post describes how to use Katello 3.5 to host Ubuntu repos, and is aimed at those wanting to get Apt repo support going without upgrading. If you are using a later version of Katello, it may already support deb packages natively. Building Ubuntu Using Katello File Repo I have an offline network and need to build both RPM based systems and DEB based systems. Instead of installing Katello to handle rpms, and something else to handle debs, I set up Katello to handle both. Get Local Copy of Repo I created a script to do this for me, with following assumptions: Using box that has debmirror installed Installing this on a Fedora box required me to remove /etc/debmirror.conf for this script to work Has rsync installed Media is mounted at /mnt has enough space to copy the repo The example is downloading xenial, but can be duplicated to do other releases. /mnt has a copy of file_repogen.rb #!/bin/bash arch=amd64 section=main,restricted,universe,multiverse,main/debain-installer,universe/debian-installer,multiver/debian-installer,restricted/debian-installer release=xenial,xenial-updates server=us.archive.ubuntu.com inpath=/ubuntu outpath=/mnt/ubuntu/xenial debmirror --arch=$arch \ --no-source \ --section=$section \ --host=$server \ --dist=$release \ --di-dist=dists \ --di-arch=arches \ --root=$inpath \ --progress \ --ignore-release-gpg \ --no-check-gpg \ --exclude-deb-section=games \ --exclude=sid \ --method=rsync \ $outpath for i in $(echo $release | sed “s/,/ /g”); do rsync -L –progress –exclude=*i386 -a rsync://$server/ubuntu/dists/$i $outpath/dists/ done /mnt/file_repogen.rb /mnt/ubuntu/xenial Import into Katello Your repo has been downloaded and prepped with a pulp_manifest so it’s ready to be imported into Katello. I created a product called Ubuntu and made a repository for each Ubuntu Distro I was trying to use. In this case, I have a repo called xenial. The type is file and the url is pointed to the media I have made available on my system. Then I start the sync and slowly sync the repo. Issues: /var/spool/pulp stores a copy of the files as it syncs, which I did not give enough space to since it was not listed in the katello installer documentation. Due to this, it takes many many failed syncs to sync all the files. Set up the Foreman Info Update the Ubuntu Mirror Installation media to http://foreman/pulp/isos/Default_Organization-Ubuntu-$release/ Add your operating system to foreman Build a Host You should now be able to build a host selecting Ubuntu as an operating system and it will build off your local media.</summary></entry></feed>