autoinstall: dynamic hostname from DHCP for the installer

Bug #1905932 reported by eoli3n
30
This bug affects 6 people
Affects Status Importance Assigned to Milestone
subiquity
New
Undecided
Unassigned

Bug Description

What I get:
With the installer, identity/hostname key is required, and set a static hostname.

What I need:
Getting hostname from DHCP.

I need to use ansible in pull mode in a chroot late command to configure the host. Ansible use current hostname to find what tasks it needs to run for the current host. I also need to make some web queries with $HOSTNAME as php arg.

How:
To get hostname from DHCP on a installed system, you need to empty /etc/hostname.

From the installer, a good behaviour would be:
If the key identity/hostname isn't defined, fallback to DHCP hostnames.

eoli3n (eoli3neoli3n)
summary: - dynamic hostname from DHCP for the installer
+ autoinstall: dynamic hostname from DHCP for the installer
Revision history for this message
eoli3n (eoli3neoli3n) wrote :
Revision history for this message
eoli3n (eoli3neoli3n) wrote :

As workaround, use a early command to set hostname from DNS.

1. Extract first default interface from "ip route"
2. Get ipv4 of that interface
3. Extract "host $ip" short hostname
4. Write it to /etc/hostname

Which gives

  early-commands:
    # Get hostname from DNS
    - host $(ip a show dev $(ip route | awk '/default/ {print $5; exit; }') | awk '/inet / {s=$2; sub(/\/.*/,"",s); print s}') | awk '{ s=$NF; sub(/\..*/,"",s); print s }' > /etc/hostname

Revision history for this message
eoli3n (eoli3neoli3n) wrote :

I improved the first workaround

  early-commands:
    # Get hostname from DNS
    - host $(/usr/sbin/ip a show dev $(/usr/sbin/ip route show default | awk 'sub(/.*dev /,"",$0) {print $1; exit;}') | awk '/inet / {sub(/\/.*/,"",$2); print $2}') | awk 'sub(/\..*/,"",$NF) { print $NF }' > /etc/hostname
    - hostname $(cat /etc/hostname)

Another one is to use json output of ip binary

  early-commands:
    # Get hostname from DNS
    - apt update && apt install -y jq
    - host $(/usr/sbin/ip -4 -j a show $(/usr/sbin/ip -j route show match default | jq -re '.[0].dev') | jq -re '.[0].addr_info[0].local') | awk 'sub(/\..*/,"",$NF) { print $NF }' > /etc/hostname
    - hostname $(cat /etc/hostname)

Revision history for this message
eoli3n (eoli3neoli3n) wrote :

Using "- hostname $(cat /etc/hostname)" is useless and breaks timezone.
See https://bugs.launchpad.net/subiquity/+bug/1907107

Revision history for this message
eoli3n (eoli3neoli3n) wrote :

I didn't wait at first startup for scripts to run to finish configurations, i ran my test too early.
Changing hostname doesn't break timezone.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

As per netplan reference https://netplan.io/reference/

use-hostname (bool)
Default: true. When true, the hostname received from the DHCP
server will be set as the transient hostname of the system. Currently
only has an effect on the networkd backend.

So this should have been working =/

Revision history for this message
forceps (ubuntubugs-web) wrote :

I am just moving to jammy from bionic and, with it, moving from the preseed environemnt to autoinstall/cloud-init. Setting hostname based on DHCP was trivial in the preseed environment. Is this still not supported spanning focal and jammy?

Revision history for this message
forceps (ubuntubugs-web) wrote :

I found a workaround using late-commands.
Note that that "curtin in-target --target=/target -- <cmd>" won't work if <cmd> contains stdout redirection, perhaps requiring some quote encapsulation. I avoid this confusion by just writing straight to /target. I find it easier to understand.

Below is a minimal working user-data file:

#cloud-config
autoinstall:
  version: 1
  identity:
    hostname: localhost
    username: ubuntu
    password: <mkpasswd output>
  late-commands:
    - getent hosts $(ip -o -4 address show scope global | head -n 1 | awk '{print $4}' | awk -F '/' '{print $1}') | awk '{print $2}' | awk -F '.' '{print $1}' > /target/etc/hostname

This command assumes that the first active non-loopback IPv4 address on the system reverse resolves to the desired hostname.

It would be nice to have this as a built-in feature. Currently, autoinstall is a step back compared to the preseed framework in this important domain.

Revision history for this message
Robert Hrovat (robi-hipnos) wrote :

Thank you forceps, been bugging me for hours why does it now work with Ubuntu 22.04.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.