Skip to content

Instantly share code, notes, and snippets.

@dbkinghorn
Created September 28, 2021 21:49
Show Gist options
  • Save dbkinghorn/c236aea31d76028b2b6ccdf6d3c6f07e to your computer and use it in GitHub Desktop.
Save dbkinghorn/c236aea31d76028b2b6ccdf6d3c6f07e to your computer and use it in GitHub Desktop.
Ubuntu 20.04 user-data files for autoinstall ISO
#cloud-config
autoinstall:
version: 1
refresh-installer: # start with an up-to-date installer
update: yes
interactive-sections: # Install groups listed here will wait for user input
- storage
storage: # should set the interactive default but doesn't seem to work??
layout:
name: direct
locale: en_US.UTF-8
keyboard:
layout: us
identity: # This is section you may want to add to interactive-sections (user name and password are ubuntu here)
hostname: puget-000
password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
username: ubuntu
ssh:
allow-pw: true
install-server: true
apt:
sources:
ignored1: # This is here to get the yaml formatting right when adding a ppa
source: ppa:graphics-drivers/ppa
packages:
- build-essential
- network-manager
- dkms
- emacs-nox
- ubuntu-desktop-minimal
package_update: true
package_upgrade: true
late-commands:
# Changing from networkd to NetworkManager
# move existing config out of the way
- find /target/etc/netplan/ -name "*.yaml" -exec sh -c 'mv "$1" "$1-orig"' _ {} \;
# Create a new netplan and enable it
- |
cat <<EOF | sudo tee /target/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: NetworkManager
EOF
- curtin in-target --target /target netplan generate
- curtin in-target --target /target netplan apply
- curtin in-target --target /target systemctl enable NetworkManager.service
# Write a script that can take care of some post install setup "late-commands" cannot be interactive unfortunately"
# - |
# cat <<EOF | sudo tee /target/etc/finish-install-setup.sh
# #!/usr/bin/env bash
# echo *************************
# echo **** Finish Setup ****
# echo *************************
# echo 'Enter the hostname for this system: '
# read NEW_HOSTNAME
# hostnamectl set-hostname \${NEW_HOSTNAME}
# echo
# echo 'Enter the timezone for this system: '
# echo 'America/Los_Angeles America/Denver America/Chicago America/New_York'
# read NEW_TIMEZONE
# timedatectl set-timezone \${NEW_TIMEZONE}
# echo *************************
# echo
# echo *************************
# echo 'Restarting to finish ...'
# shutdown -r 3
# EOF
# - curtin in-target --target /target chmod 744 /etc/finish-install-setup.sh
- cp /target/cdrom/extras/Puget_Systems.png /target/usr/share/backgrounds/
user-data: # Commands here run during first boot (cannot be interactive)
runcmd:
# Install the NVIDIA driver from the ppa we setup earlier
- [apt-get, update]
- [apt-get, dist-upgrade, --yes]
- [apt, autoremove, --yes]
- [apt-get, install, --yes, nvidia-driver-470] #, --no-install-recommends]
- [sudo, -u, ubuntu, dbus-launch, gsettings, set, org.gnome.desktop.background, picture-uri, file:///usr/share/backgrounds/Puget_Systems.png]
# - |
# #!/usr/bin/env bash
# echo ''
# echo '***************************************'
# echo ' To complete install setup please run, '
# echo ' sudo /etc/finish-install-setup.sh'
# echo '***************************************'
# echo ''
#cloud-config
autoinstall:
version: 1
refresh-installer: # start with an up-to-date installer
update: yes
interactive-sections: # Install groups listed here will wait for user input
- storage
storage: # should set the interactive default but doesn't seem to work??
layout:
name: direct
locale: en_US.UTF-8
keyboard:
layout: us
identity: # This is section you may want to add to interactive-sections (user name and password are ubuntu here)
hostname: puget-000
password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
username: ubuntu
ssh:
allow-pw: true
install-server: true
apt:
sources:
ignored1: # This is here to get the yaml formatting right when adding a ppa
source: ppa:graphics-drivers/ppa
packages:
- build-essential
- network-manager
- dkms
- emacs-nox
#- ubuntu-desktop-minimal^
package_update: true
package_upgrade: true
late-commands:
# Changing from networkd to NetworkManager
# move existing config out of the way
- find /target/etc/netplan/ -name "*.yaml" -exec sh -c 'mv "$1" "$1-orig"' _ {} \;
# Create a new netplan and enable it
- |
cat <<EOF | sudo tee /target/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: NetworkManager
EOF
- curtin in-target --target /target netplan generate
- curtin in-target --target /target netplan apply
- curtin in-target --target /target systemctl enable NetworkManager.service
# Write a script that can take care of some post install setup "late-commands" cannot be interactive unfortunately"
# - |
# cat <<EOF | sudo tee /target/etc/finish-install-setup.sh
# #!/usr/bin/env bash
# echo *************************
# echo **** Finish Setup ****
# echo *************************
# echo 'Enter the hostname for this system: '
# read NEW_HOSTNAME
# hostnamectl set-hostname \${NEW_HOSTNAME}
# echo
# echo 'Enter the timezone for this system: '
# echo 'America/Los_Angeles America/Denver America/Chicago America/New_York'
# read NEW_TIMEZONE
# timedatectl set-timezone \${NEW_TIMEZONE}
# echo *************************
# echo
# echo *************************
# echo 'Restarting to finish ...'
# shutdown -r 3
# EOF
# - curtin in-target --target /target chmod 744 /etc/finish-install-setup.sh
- ls -l > /target/root/ls.out
- pwd > /target/root/pwd.out
- mount > /target/root/mount.out
- touch afile
- cp afile /target/root/
- ls -l / > /target/root/ls-root.out
- ls -l /target > /target/root/ls-target.out
- ls -l /target/cdrom > /target/root/ls-target-cdrom.out
user-data: # Commands here run during first boot (cannot be interactive)
runcmd:
# Install the NVIDIA driver from the ppa we setup earlier
- [apt-get, install, --yes, nvidia-driver-470, --no-install-recommends]
- |
#!/usr/bin/env bash
echo ''
echo '***************************************'
echo ' To complete install setup please run, '
echo ' sudo /etc/finish-install-setup.sh'
echo '***************************************'
echo ''
@dbkinghorn
Copy link
Author

The suggestions I've given are all I know for issues with WRX80 motherboards. If you are still having trouble with a local install then maybe you have a physical hardware problem. I can't really help you diagnose that.

@einsteinagogo
Copy link

einsteinagogo commented Jul 6, 2023

Any ideas, why the write script option in your template is not being executed ?

edit. Probably a typo, one issue is though /etc/hosts file goes not get changed, on changing hostname via hostnamectl ? any ideas ?

@dbkinghorn
Copy link
Author

Yes. In the write section I have commented out there are interactive sections for reading hostname and timezone. Those hang because there isn't proper terminal i/o at that point.

You can write scripts like that out and I thought it would run properly during the user-data section but there still isn't terminal i/o available.

It seems like there should be some way to do this but I was not able to find it.

...
I wish Canonical would have kept an option to do server installs from the Debian installer! ... or better adopted Kickstart :-)

@einsteinagogo
Copy link

Thanks for reply, I cross posted because I edited it, and got it working.

but changing hostname, via hostnamectl does not change the hostname in the /etc/hosts, so not sure if need to drop back to interactivite method of entering name password and hostname to get the correct hostname in /etc/hosts

@dbkinghorn
Copy link
Author

... I don't like to drop back to interactive for all of that but it may be the best (easiest) solution.
When you go to an interactive section, the installer is supposed to populate you defaults with any values you give in the cloud-init file. Like a default user and pw, but I've had trouble getting that to work too!

@einsteinagogo
Copy link

I found a way, to update /etc/hosts file, I think scripted, but this may all be a waste of time, because of domain join to Active Directory and if the workstation was joined to domain on build and later hostname change, it's going to break domain connection, so may have to also script domain join, and not make part of cloud-init

@homaur
Copy link

homaur commented Sep 7, 2023

Hi @dbkinghorn
Nice to meet you.
I have read your blogs but I am totally confused about how to create an autoinstall configuration file and edit it.

I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need.

@zero-pytagoras
Copy link

Hi @homaur
as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use.
as an example, part of user-data file:

apt:
    sources:
      ignored1:  # This is here to get the yaml formatting right when adding a ppa
        source: ppa:saltstack/salt
  packages: 
    - build-essential
    - network-manager
    - dkms
    - salt # <-- here you add the package 

@homaur
Copy link

homaur commented Sep 7, 2023

Hi @homaur as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use. as an example, part of user-data file:

apt:
    sources:
      ignored1:  # This is here to get the yaml formatting right when adding a ppa
        source: ppa:saltstack/salt
  packages: 
    - build-essential
    - network-manager
    - dkms
    - salt # <-- here you add the package 

Great!
But as I mentioned above, I am not clear on how to create the user-data file and where this file should be located.
I can't find any blogs for how to create the user-data file and where this file is and so on.
There are many blogs with rough explanations. No details.
Please help me how to do that.
Did you understand what I want to do?

I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need.

@jnlickey
Copy link

jnlickey commented Sep 7, 2023 via email

@homaur
Copy link

homaur commented Sep 7, 2023

Homaur,Feel free to use my Ubuntu AutoInstaller script. It will help to auto generate the user data file, by setting up the networking information, name, user accounts, etc. However, you'll need to modify either the script or the user-data file for your needs. Here's an example user-data file:https://github.com/jnlickey/Ubuntu_AutoInstaller/blob/main/user-dataJon Lickey, M.I.S Sent from my Verizon, Samsung Galaxy smartphone -------- Original message --------From: Homaur @.> Date: 9/7/23 6:03 AM (GMT-05:00) To: homaur @.> Cc: Comment @.***> Subject: Re: dbkinghorn/user-data-server @homaur commented on this gist.Hi @homaur as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use. as an example, part of user-data "notranslate">apt: sources: ignored1: # This is here to get the yaml formatting right when adding a ppa source: ppa:saltstack/salt packages: - build-essential - network-manager - dkms - salt # <-- here you add the package Great!But as I mentioned above, I am not clear on how to create the user-data file and where this file should be located.—Reply to this email directly, view it on GitHub or unsubscribe.You are receiving this email because you commented on the thread.Triage notifications on the go with GitHub Mobile for iOS or Android.

Oh great and Oh very complicated.
I am not sure if you understand what I want or not. Here is my explanation of what I want to do.

I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need. Totally, I want to install additional software automatically after Ubuntu has installed. Ubuntu will be installed via PXE net.
Do you understand?

@zero-pytagoras
Copy link

zero-pytagoras commented Sep 7, 2023

Hi @homaur as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use. as an example, part of user-data file:

apt:
    sources:
      ignored1:  # This is here to get the yaml formatting right when adding a ppa
        source: ppa:saltstack/salt
  packages: 
    - build-essential
    - network-manager
    - dkms
    - salt # <-- here you add the package 

Great! But as I mentioned above, I am not clear on how to create the user-data file and where this file should be located. I can't find any blogs for how to create the user-data file and where this file is and so on. There are many blogs with rough explanations. No details. Please help me how to do that. Did you understand what I want to do?

I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need.

Hi @homaur
In regards to where, It depends - if you wish to use iPXE then it should be located on PXE server , on the path that is shared. For example: /var/www/pxe/user-data folder.
All is left is to take ISO file of ubuntu -> boot -> choose boot from PXE(should be in advanced settings) -> give it pxe address and path to user-data, and it will perform what ever is configured in user-data
In regards to How to create user-data : @jnlickey provided link to github repository with example of user-data and tool to build the file. there is also cloud-init documentation that is used to create the file and also there is youtube tutorial to guide you and another one that might be useful

@homaur
Copy link

homaur commented Sep 7, 2023

Hi @homaur as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use. as an example, part of user-data file:

apt:
    sources:
      ignored1:  # This is here to get the yaml formatting right when adding a ppa
        source: ppa:saltstack/salt
  packages: 
    - build-essential
    - network-manager
    - dkms
    - salt # <-- here you add the package 

Great! But as I mentioned above, I am not clear on how to create the user-data file and where this file should be located. I can't find any blogs for how to create the user-data file and where this file is and so on. There are many blogs with rough explanations. No details. Please help me how to do that. Did you understand what I want to do?
I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need.

Hi @homaur In regards to where, It depends - if you wish to use iPXE then it should be located on PXE server , on the path that is share. For example: /var/www/pxe/user-data folder. All is left is to take ISO file of ubuntu -> boot -> choose boot from PXE(should be in advanced settings) -> give it pxe address and path to user-data, and it will perform what ever is configured in user-data In regards to How to create user-data : @jnlickey provided link to github repository with example of user-data and tool to build the file. there is also cloud-init documentation that is used to create the file and also there is youtube tutorial to guide you and another one that might be useful

Oh so, for example, autoinstall configuration file will be located in /var/www/pxe/user-data folder in iPXE server, right?

@zero-pytagoras
Copy link

Hi @homaur as mentioned above - create the user-data file that has apt and packages parts, where you add repositories and packages for you use. as an example, part of user-data file:

apt:
    sources:
      ignored1:  # This is here to get the yaml formatting right when adding a ppa
        source: ppa:saltstack/salt
  packages: 
    - build-essential
    - network-manager
    - dkms
    - salt # <-- here you add the package 

Great! But as I mentioned above, I am not clear on how to create the user-data file and where this file should be located. I can't find any blogs for how to create the user-data file and where this file is and so on. There are many blogs with rough explanations. No details. Please help me how to do that. Did you understand what I want to do?
I have set up an iPXE boot server and that works. However, I would like to automate the installation of additional software so Ubuntu installs automatically with either autoinstall/preseed. However I am not sure how to add additional software packages to the autoinstall file and where is autoinstall configuration file etc. Finally, I'd like to install salt at the end so it can finish configuring the device with the software I need.

Hi @homaur In regards to where, It depends - if you wish to use iPXE then it should be located on PXE server , on the path that is share. For example: /var/www/pxe/user-data folder. All is left is to take ISO file of ubuntu -> boot -> choose boot from PXE(should be in advanced settings) -> give it pxe address and path to user-data, and it will perform what ever is configured in user-data In regards to How to create user-data : @jnlickey provided link to github repository with example of user-data and tool to build the file. there is also cloud-init documentation that is used to create the file and also there is youtube tutorial to guide you and another one that might be useful

Oh so, for example, autoinstall configuration file will be located in /var/www/pxe/user-data folder in iPXE server, right?

Yes - indeed ...

@homaur
Copy link

homaur commented Sep 7, 2023

Ah!!! Great!!!
Thank you for your kind reply.
I will try with your suggestion and let you know.
I really appreciate it.
Thank you again!!!

@shubham-kshetre
Copy link

shubham-kshetre commented Sep 17, 2023

Hello there,

I am currently building an autoinstall ISO using Ubuntu 22.04.3 LTS live server. A blog post by @dbkinghorn has been immensely helpful in this process. However, I have encountered an issue with the autoinstall script I created, specifically with regard to enabling autologin for the new user.

The purpose of this autoinstall is to run docker engine. I am in need of suggestions or assistance to resolve this issue. Below is my 'user-data' configuration:

#cloud-config
autoinstall:
  version: 1
  storage:
    layout:
      name: direct
  partitions:
    - name: primary
      number: 1
      size: 100%
      type: ext4
      wipe: superblock
  preserve_layout: false
  overwrite: true
  filesystems:
    - device: /dev/disk/by-id/*
      format: ext4
      label: ubuntu
  locale: en_US.UTF-8
  keyboard:
    layout: us
  identity:
    hostname: ubuntu_machine
    password: $6$NpdhCKROExJxGAP9$uJ/hKo9ON7VZ.nwC02p8yKHPFtEWz.aphNk7D1fDI7aUmtrXTN5i/QmDhtbCf0xNQEr/LTphOfdcgovbDwG8l.
    username: ubuntu
  ssh:
    allow-pw: true
    install-server: true
  apt:
    primary:
      - arches: [default]
        uri: http://us.archive.ubuntu.com/ubuntu/
  packages:
    - build-essential
    - network-manager
    - dkms
    - vim
    - git
    - docker.io
    - nodejs
    - npm
    - sqlite

  package_update: true
  package_upgrade: true
  late-commands:
    # Changing from networkd to NetworkManager
    # move existing config out of the way
    - find /target/etc/netplan/ -name "*.yaml"
      -exec sh -c 'mv "$1" "$1-orig"' _ {} \;
    # Create a new netplan and enable it
    - |
      cat <<EOF | sudo tee /target/etc/netplan/01-netcfg.yaml
      network:
        version: 2
        renderer: NetworkManager
      EOF
    - curtin in-target --target /target netplan generate
    - curtin in-target --target /target netplan apply
    - curtin in-target --target /target systemctl enable NetworkManager.service
  users:
    - name: ubuntu
      groups: docker
      shell: /bin/bash
      sudo: ALL=(ALL) NOPASSWD:ALL
  autologin:
    enable: true
    user: root

I have been working on this problem for several weeks and would greatly appreciate any guidance or help. Thank you.

@dbkinghorn
Copy link
Author

You probably still have a little more experimenting to do. Here are a couple of things to try;

  • You have the user 'ubuntu' already defined with a password (effectively the install root user'.) You might want to try setting up your auto-login user with at different name. (I'm not sure how this is done with a manual install. Maybe you want to do this in the identity section and not assign a password at all??)

  • If you want to have the user 'ubuntu' as the auto login user then you might have better luck in late-commands using curtin in-target --target to do the config change manually with system commands like usermod etc..

I don't have experience using auto login but I hope I'm giving you good advise on things to try. Best wishes --Don

@smahm006
Copy link

smahm006 commented Nov 5, 2023

@shubham-kshetre I had a kinda successful but disgusting method go get autologin working.

In late_commands add this:

# Create a service to run above script on bootup
- |
  cat <<EOF | sudo tee /target/etc/systemd/system/setup_autologin.service
  [Unit]
  Description=Configure autologin for user "tester"

  [Service]
  Type=oneshot
  ExecStart=/bin/bash -c "sed -i 's/#  AutomaticLoginEnable = true/AutomaticLoginEnable = true/' /etc/gdm3/custom.conf && sed -i 's/#  AutomaticLogin = user1/AutomaticLogin = tester/' /etc/gdm3/custom.conf && groupadd docker && usermod -aG docker tester && newgrp docker"

  [Install]
  WantedBy=multi-user.target
  EOF
- curtin in-target --target /target chmod 0644 /etc/systemd/system/setup_autologin.service
- curtin in-target --target /target systemctl enable setup_autologin

Basically create a service that will run prior to the desktop loading. Problem is that you have to delete the service file post login.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment