Getting started with bare-metal provisioning using Foreman

Problem: I’m very new to Foreman and wanting some guidance as to how to get a basic POC going with bare metal deployment.

I found this 3-year-old guide - https://www.linuxtechi.com/bare-metal-provisioning-through-foreman-server/ - which shows how to do the things I want to do! Unfortunately, it’s 3 years old and nothing from Step3 onwards appears to apply to modern Foreman.

I was able to use the Foreman Installer to spool up a test instance in VirtualBox and am keen to start trying things, but a little scared as I don’t know how to set up provisioning properly. The intent is for this Foreman install to be the “god” of its sandbox - providing DHCP/PXE to a bunch of VMs and thus being a proof-of-concept for later work (I want to use Foreman to stand up a HPC cluster).

Expected outcome:
I would love some advice and feedback - I’d be happy to turn it into a tutorial once I know what I’m doing so I can help other people in my position!

Foreman and Proxy versions:
1.20.2

Foreman and Proxy plugin versions:
Unsure

Other relevant data:
[e.g. logs from Foreman and/or the Proxy, modified templates, commands issued, etc]
(for logs, surround with three back-ticks to get proper formatting, e.g.)

logs

I found this comment on a blog:

“Install foreman using this command “sudo foreman-installer –enable-foreman-plugin-setup”. Apparently you need the plugin setup to have the provision setup tab.”

After running that command that missing tab shows up! Will have a go and report back here later…

Okay, I’m able to follow the wizard and use the foreman-installer commands it’s recommending, but it fail when I hit next:

*ArgumentError*
**wrong number of arguments (given 1, expected 0)**
/usr/share/foreman/app/models/provisioning_template.rb:153:in `build_pxe_default'
/usr/share/foreman/vendor/ruby/2.5.0/gems/foreman_setup-6.0.0/app/controllers/foreman_setup/provisioners_controller.rb:99:in `step4'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/abstract_controller/base.rb:194:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:109:in `block in run_callbacks'
/usr/share/foreman/app/controllers/concerns/application_shared.rb:15:in `set_timezone'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/usr/share/foreman/app/models/concerns/foreman/thread_session.rb:32:in `clear_thread'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/usr/share/foreman/app/controllers/concerns/foreman/controller/topbar_sweeper.rb:12:in `set_topbar_sweeper_controller'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/usr/share/foreman/vendor/ruby/2.5.0/gems/audited-4.8.0/lib/audited/sweeper.rb:14:in `around'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/usr/share/foreman/vendor/ruby/2.5.0/gems/audited-4.8.0/lib/audited/sweeper.rb:14:in `around'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:136:in `run_callbacks'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:168:in `block in instrument'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:168:in `instrument'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record/railties/controller_runtime.rb:24:in `process_action'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/abstract_controller/base.rb:134:in `process'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionview-5.2.1/lib/action_view/rendering.rb:32:in `process'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal.rb:191:in `dispatch'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_controller/metal.rb:252:in `dispatch'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/routing/route_set.rb:34:in `serve'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/journey/router.rb:52:in `block in serve'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/journey/router.rb:35:in `each'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/journey/router.rb:35:in `serve'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/routing/route_set.rb:840:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/apipie-rails-0.5.15/lib/apipie/static_dispatcher.rb:66:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/apipie-rails-0.5.15/lib/apipie/extractor/recorder.rb:137:in `call'
/usr/share/foreman/lib/middleware/telemetry.rb:9:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/apipie-rails-0.5.15/lib/apipie/middleware/checksum_in_headers.rb:27:in `call'
/usr/share/foreman/lib/middleware/catch_json_parse_errors.rb:8:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/tempfile_reaper.rb:15:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/etag.rb:25:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/conditional_get.rb:38:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/head.rb:12:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/http/content_security_policy.rb:18:in `call'
/usr/share/foreman/lib/middleware/logging_context.rb:23:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:232:in `context'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:226:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/cookies.rb:670:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/callbacks.rb:98:in `run_callbacks'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/railties-5.2.1/lib/rails/rack/logger.rb:38:in `call_app'
/usr/share/foreman/vendor/ruby/2.5.0/gems/railties-5.2.1/lib/rails/rack/logger.rb:28:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/quiet_assets.rb:13:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/method_override.rb:22:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/runtime.rb:22:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/activesupport-5.2.1/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/actionpack-5.2.1/lib/action_dispatch/middleware/static.rb:127:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/sendfile.rb:111:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/secure_headers-6.0.0/lib/secure_headers/middleware.rb:13:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/railties-5.2.1/lib/rails/engine.rb:524:in `call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/railties-5.2.1/lib/rails/railtie.rb:190:in `public_send'
/usr/share/foreman/vendor/ruby/2.5.0/gems/railties-5.2.1/lib/rails/railtie.rb:190:in `method_missing'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:68:in `block in call'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:53:in `each'
/usr/share/foreman/vendor/ruby/2.5.0/gems/rack-2.0.6/lib/rack/urlmap.rb:53:in `call'
/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:97:in `process_request'
/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb:160:in `accept_and_process_next_request'
/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb:113:in `main_loop'
/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler.rb:416:in `block (3 levels) in start_threads'
/usr/lib/ruby/vendor_ruby/phusion_passenger/utils.rb:113:in `block in create_thread_and_abort_on_exception'
/usr/share/foreman/vendor/ruby/2.5.0/gems/logging-2.2.2/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'

Hi,
I’m afraid that the foreman_setup plugin isn’t maintained and is no longer compatible with recent foreman versions. perhaps @discovery team could assist with explaining bare metal provisioning (or even create a new guide with recent versions)

Ah, that is a pity… I’m super eager to try Foreman as I think it’s a great fit for what we’re doing. Hopefully I can get some guidance :slight_smile:

Basically just want

  • DHCP PXE range 10.21.30.40 thru 10.21.30.200
  • Machine range 10.21.31.1 thru 10.21.31.200

And CentOS/Ubuntu PXE deployment…

That guide I was trying to follow is an almost perfect example of what I want, actually.

Thanks for your reply - you’ve probably saved me a lot of pain.

I am actually going thru this same exercise and used that exact same document you mentioned as reference. I installed Foreman on a Centos VM using the Quickstart instructions. (Foreman :: Quickstart). I Already installed the Foreman 5-6 times on Vagrant-Centos as well as vCenter Centos VM no issues. Actually impressed with the installer.

Then used that document to provision my first VM. Only issue I had was creating the installation Media/Operating system. During pxe it was missing some files, so used the default Centos mirror install media and was able successfully provision a Centos VM. Now, this was using 1 single network.

Now, I haven’t been able to configure multiple network yet. So I am not 100% sure how to separate DHCP from Machine range. Foreman is non disruptive which is cool, unlike other PXE solution where any server can boot into it if not configured properly.

If you want to keep thing simple, you could deploy Foreman on the machine range say IP 10.21.31.5 – then set subnet range to 10.21.31.10-10.21.31.200. This should work…

I manually created a subnet and ran the following:

foreman-installer \
  --enable-foreman-proxy \
  --foreman-proxy-tftp=true \
  --foreman-proxy-tftp-servername=10.21.30.2 \
  --foreman-proxy-dhcp=true \
  --foreman-proxy-dhcp-interface=enp0s8 \
  --foreman-proxy-dhcp-gateway="10.21.30.1" \
  --foreman-proxy-dhcp-nameservers="10.21.30.2" \
  --foreman-proxy-dns=true \
  --foreman-proxy-dns-interface=enp0s8 \
  --foreman-proxy-dns-zone=riff.cc \
  --foreman-proxy-dns-reverse=30.21.10.in-addr.arpa \
  --foreman-proxy-dns-forwarders=redacted.6 \
  --foreman-proxy-dns-forwarders=redacted.7 \
  --foreman-proxy-dns-forwarders=redacted.1
  --foreman-proxy-foreman-base-url=https://fm-master2.riff.cc

I’ve set fm-master2.riff.cc to point to 10.21.30.2 (my Foreman server).

I’ve gotten to the point where PXELinux successfully boots and chainloads the installer for CentOS, but unfortunately I’m getting some errors.

So close! Any ideas?

The machine drops to a shell eventually where I find I can ping 8.8.8.8 (google public DNS) but not google.com or fm-master2.riff.cc…

Same thing happens on Ubuntu 18.04

(Also, the “redacted” bits in that foreman-installer command are proper IPs :slight_smile:)

Hey guys, two things to check in this case:

  • Does the hostname in kickstart URL resolve correctly for that host? You really need to install a VM manually in that network and then get an IP from the DHCP server and then try to resolve it.
  • Can the host reach to the host? Some networks might not be routable.

Hey!
Just saw the part regarding DNS.
Are you able to access the DNS service at all from an external system (by which I mean, is it running on your system? Is the firewall blocking access to TCP/53 or UDP/53?)?

You could either test this by trying nslookup - 10.21.30.2 from any PC in the network or even the anaconda shell.

Also, if configuring the firewall doesn’t help:
it’s been a while now that I’ve done this manually but best is to check your answers file (/etc/foreman-installer/scenarios.d/foreman-answers.yaml) and check if the following is set:

  dns_managed: true
  dns_provider: nsupdate
  dns_server: 127.0.0.1

At least, that’s what I have set here :slight_smile:

Kind regards!

Having spun up a new VM on that network, it’s definitely an issue with my DNS server.

The VM gets DHCP, and DNS etc are all set to the correct IPs, but I can’t ping, dig or nslookup anything sensible.

I’ll report back here once I’ve figured it out…

I believe I’ve finally cracked it.

I was naively using the address 10.21.30.2 (/23) for my Foreman host/master and assuming it was working, because it seemed to be.

Turns out VirtualBox was doing some weird mapping between the host and the VMs that meant that I was trying to hit the host when I hit .2

I’m in the middle of rebuilding to use .3 instead but some initial testing is showing lots of promise.

Having moved everything to .3, everything now works.

Was able to install CentOS 7.6 and Ubuntu 18.04.2 no problems, and got SLES15 mostly working.

2 Likes