Ansible role to generate a Linux installer .iso file with or without preseeding.
Full documentation on Readthedocs.
Source code on:
Ingredients
Ansible role to generate a Linux installer .iso file with or without preseeding.
When using preseeding on the generated iso, the questions asked by the Debian installer during the installation process will be automatically answered and when the installation process ends, the kick.sh script will be runned to setup the newly installed system.
When using preseeding and on the first screen that the Debian Installer shows, you will have to wait a couple of seconds (about 5) for the process to autostart.
- To install and execute:
ansible-galaxy install constrict0r.iso ansible localhost -m include_role -a name=constrict0r.iso -K
- Passing variables:
ansible localhost -m include_role -a name=constrict0r.iso -K \ -e "{username: [mary]}"
- To include the role on a playbook:
- hosts: servers roles: - {role: constrict0r.iso}
- To include the role as dependency on another role:
dependencies: - role: constrict0r.iso username: [mary]
- To use the role from tasks:
- name: Execute role task. import_role: name: constrict0r.iso vars: username: [mary]
- To use a USB stick to install a physical computer:
Use this role to generate a remaster.iso image (replace with your data):
ansible localhost -m include_role -a name=constrict0r.iso -K -e \ 'username=constrict0r userpass=1234 rootpass=1234 device=sda \ preseed=true preseed_wireless=true preseed_partitioning=true \ preseed_last_question=true \ preseed_custom=/home/constrict0r/Documentos/madvillain.yml \ networkname="MY NETWORK" networkpass="my-network-pass" \ hostname="latveria" domain="amanita" \ firmware_path=/home/constrict0r/Instaladores/firmware/'
- Then use dd to
- copy the file to your USB stick (replacing sdx with your drive):
su -c 'dd if=/path/to/remaster.iso of=/dev/sdx'
- Some modern computer complaints about a cdrom not detected
- during the installation process (because they no longer include cdroms), to overpass this issue, rename the extension .iso to .img and use dd to copy the file:
mv remaster.iso remaster.img su -c 'dd if=/path/to/remaster.img of=/dev/sdx'
To run tests:
cd iso chmod +x testme.sh ./testme.sh
On some tests you may need to use sudo to succeed.
- To use with Virt Manager:
Use this role to generate a remaster.iso image (replace with your data):
ansible localhost -m include_role -a name=constrict0r.iso -K -e \ 'username=constrict0r userpass=1234 rootpass=1234 device=sda preseed=true \ preseed_wireless=true preseed_partitioning=true preseed_last_question=true \ preseed_custom=/home/constrict0r/Documentos/madvillain.yml networkname="MY NETWORK" \ networkpass="my-network-pass" hostname="latveria" domain="amanita"'
Open Virt Manager and click on the New Virtual Machine icon (the tiny computer):
On the new Virtual Machine screen choose the option Local media and press Next:
On the Create Virtual Machine screen, search for the remaster.iso file and on the bottom input select the Generic OS type, then press the Next button:
On the Memory Assign screen type the amount of memory you need and the amount of cpus that you want to use and press Next:
On the Disk Space screen type the amount of space that you want to use and press Next:
On the Final screen put a name to your Virtual Machine, choose the network you want to use and press Finish:
The following variables are supported:
Absolute file path to an ISO file to use as base for preseeding.
If this variable is not especified, a Debian netinstall iso will be downloaded from internet.
This variable is empty by default.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "iso_path=/home/username/my-image.iso" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso iso_path: /home/username/my-image.iso # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "iso_path=/home/username/my-image.iso"
Url to obtain a Linux ISO image.
It can be the a full url to an ISO (i.e.: https://mirrors.ucr.ac.cr/debian-cd/current/amd64/iso-cd/debian-10.1.0-amd64-netinst.iso) to fetch a specific Debian version or it can be the base url of that ISO (i.e.: https://mirrors.ucr.ac.cr/debian-cd/current/amd64/iso-cd) to fetch the latest Debian version.
If this url does not refers to an .iso file, then is assumed to be a base ISO URL and the md5 file will be used to obtain the ISO name.
This variable points to https://mirrors.ucr.ac.cr/debian-cd/current/amd64/iso-cd by default.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "iso_url=https://is.gd/TFzT71" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso iso_url: https://is.gd/TFzT71 # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "iso_url=https://is.gd/TFzT71"
Local directory path where to store the downloaded Linux ISO file.
Defaults to ~/.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "iso_destination=/home/username/my-downloaded-iso/" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso iso_destination: /home/username/my-downloaded-iso/ # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "iso_destination=/home/username/my-downloaded-iso/"
Local directory path where to mount the downloaded Linux ISO to be preseeded.
If this directory does not exist it will be created.
If you want this directory to be deleted at the end of the process, set the delete_iso_mount variable to true.
Defaults to ~/original_iso/.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "iso_mount=/home/username/my-mount/" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso iso_mount: /home/username/my-mount/ # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "iso_mount=/home/username/my-mount/"
Wheter to delete or not (at the end of the process) the directory where the original Debian iso is mounted.
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "delete_iso_mount=true" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso delete_iso_mount: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "delete_iso_mount=true"
Local directory path where to copy the Linux ISO files to be modified to include preseeding.
If you want this directory to be deleted at the end of the process, set the delete_remaster_mount variable to true.
Defaults to ~/remaster_iso/.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "remaster_mount=/home/username/my-remaster/" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso remaster_mount: /home/username/my-remaster/ # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "remaster_mount=/home/username/my-remaster/"
Wheter to delete or not (at the end of the process) the directory where the Linux files to be modified are copied.
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "delete_remaster_mount=true" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso delete_remaster_mount: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "delete_remaster_mount=true"
Local file path where to save the resulting remastered ISO.
Defaults to ~/remaster.iso.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "remaster_destination=/home/username/my-remaster.iso" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso remaster_destination: /home/username/my-remaster.iso # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "remaster_destination=/home/username/my-remaster.iso"
The iso architecture, this variable is used to set the path where to copy and modify the preseed.cfg file. Valid values are:
- amd64: To install x86_64 machines.
- 386: To install x86 machines.
- a64: To install arm machines.
Defaults to amd64.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "iso_architecture=amd64" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso iso_architecture: 386 # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "iso_architecture=a64"
Local directory path to a folder containing firmware files to be added to the resulting ISO file.
This files must have .deb extension.
This variable answer to the following steps of the Debian Installer:
This variable is empty by default.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "firmware_path=/home/username/my-firmware/" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso firmware_path: /home/username/my-firmware/ # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "firmware_path=/home/username/my-firmware/"
Wheter to add preseeding to the resulting ISO or not.
If set to false the grub installation step is not preseeded neither.
If this variable is set to true the Debian Installer Variables (listed below) are used to apply preseeding.
This variable answer to the following step of the Debian Installer:
And:
And:
And:
And:
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed=false" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed=false"
Wheter to preseed wireless network configuration or not.
You can disable wireless network preseeding when using wired connections or for another particular case.
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed_wireless=false" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed_wireless: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed_wireless=false"
Wheter to apply preseed to partitioning configuration or not.
If set to true the atomic partitioning type is applied on the device specified in the device variable.
On simple terms this variable allows to apply a whole disk partitioning or not (none) partitioning at all.
This variable answer to the following step of the Debian Installer:
And:
And:
And:
And:
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed_partitioning=false" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed_partitioning: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed_partitioning=false"
Wheter to apply desktop configuration to the new system or not.
If set to true the gnome desktop enviroment is installed by including the constrictor.desktop ansible role.
When the preseed_custom variable is present and not empty, this variable is ignored.
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed_desktop=false" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed_desktop: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed_desktop=false"
Absolute path to a .yml file containing some or all of the following configuration:
- A list of apt repositories to add (see constrict0r.sourcez role).
- A list of packages to purge via Apt (see constrict0r.aptitude
- role).
- A list of packages to install via Apt (see constrict0r.aptitude
- role).
- A list of packages to install via yarn (see constrict0r.jsnode
- role).
- A list of packages to install via pip (see constrict0r.pyp role).
- An URL to a skeleton git repository to copy to / (see
- constrict0r.sysconfig role).
- A list of services to stop and disable (see constrict0r.servicez
- role).
- A list of services to enable and restart (see
- constrict0r.servicez role).
- A list of users to create (see constrict0r.users role).
- A list of groups to add the created users (see constrict0r.group
- role).
- A password for each created user.
- A list of files or URLs to skeleton git repositories to copy to
- each /home folder (see constrict0r.userconfig role).
- A list of files or URLs to custom Ansible tasks to run (see
- constrict0r.task role).
If set to true the constrictor.constructor ansible role will be included to read the specified configuration file and to apply the configuration described on it.
When this variable is present and not empty, the preseed_desktop variable is ignored (as if its value is false).
Defaults to empty.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed_custom=/home/username/my-config.yml" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed_custom: /home/username/my-config.yml # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed_custom=/home/username/my-config.yml"
Wheter to preseed or not the last question.
This is useful to prevent multiple installations if the machine keeps booting from an usb drive or similar.
This variable answer to the following steps of the Debian Installer:
Defaults to false.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "preseed_last_question=false" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso preseed_last_question: true # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "preseed_last_question=false"
Language and country to use.
This variable answer to the following step of the Debian Installer:
Defaults to es_CR.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "locale=us_US" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso locale: us_US # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "locale=us_US"
Keyboard distribution to use.
This variable answer to the following step of the Debian Installer:
Defaults to latam.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "keyboard=en_US" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso keyboard: en_US # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "keyboard=en_US"
Network name to use.
This variable answer to the following steps of the Debian Installer:
Defaults to mynetwork.
Must use quotes (“ or ‘) when specifying this variable via –extra-vars (-e):
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "networkname='mynetwork'" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso networkname: 'my network with spaces' # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "networkname='mynetwork'"
Network password to use.
This variable answer to the following steps of the Debian Installer:
And:
Defaults to 12345678.
Must use quotes (“ or ‘) when specifying this variable via –extra-vars (-e):
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "networkpass='my-password'" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso networkpass: "str@nge!Pass" # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "networkpass='my-password'"
Hostname to use.
This variable answer to the following step of the Debian Installer:
Defaults to debian.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "hostname=my-hostname" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso hostname: my-hostname # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "hostname=my-hostname"
Domain name to use.
This variable answer to the following step of the Debian Installer:
Defaults to debian.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "domain=my-domain" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso domain: my-domain # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "domain=my-domain"
Root user password.
This variable answer to the following step of the Debian Installer:
Defaults to debian.
Must use quotes (“ or ‘) when specifying this variable via –extra-vars (-e):
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "rootpass='my-password'" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso rootpass: "str@nge!Pass" # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "rootpass='my-password'"
Non-root username.
This variable answer to the following step of the Debian Installer:
Defaults to debian.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "username=mary" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso username: jhon # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "username=mary"
Non-root user password.
This variable answer to the following step of the Debian Installer:
Defaults to debian.
Must use quotes (“ or ‘) when specifying this variable via –extra-vars (-e):
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "userpass='my-password'" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso userpass: "str@nge!Pass" # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "userpass='my-password'"
Debian mirror url added to sources.
This variable answer to the following steps of the Debian Installer:
Defaults to `https://mirrors.ucr.ac.cr <https://mirrors.ucr.ac.cr>`_.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "mirror=https://mirrors.ucr.ac.cr" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso mirror: http://ftp.us.debian.org/debian # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "mirror=https://mirrors.ucr.ac.cr"
Device used for partitioning and where to install grub, usually sda or hda.
This variable must not include the text /dev/ but only the device name.
This variable answer to the following step of the Debian Installer:
Defaults to sda.
# Including from terminal. ansible localhost -m include_role -a name=constrict0r.iso -K -e \ "device=sda" # Including on a playbook. - hosts: servers roles: - role: constrict0r.iso device: sdb # To a playbook from terminal. ansible-playbook -i tests/inventory tests/test-playbook.yml -K -e \ "device=hda"
If you want to run the tests, you will also need:
- This role uses the username variable to set both the non-root
username and its full user name.
- Only support two types of partitioning: no partitioning or whole
disk partitioning.
- If you use the whole partitioning type it does not allow to
handle encrypted partitioning.
Does not allows to handle partman recipes.
- When using preseeding to specify packages to install via apt
there could be some problematic packages that needs a full Linux system enviroment to get installed and configured properly. Example of such packages are:
- bridge-utils
- libvirt-system-daemon
If you include any of those packages on a preseeding setup it will fail.
To prevent such failure it is recommended to setup a basic system first and when the system has started, call the kick.sh script again passing to it a configuration file.
Uses the same device to install the operating system and grub.
When using a wireless network there is one step not preseeded:
The option Enter ESSID Manually must be choosed automatically but it does not, the installer highlights the option correctly but does not continue with the process as if the Enter key is not preseed, and because of this is necessary to hit the Enter key one time during this step.
Once the Enter key has been preseed, all the other steps continue without any problem.
Luckily this step occurs at the beggining of the installation process, affects only wireless setups and does not affect virtual machines or containers.
- This role does not support vault values.
MIT. See the LICENSE file for more details.
The full project structure is shown below:
The project data flow is shown below:
The cleanup process data flow is shown below:
The process to modify the initrd.gz file is shown below:
The process to modify the initrd.gz file is shown below:
The process to preseed the answers for the Installer is shown below:
The process to modify the boot menu is shown below:
The preseeding process is shown below:
The remastering process is shown below:
The files sync process is shown below:
The process of obtaining the ISO to sync is shown below:
The process of variable copying is shown below:
The Travelling Vaudeville Villain.
Enjoy!!!