Foreman bootdisk and external DHCP

Hi everybody, and thanks Foreman people for a wonderful piece of kit. I've been using it successfully for a little while, and am now trying to sort out provisioning here at work to save us some time.

We are predominantly a Windows environment however, and in particular our DHCP servers are windows boxes that I have no control over. PXE is in use exclusively for our Windows imaging.

Given that, I though that the foreman_bootdisk plugin would be the answer, and I'm really close to getting it all working, but any machine I try to provision has network issues and fails the build. I boot via the generic boot disk and the machine starts, gets an IP address and contacts The Foreman for build instructions (preseed, kickstart etc). After that it seems that the machine loses its IP address and subsequently fails to go any further.

I think the piece I'm missing is how to make The Foreman bootdisk scenario work with an external DHCP server. I had thought I could just boot via the bootdisk and let the existing DHCP take care of the network piece, and this is exactly how I build RHEL boxes here from Satellite 5.x, but I think I've missed some config or I'm not understanding how Foreman works with external non-controlled DHCP.

Apologies for the long post. Can anyone offer any guidance on how to make Foreman bootdisk and external DHCP work? More than happy to provide any details or logs that could be of use.

Many thanks, Craig.

Hey Craig and welcome here.

Can you explain what happens in more detail? At which point you seem
to lost IP address? You say you hit kickstart that would mean Anaconda
was loaded up and initialized network, at this point there is almost
nothing which could literally stop Anaconda from completing
installation, except some misconfiguration in the kickstart itself.

Also which bootdisk type do you use? These are very different
workflows. Generic (and subnet) bootdisks match the host you want to
provision with MAC address. But host or full host disk uses token
which is tied to host you created bootdisk for. The token has limited
expiration time (by default 90 minutes I think), then the bootdisk is
invalid. You can turn of token_duration in settings, in that case
Foreman will try to match hosts via REMOTE_IP (which will not work if
your IP address is not correct in foreman db) or for Anaconda (Red Hat
systems only) it will match according to MAC address sent by anaconda
in HTTP header.

Better understanding will give you generic and host snippets which are
used to generate /SCRIPT file for iPXE:


For full host disk PXELinux template is used. Remember you can edit
any of these in Foreman, feel free to modify iPXE as you want. If you
don't want static allocation, you can just put DHCP statement there
and iPXE will chainboot from Foreman iPXE template using DHCP. The
same way you can modify PXELinux template which is by default DHCP
(but when Subnet is put into Static mode it will also use static
configuration).

In all cases, I recommend to setup this without foreman first and then
after full understanding how you want piece things together you can
modify templates like you want.

Good luck!

··· On Tue, Oct 10, 2017 at 9:15 AM, Craig Parker wrote: > Hi everybody, and thanks Foreman people for a wonderful piece of kit. I've been using it successfully for a little while, and am now trying to sort out provisioning here at work to save us some time. > > We are predominantly a Windows environment however, and in particular our DHCP servers are windows boxes that I have no control over. PXE is in use exclusively for our Windows imaging. > > Given that, I though that the foreman_bootdisk plugin would be the answer, and I'm really close to getting it all working, but any machine I try to provision has network issues and fails the build. I boot via the generic boot disk and the machine starts, gets an IP address and contacts The Foreman for build instructions (preseed, kickstart etc). After that it seems that the machine loses its IP address and subsequently fails to go any further. > > I think the piece I'm missing is how to make The Foreman bootdisk scenario work with an external DHCP server. I had thought I could just boot via the bootdisk and let the existing DHCP take care of the network piece, and this is exactly how I build RHEL boxes here from Satellite 5.x, but I think I've missed some config or I'm not understanding how Foreman works with external non-controlled DHCP. > > Apologies for the long post. Can anyone offer any guidance on how to make Foreman bootdisk and external DHCP work? More than happy to provide any details or logs that could be of use. > > Many thanks, Craig. > > -- > You received this message because you are subscribed to the Google Groups "Foreman users" group. > To unsubscribe from this group and stop receiving emails from it, send an email to foreman-users+unsubscribe@googlegroups.com. > To post to this group, send email to foreman-users@googlegroups.com. > Visit this group at https://groups.google.com/group/foreman-users. > For more options, visit https://groups.google.com/d/optout.


Later,
Lukas @lzap Zapletal

Hi Lukas, and thanks so much for your reply. I really appreciate the time and effort you put into this.

Unfortunately I've been really busy with operational tasks today and haven't had any time to devote to this at all. What's happening though is this:

  • I boot the target machine (currently just an Ubuntu VM) with the generic bootdisk option
  • The machine boots, gets an IP address off our existing DHCP infrastructure, and contacts Foreman to look for a machine configured with its MAC
  • The machine finds a corresponding MAC address registered in Foreman, and proceeds to build via the templates outlined at the GitHub bootdisk page:
    "Preseed default iPXE",
    "Preseed default", and
    "Preseed default finish"

I haven't modified any of these templates at this stage while I try to understand the process.
At some stage fairly early on in the build though, it seems I lose my IP address, and the build subsequently fails, as it can't download any required files. By this stage I can't find my VM on the network anymore either.

I hope I've explained this ok. Does this make sense?

Thanks for your comments regarding setting a DHCP option inside the preseed or kickstart file. I suspect that's all I may need to do perhaps. Sorry for the possibly stupid question, but would you be able to give me any guidance on how to set DHCP inside the preseed file (which one?) and / or inside the RHEL kickstart file in Foreman?

I should have a bit more time for this tomorrow and am more than happy to provide screenshots / error messages / log files as necessary - I just don't want to bomb you right now with potentially unnecessary extra stuff.

Thanks again for your help, Craig

Hello,

I have zero experience with Ubuntu/Debian preseed but you need to
identify exactly at which stage you loose IP connection. My bet would
be when the installer attempts to reconfigure network? Perhaps there
is some log on virtual console 2 or higher where you can see this.

FYI Preseed default finish (or any "finish" template kind) is only
used in cloud environment. In PXE it won't be used I think. At least
in Red Hat OS (there is post scriplet in kickstart for this).

Now, I can comment only on Red Hats since this is my primary OS. We
ship the default kickstart configured in a way that if the subnet
associated with the host is set to DHCP mode, it will configure the
primary device for DHCP. Otherwise, it will do static configuration. I
assume it's the same for Debians. For docs about kickstart you can go
(or RHEL docs as well for enterprise versions).

Now it is important to understand that "network" kickstart option
re-configures network, but for PXE installations network needs to be
pre-initialized before Anaconda loads up. This is done by init ram
disk via kernel command line options. Again, by default we configure
DHCP or Static according to subnet setting. You can see this in
PXELinux template when doing PXE. For iPXE you can see this in iPXE
template ("Preseed default iPXE"). As you can see, iPXE IP address,
gateway and DNS is passed into the installer which will re-use these
to start Linux network stack.

So there are two phases, in your case the 2nd one perhaps fails. Check
your "Preseed default" template Preview option to see it.

Again, I suggest you to set things up without Foreman first to
understand how things work. I won't be able to help from screenshots,
I don't do Ubuntu provisioning much.

··· to: http://pykickstart.readthedocs.io/en/latest/kickstart-docs.html#network

On Wed, Oct 11, 2017 at 1:13 PM, Craig Parker tempohouse@gmail.com wrote:

Hi Lukas, and thanks so much for your reply. I really appreciate the time and effort you put into this.

Unfortunately I’ve been really busy with operational tasks today and haven’t had any time to devote to this at all. What’s happening though is this:

  • I boot the target machine (currently just an Ubuntu VM) with the generic bootdisk option
  • The machine boots, gets an IP address off our existing DHCP infrastructure, and contacts Foreman to look for a machine configured with its MAC
  • The machine finds a corresponding MAC address registered in Foreman, and proceeds to build via the templates outlined at the GitHub bootdisk page:
    “Preseed default iPXE”,
    “Preseed default”, and
    "Preseed default finish"

I haven’t modified any of these templates at this stage while I try to understand the process.
At some stage fairly early on in the build though, it seems I lose my IP address, and the build subsequently fails, as it can’t download any required files. By this stage I can’t find my VM on the network anymore either.

I hope I’ve explained this ok. Does this make sense?

Thanks for your comments regarding setting a DHCP option inside the preseed or kickstart file. I suspect that’s all I may need to do perhaps. Sorry for the possibly stupid question, but would you be able to give me any guidance on how to set DHCP inside the preseed file (which one?) and / or inside the RHEL kickstart file in Foreman?

I should have a bit more time for this tomorrow and am more than happy to provide screenshots / error messages / log files as necessary - I just don’t want to bomb you right now with potentially unnecessary extra stuff.

Thanks again for your help, Craig


You received this message because you are subscribed to the Google Groups “Foreman users” group.
To unsubscribe from this group and stop receiving emails from it, send an email to foreman-users+unsubscribe@googlegroups.com.
To post to this group, send email to foreman-users@googlegroups.com.
Visit this group at https://groups.google.com/group/foreman-users.
For more options, visit https://groups.google.com/d/optout.


Later,
Lukas @lzap Zapletal

I am striking exactly the same trouble using preseed from a bootdisk ISO trying to get DHCP working. The Ubuntu 18 install throws an error saying The IP address you provided in malformed and Execution of preseed command: "/bin/killall.sh; /bin/netcfg" failed. Looking through the Preseed default template there is:

<% subnet = @host.subnet -%>
<% if subnet.respond_to?(:dhcp_boot_mode?) -%>
  <% dhcp = subnet.dhcp_boot_mode? && !@static -%>
<% else -%>
  <% dhcp = !@static -%>
<% end -%>
<% unless dhcp -%>
# Static network configuration.
d-i preseed/early_command string /bin/killall.sh; /bin/netcfg

So given that command (killall and netcfg) was run it means it thinks it isn’t dhcp for some reason. My subnet is set to Boot mode: DHCP. When I ‘review’ the generated template it isn’t using these ‘static’ commands but I noticed the bootdisk ISO when it pulls the provisioning template (in my case: http://foreman.***removed***/unattended/provision?token=d9eade2e-fb33-46d9-8fd6-d2e1291707b1&static=yes) it’s passing static=yes which I assume is explicitly setting static in the template. I can’t figure out why that URL gets static=yes tho.

Further to the above, it’s definitely the network setup that’s wrong as when preseed fails, if I go to a console window and run dhclient and it gets an address, then preseed can happily carry on (well, until there’s no partition info for some reason but that’s another problem).

I’ve found where static=yes comes from. In “Pressed default iPXE”:

<% static = @host.token.nil? ? '?static=yes' : '&static=yes' -%>

kernel <%= kernel %> initrd=initrd.img interface=auto url=<%= foreman_url('provision')%><%= static %> ramdisk_size=10800 root=/dev/rd/0 rw auto netcfg/disable_dhcp=true BOOTIF=01-${netX/mac:hexhyp} hostname=<%= @host.name %> <%= keyboard_params %> locale=<%= host_param('lang') || 'en_US' %> netcfg/get_ipaddress=${netX/ip} netcfg/get_netmask=${netX/netmask} netcfg/get_gateway=${netX/gateway} netcfg/get_nameservers=${dns} netcfg/confirm_static=true

Which appears to enforce static addresses in multiple ways. Which seems strange. Why is this template designed to be static-only?

Hey, this is probably a bug or misunderstanding, this is how things are supposed to be:

Test this and then provide a PR to fix Debian-based template?

Thanks @lzap. Happy to submit a PR but I’m no preseed expert.

Specifically, in my modified template I removed several references to netcfg from kernel:

  • netcfg/disable_dhcp=true
  • netcfg/get_ipaddress=${netX/ip}
  • netcfg/get_netmask=${netX/netmask}
  • netcfg/get_gateway=${netX/gateway}
  • netcfg/confirm_static=true

That seemed logical to me and does work on Ubuntu 18.04. Even when using a static address it seems strange passing in these netcfg options when they would all be set in the preseed default provisioning template anyway.

Another change I would like guidance on is hosts without a subnet. The Foreman UI does not require a host to have a subnet but a couple of templates will fail if it does not. For a DHCP setup a subnet makes no sense when provisioning in a network I don’t control since I don’t know beforehand what the address or network prefix/mask will be (which are mandatory in a subnet). I would have thought no subnet would imply DHCP but (as per this bug I posted about these issues) the preseed_networking_setup template has several instances of checks like this:

<% host_subnet = @host.subnet -%>
<% host_dhcp = host_subnet.nil? ? false : host_subnet.dhcp_boot_mode? -%>
...
<% unless host_dhcp -%>
    address <%= @host.ip %>
    gateway <%= host_subnet.gateway %>
    netmask <%= host_subnet.mask %>
...

So if there’s no subnet it assumes it’s not DHCP. Which is crazy as it then tries to access fields of that nil subnet.

Would it be safe to assume no subnet implies DHCP?

When subnet is not set, defaulting to DHCP sounds like a good plan to me. Let’s do this for sure, this is how OS installers default too when nothing is configured usually.

PR submitted: https://github.com/theforeman/community-templates/pull/571