Please test autoinstalls for 20.04!

I have/had an oddity related to DHCP during a Packer build with ubuntu-21.10-live-server-amd64.iso on vSphere. This is most likely a Packer issue, so see:

https://github.com/hashicorp/packer/issues/11385

I am using this boot command:

    "c",
    "linux /casper/vmlinuz \"ds=nocloud-net;seedfrom=http://{{.HTTPIP}}:{{.HTTPPort}}/\" autoinstall quiet --- ",
    "<enter><wait>",
    "initrd /casper/initrd<enter><wait>",
    "boot<enter>"

When the server initially boots, it gets an address from DHCP, which is the address that Packer then thinks is the address. Of course, during the install the server reboots, applying the config from the user-data. After rebooting, the server has a new IP address from DHCP, which is not the address that Packer thinks the server has.

In the user-data I do set dhcp-identifier: mac, but that does not help here as the first DHCP address is released, as it should be, so will not be reassigned.

In the end, I added a <wait300> at the end of the boot_command, so that 5 min goes by, whilst the VM installs the kernel and reboots. After that 5 min, Packer will carry on and get the IP address that will work, and all is good. This is clearly not the best thing to do, so there might be a Packer fix here too.

See: https://github.com/hashicorp/packer/issues/11385

What a microsoft-style answer. Unbelievable! What if I wanted for some particular reason, to simply delay those updates because of the way I’m deploying a virtual machine? This reminds me of those videos in which Windows would restart automatically while playing counter-strike.
It’s about choice and responsibility of the user, not about strictly telling users what they should do!
I would really have liked to have a choice of skipping it at this stage while keeping internet access to be able to get resources from repositories on my local network, for example.

1 Like

Is there a theoretical limit on the size of files used in a write_files block?

I’m trying to write out a (fairly large) file and I’m struggling to get it to work at all. I can’t even see it attempting to write in the install logs.

The syntax I’m using:

  user-data:
    write_files:
      - encoding: gz+b64
        content: B64CONTENTGOESHERE
        owner: root:root
        path: /root/ubuntu2004-script-cis_level2_server.sh
        permissions: '0755'
        defer: true 

I’ve tried a few different permutations of this. My understanding is that since the write_files feature is a legacy cloud-init one, it needs to be nested inside the user-data block, so I’ve made sure that’s done (I’ve also tried it outside that block).

I’ve tried this with the raw script as well, fed into base64 but that key:value pair ends up being very large (the script in question is 250kB). Instead, I have moved to using encoding: gz+b64 and I run the script through this process before copying into the user-data file:

gzip -9 --stdout ubuntu2004-script-cis_level2_server.sh | base64 -w0

When compressed, the script in question is a much more manageable 20kB but it still results in a key:value pair that’s very large.

No matter what I seem to try, this file just doesn’t end up being written to disk at all, either in the installer or in the /target system.

Am I missing something obvious here?

(for anyone that might want to test directly, the script in question is ubuntu2004-script-cis_level2_server.sh from the latest 0.1.58 release of ComplianceAsCode).


Edit: After some further searching, I’ve found a few instances of people around the internet reporting that the write_files directive doesn’t seem to work on Ubuntu. Instead I came up with this not-very-appealing solution, but it seems to work:

  late-commands:
    - /usr/bin/echo 'B64CONTENTGOESHERE' | /usr/bin/base64 --decode | /usr/bin/gunzip | /usr/bin/tee /target/root/ubuntu2004-script-cis_level2_server.sh

I think it would be nice if we could use write_files with Ubuntu as it’s expected to work, but I’m leaving the solution above here in case anyone else needs a quick fix to the same problem.

I have a cloud-config file /tftp/user-data which contains the following:

#cloud-config
autoinstall:
...content removed...
storage:
  grub:
    reorder_uefi: False
  layout:
    name: direct

However, every time this runs, it re-orders UEFI boot order and puts the PXE boot interface at the top, so it stays in a constant boot loop and never boots into the installed OS unless I interrupt, go into the System Settings and change the boot order back once it has rebooted after installation. I guess this is curtin doing it (like it does with MAAS, where it makes sense) but I can’t work out why this is being ignored, or how I can stop it.

I’m using the boot files from Ubuntu 20.04.3 - am I doing something wrong in the cloud-config file?

How do I define the ntp server to use? With d-i it was clock-setup/ntp-server 1.1.1.1 but how to do it now? There is like zero documentation for the new installer. Feels like d-i all over again. I am really disappointed.

I mean yes, I could probably do it via some hacky whacky as always stuff using late-commands: since d-i got deprecated alá unlinking the current timezone and linking a new one to /etc/localtime but my god, there must be a native way… Is there?

Another problem I couldn’t figure out. I want a simple encrypted LVM setup. I tried it with the following, where I get LVM but it is not encrypted

storage:
  grub: [...]
  swap: [...]
  layout:
    name: lvm
    match: {}
    key: mysecretkey

But this didn’t work. I don’t need a complex partition setup nor do I want to define sizes. I need what the installer does but via autoinstall. The problem is I don’t know whether the setup will be deployed on a sata (sda) or nvme device, therefore I cannot define a path and cannot use the custom layout. Using the old d-i I had an early command for partman to find the best matching disk and handed that to partman-auto/disk $bootdev and grub-installer/bootdev $bootdev defining lvm and a passphrase which always worked just like I wanted. I cannot get the setup to work using autoinstall.

Any help would be appreciated.

Via cloud-init probably? https://cloudinit.readthedocs.io/en/latest/topics/modules.html#ntp

I haven’t tried it but something like:

autoinstall:
 user-data:
  ntp:
   servers: [my.ntp.server]

Should do it.

Hey, thanks for the reply. This is working, tho you really have to put it into the brackets!

I tried to go with a custom config for partitioning now. This is working for EFI based systems, but how about legacy? Is it somehow possible to have both in the same config with smart decisions or so? I need to compare this to d-i where I had one config for all systems.

current config

  storage:
    grub:
      reorder_uefi: False
    swap:
      size: 0
    config:
    - {ptable: gpt, wipe: superblock, preserve: false, name: '', grub_device: false,
      type: disk, id: disk0}
    - {device: disk0, size: 536870912, wipe: superblock, flag: boot, number: 1,
      preserve: false, grub_device: true, type: partition, id: partition-0}
    - {fstype: fat32, volume: partition-0, preserve: false, type: format, id: format-0}
    - {device: disk0, size: 1073741824, wipe: superblock, flag: '', number: 2,
      preserve: false, grub_device: false, type: partition, id: partition-1}
    - {fstype: ext4, volume: partition-1, preserve: false, type: format, id: format-1}
    - {device: disk0, size: -1, wipe: superblock, flag: linux, number: 3, 
      preserve: false, grub_device: false, type: partition, id: partition-2}
    - {volume: partition-2, key: 'secretkey', preserve: false, type: dm_crypt,
      id: dm_crypt-0}
    - name: ubuntu-vg
      devices: [dm_crypt-0]
      preserve: false
      type: lvm_volgroup
      id: lvm_volgroup-0
    - {name: ubuntu-lv, volgroup: lvm_volgroup-0, size: 100%, wipe: superblock, 
      preserve: false, type: lvm_partition, id: lvm-partition-0}
    - {fstype: ext4, volume: lvm-partition-0, preserve: false, type: format, id: format-2}
    - {path: /, device: format-2, type: mount, id: mount-2}
    - {path: /boot, device: format-1, type: mount, id: mount-1}
    - {path: /boot/efi, device: format-0, type: mount, id: mount-0}

Further problems:

  • keymap doesn’t match keyboard layout in config → Cannot enter proper encryption password
    • keyboard: {layout: de, toggle: null, variant: ''}
      locale: de_DE.UTF-8
      

This also happens during manual server installations. At least it was the case for me. I chose English but with German keyboard, configured encrypted LVM and couldn’t decrypt after the install finished.

Interactive Sections:

  • I am used to being able to get a dialogue for the hostname only. This doesn’t work anymore since it is baked into a bigger interactive section. I would like to call a dialogue for one specific field only. This should be a thing in my opinion

late-commands
Shell commands to run after the install has completed successfully and any updates and packages installed, just before the system reboots.

Doesn’t seem to be the case. At least during late-commands I would expect the system to be finished as per description, but i.e. the defined user in identity isn’t even in /target/etc/passwd nor in /etc/passwd. Caused my late-command script to fail.

  • Not reported yet
    EDIT: the user is not even being added to the respective groups until restart.
    EDIT2: after some googling I found a config on github and tried it for two users. Nothing in /target/home nor passwd nor group until restart. This is BAD!

  • user-data:
      hostname: HOSTNAME
      timezone: TIMEZONE
      ntp:
        servers: [1.1.1.1]
      users:
        - name: USER1
          shell: /bin/SHELL
          lock-passwd: false
          passwd: HASHEDPASS 
          groups: [adm, cdrom, sudo, dip, plugdev, lxd]
        - name: USER2
          shell: /bin/SHELL
          lock-passwd: false
          passwd: HASHEDPASS 
          groups: [adm, cdrom, sudo, dip, plugdev, lxd]```
    
    
  • still ends ends in su: user USER does not exist so this is no solution to the underlying problem!

Furthermore due to the script being there already, I add a user in late-commands using useradd as normal. This causes this user to be user 1000 and the one from identity to be user 1001.

Some problems trying to workaround autoinstall desktop via pxe:

Using the ubuntu-desktop package: The user defined in identity isn’t able to login but the one from the script (mentioned above) is. It gets catapulted back to the login screen instantly. This is due to /home/CONFIGUREDUSER/ belongs to root:root instead of the user! This is a bug in the autoinstaller in this case. Even if I would use the user-data section (which isn’t documented at all so I don’t know what to do here to get both) the problem would probably remain for my late-command-script since the users are not accessible until reboot!

The locale is neither being applied for ubuntu-desktop nor console, neither for the script-user nor the autoinstall user (also without my late command script), it remains at the standard one despite locale listing the specified one for every entry.

  • For Desktop: Region & Language → Language and Formats are empty!
  • Missing packages: language-pack-LANG and language-pack-LANG-base

The language packs are completely missing, for every single application affected by it, depending on the packages (i.e. language-pack-LANG, language-pack-LANG-base, firefox-locale-LANG, gnome-user-docs-LANG, language-pack-gnome-LANG, language-pack-gnome-LANG-base, …)

This needs to be addressed! Previously using debian-installer I configured the language, keyboard layout and packages (in this case, also ubuntu-desktop) and everything got installed properly!

So I’m generally a big fan of Snaps on the desktop and I don’t want to start a flame war with this question, but how can I purge snapd during install? I have some servers which I know I’ll never use it on and want to slim down the attack surface of the system by removing it out of the box.

I’ve tried this on 20.04.3 and it seems to just break the installation process:

  late-commands:
    # Remove snapd
    - curtin in-target --target=/target -- apt-get --purge -y --quiet=2 remove snapd
    - rm -rf /target/root/snap

I can remove snapd just fine with the same command post-installation, but this doesn’t seem to work and I’d love to be able to do it within the autoinstall so I can build an image without it.

1 Like

Is there a way to configure the network to use DHCP if it’s available then switch to interactive for a static IP if not? This is the configuration I use with the debian-installer, but don’t see a way to recreate that with this.

I am having issues with 21.04 and 21.10 as well, i am using NOC-PS to do a physical install but its still loading up the language selection and so on and wont do an auto install, here is my pxe code.

#!gpxe
kernel http://$server/proxy.php/casper/vmlinuz ks=http://$server/kickstart.php/ubuntu?netplan=1 netcfg/choose_interface=$mac netcfg/no_default_route=1 vga=normal ip=dhcp url=http://www.releases.ubuntu.com/21.04/ubuntu-21.04-live-server-amd64.iso auto=true priority=critical debian-installer/locale=en_US keyboard-configuration/layoutcode=us ubiquity/reboot=true languagechooser/language-name=English countrychooser/shortlist=US localechooser/supported-locales=en_US.UTF-8 boot=casper automatic-ubiquity autoinstall quiet splash noprompt noshell
initrd http://$server/proxy.php/casper/initrd
boot

Automated Server Installs
Automated Server Installs Config File Reference
/
This is not a technical support site.
Please use:
https://answers.launchpad.net/ubuntu/+addquestion

very much looks like a support forum to me, and i have been through them and they dont work.

1 Like

You never provide a datasource. Typically, a kernel argument like ds=nocloud-net;s=http://$server/autoinstall is provided to download the autoinstall file(s) from a webserver.

Another paying Canonical customer chiming in here with a (IMO) valid use-case:

When doing prototyping that involves autoinstall, we want to fail fast when there are problems and iterate fast when there are not problems.

The forced security upgrades, especially on embedded platforms that do disk operations slowly, those cost $$$ in terms of my time spent waiting to pass through this phase of the deployment.

I’m actually writing this comment while waiting for an embedded SBC prototype to deploy…

Completely removing the option, rather than simply discouraging bad practices, removes my own agency to move at the pace I need to even within the safe confines of my work’s lab environment.

1 Like

I am trying to create modified Ubuntu 20.04.3 ISO image for embedded autoinstall-user-data. When I boot a Dell server with this modified image the installer keep crashing.

From crash dump I found that the installer is looking for “cdrom:/dists/focal/main/binary-amd64/Packages” but I only see Packages.gz in that path.

To fix it I tried this workaround successfully: Place the extracted 'Packages" file under the path ‘/dists/focal/main/binary-amd64/’ in ISO before generating custom ISO. Also keep “Packages.gz” in the ISO. This fixed the issue.

Did anyone encounter this issue? It looks like a bug in the installer if I am not doing anything wrong.

I posted more details here: https://askubuntu.com/questions/1394441/ubuntu-20-04-3-autoinstall-with-embedded-user-data-crashing-i-got-workaround

Does anyone know where in the installer logs I can find why my autoinstall config didn’t take? It’s an old config file that I know has worked in the past, so it’s probably something stupid I’m doing, but I don’t see any relevant errors in any of the logs.

I can see in the logs that args are getting passed in via netboot correctly: autoinstall ds=nocloud-net;s=http://assets.netboot.domain.com/, and http://assets.netboot.domain.com/user-data contains:

#cloud-config
autoinstall:
  version: 1
  early-commands:
    - ping -c1  10.7.0.1
  locale: en_US.UTF-8
  keyboard:
    layout: us
    toggle: null
    variant: ''
  network:
    network:
      version: 2
      ethernets:
        id0:
          match:
            name: en*
          dhcp4: true
  storage:
    layout:
      name: direct
  identity:
    hostname: newhost
    username: administrator
    password: <omitted>
  ssh:
    install-server: true
    allow-pw: true
  user-data:
    disable_root: false

Having some trouble setting up an automated install via packer on 20.04.4. When testing on hyper-v builder, I boot into a grub prompt where I can edit the kernel params using predefined keystrokes. For some reason when using qemu builder which we use on our infra farm, I’m not getting the grub prompt but rather getting this screen:

Using the same ISO in both. Is there a way I can force into grub boot? Or a way to set kernel parameters in this “BootOptions” screen? Trying to set “autoinstall ds…” etc but hitting f6 and typing in that prompt doesn’t seem to map the same way as editing through grub

This also appears to be a non issue on 21.10

Hey, I’ve done a couple of tests with the newest ubuntu 22.04 beta and can say that providing boot commands in grub such:

c
linux /casper/vmlinuz quiet — autoinstall
initrd /casper/initrd
boot

With mounted iso file labled cidata with user-data and meta-data.
or

c
linux /casper/vmlinuz “ds=nocloud-net;seedfrom=http://192.168.10.10/\” autoinstall quiet —
initrd /casper/initrd
boot

Serving the user-data over http.
basically no longer works.

It likely requires some different hack. Can somebody confirm that? I think the biggest difference now is that from some version Ubuntu doesn’t provide Casper server ?! So we have grub available only (also ?).
Does anybody know if a similiar thread about autoinstall method on version 21.04+ is available (somewhere)?

Happy hacking :slight_smile: