From 5f171450f2b096d53fdde86556014a70b777ed99 Mon Sep 17 00:00:00 2001 From: cytopia Date: Wed, 7 Nov 2018 16:05:51 +0100 Subject: [PATCH] Add new repository files --- .gitignore | 1 + .travis.yml | 46 ++++++----------- Dockerfile | 12 ++--- LICENSE.md | 0 Makefile | 113 ++++++++++++++++++++++++++++++++++++++++ README.md | 146 +++++++++++++++++++++++++++++++--------------------- Vagrantfile | 74 ++++++++++++++++++++++++++ bootstrap | 47 +++++++++++++++++ 8 files changed, 343 insertions(+), 96 deletions(-) mode change 100755 => 100644 LICENSE.md create mode 100644 Makefile create mode 100644 Vagrantfile create mode 100755 bootstrap diff --git a/.gitignore b/.gitignore index 945fcbf..be02284 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ # Add repo specific stuff here... validate.sh +.vagrant ###################################### # GENERIC diff --git a/.travis.yml b/.travis.yml index 66f4f9d..e9f5394 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,44 +8,24 @@ services: env: matrix: ### - ### Debian stretch + ### Generic profile ### # All roles (playbook order) - - single=0 random=0 dist=debian-stretch + - single=0 random=0 dist=generic-all # All roles (random order) - - single=0 random=1 dist=debian-stretch + - single=0 random=1 dist=generic-all # Start each role separately - - single=1 random=0 dist=debian-stretch + - single=1 random=0 dist=generic-all ### - ### Debian testing + ### Cytopia's profile ### # All roles (playbook order) - - single=0 random=0 dist=debian-testing + - single=0 random=0 dist=cytopia-t470p # All roles (random order) - - single=0 random=1 dist=debian-testing + - single=0 random=1 dist=cytopia-t470p # Start each role separately - - single=1 random=0 dist=debian-testing - - ### - ### Cytopia's profile: stretch - ### - # All roles (playbook order) - - single=0 random=0 dist=cytopia-stretch - # All roles (random order) - - single=0 random=1 dist=cytopia-stretch - # Start each role separately - - single=1 random=0 dist=cytopia-stretch - - ### - ### Cytopia's profile: testing - ### - # All roles (playbook order) - - single=0 random=0 dist=cytopia-testing - # All roles (random order) - - single=0 random=1 dist=cytopia-testing - # Start each role separately - - single=1 random=0 dist=cytopia-testing + - single=1 random=0 dist=cytopia-t470p before_script: @@ -56,14 +36,14 @@ before_script: script: # 1. Run it multiple times until it succeeds. This is to prevent errors that occur due to network timeouts between travis-ci # 2. Separate between single runs and full runs - - if [ "${single}" = "1" ]; then + - if [ "${single}" -eq "1" ]; then ROLES="$( for d in $(/bin/ls roles/); do if [ -d roles/${d} ]; then echo $d; fi done | grep -vE '*-meta$' | sort -R )"; TOTAL="$( echo "${ROLES}" | wc -l )"; START=1; for r in ${ROLES}; do printf "========== Run %s / %s (%s) ==========\n" "${START}" "${TOTAL}" "${r}"; max=10; i=0; while [ $i -lt $max ]; do - if docker run --rm -e MY_HOST=${dist} -e tag=${r} -t ansible-debian; then + if make test-docker-single PROFILE=${dist} ROLE=${r}; then break; else i=$((i+1)); @@ -73,5 +53,9 @@ script: START=$((START+1)); done; else - docker run --rm -e MY_HOST=${dist} -e random=${random} -t ansible-debian; + if [ "${random}" -eq "1" ]; then + make test-docker-random PROFILE=${dist}; + else + make test-docker-full PROFILE=${dist}; + fi fi diff --git a/Dockerfile b/Dockerfile index 26c4b59..9c220ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM debian:stretch MAINTAINER "cytopia" -RUN set -x \ +RUN set -eux \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ python-apt \ @@ -14,18 +14,18 @@ RUN set -x \ && rm -rf /var/lib/apt/lists/* \ && apt-get purge -y --autoremove -RUN set -x \ +RUN set -eux \ && pip install wheel \ && pip install ansible # Add user with password-less sudo -RUN set -x \ +RUN set -eux \ && useradd -m -s /bin/bash cytopia \ && echo "cytopia ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/cytopia # Copy files COPY ./ /home/cytopia/ansible -RUN set -x \ +RUN set -eux \ && chown -R cytopia:cytopia /home/cytopia/ansible # Switch to user @@ -35,12 +35,12 @@ USER cytopia WORKDIR /home/cytopia/ansible # Systemd cannot be checked inside Docker, so replace it with a dummy role -RUN set -x \ +RUN set -eux \ && mkdir roles/dummy \ && sed -i'' 's/systemd-meta/dummy/g' playbook.yml # Randomize roles to install each time the container is build (each travis run) -RUN set -x \ +RUN set -eux \ && ROLES_INSTALL="$( for d in $(/bin/ls roles/); do if [ -d roles/${d} ]; then echo $d; fi done | grep -vE '*-meta$' | sort -R )" \ && ROLES_REMOVE="$( for d in $(/bin/ls roles/); do if [ -d roles/${d} ]; then echo $d; fi done | grep -vE '*-meta$' | sort -R )" \ \ diff --git a/LICENSE.md b/LICENSE.md old mode 100755 new mode 100644 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a484ed2 --- /dev/null +++ b/Makefile @@ -0,0 +1,113 @@ +DIR = . +FILE = Dockerfile +IMAGE = cytopia/ansible-debian +TAG = latest + +# Ansible variables +VERBOSE= +PROFILE=cytopia-t470p + +.PHONY: help build-docker test-docker-full test-docker-random test-docker-single itest-docker-full itest-docker-random itest-docker-single + + +#-------------------------------------------------------------------------------------------------- +# Default Target +#-------------------------------------------------------------------------------------------------- + +help: + @echo "################################################################################" + @echo "# #" + @echo "# Debian Provisioning with Ansible #" + @echo "# #" + @echo "################################################################################" + @echo + @echo + @echo "------------------------------------------------------------" + @echo " Run tests in Docker" + @echo "------------------------------------------------------------" + @echo + @echo "build-docker Build the testing Docker image (happens automatically during tests)" + @echo + @echo "test-docker-docker-full Run a full test in a Docker (requires PROFILE)" + @echo "test-docker-docker-random Run a full randomized test in a Docker (requires PROFILE)" + @echo "test-docker-docker-single Run the test on a single role in a Docker (requires PROFILE and ROLE)" + @echo + @echo "itest-docker-docker-full Interactive version of test-docker-full (requires PROFILE)" + @echo "itest-docker-docker-random Interactive version of test-docker-random (requires PROFILE)" + @echo "itest-docker-docker-single Interactive version of test-docker-single (requires PROFILE and ROLE)" + @echo + @echo + @echo "------------------------------------------------------------" + @echo " Run tests in Vagrant" + @echo "------------------------------------------------------------" + @echo + @echo "------------------------------------------------------------" + @echo " Deploy your host system" + @echo "------------------------------------------------------------" + @echo + + +#-------------------------------------------------------------------------------------------------- +# Tests with Docker +#-------------------------------------------------------------------------------------------------- + +build-docker: + docker build -t $(IMAGE) -f $(DIR)/$(FILE) $(DIR) + +# Automated tests +test-docker-full: build-docker + docker run --rm -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -t $(IMAGE) + +test-docker-random: build-docker + docker run --rm -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -e random=1 -t $(IMAGE) + +test-docker-single: build-docker + docker run --rm -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -e tag=$(ROLE) -t $(IMAGE) + +# Interactive tests +# When inside the Container execute: ./run-tests.sh +itest-docker-full: build-docker + docker run -it --rm --entrypoint=bash -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -t $(IMAGE) + +itest-docker-random: build-docker + docker run -it --rm --entrypoint=bash -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -e random=1 -t $(IMAGE) + +itest-docker-single: build-docker + docker run -it --rm --entrypoint=bash -e MY_HOST=$(PROFILE) -e verbose=$(VERBOSE) -e tag=$(ROLE) -t $(IMAGE) + + +#-------------------------------------------------------------------------------------------------- +# Tests with Vagrant +#-------------------------------------------------------------------------------------------------- + +# Test your profile with Vagrant +test-vagrant: + vagrant rsync + PROFILE=$(PROFILE) vagrant up --provision + + +#-------------------------------------------------------------------------------------------------- +# Deploy Targets +#-------------------------------------------------------------------------------------------------- + +# (Step 1/3) Ensure required software is present +deploy-init: + DEBIAN_FRONTEND=noninteractive apt-get update -qq + DEBIAN_FRONTEND=noninteractive apt-get install -qq -q --no-install-recommends --no-install-suggests \ + python-apt \ + python-dev \ + python-jmespath \ + python-pip \ + python-setuptools + pip install wheel + pip install ansible + +# (Step 2/3) Add new Debian sources and dist-upgrade your system +deploy-dist-upgrade: + ansible-playbook -i inventory playbook.yml --limit ${PROFILE} --diff -t bootstrap-system --ask-become-pass + DEBIAN_FRONTEND=noninteractive apt-get update -qq + DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -qq -y + +# (Step 3/3) Deploy your system +deploy-tools: + ansible-playbook -i inventory playbook.yml --limit ${PROFILE} --diff --ask-become-pass diff --git a/README.md b/README.md index 591cb4d..9d98a37 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ It is designed to be a generic **buildfiles** (as opposed to **[dotfiles](https: 4. [Customize your profile](#customize-your-profile) 5. [Provision your profile](#provision-your-profile) 4. **[Test your profile](#test-your-profile)** - 1. [Build the Docker image](#build-the-docker-image) - 1. [Run the Docker container](#run-the-docker-container) + 1. [Docker](#docker) + 1. [Vagrant](#vagrant) 5. **[Options](#options)** 1. [Enable / Disable Management](#enable--disable-management) 2. [Package options](#package-options) @@ -46,19 +46,44 @@ It is designed to be a generic **buildfiles** (as opposed to **[dotfiles](https: Make sure your system meets the **[requirements](#requirements)** before you start. -##### Provision your system -``` -ansible-playbook -i inventory playbook.yml --diff --limit debian-stretch --ask-become-pass -``` +#### Fully provision your system from scratch -##### See what would change (dry-run) -``` -ansible-playbook -i inventory playbook.yml --diff --limit debian-stretch --ask-become-pass --check +Use this to provision your system from scratch, when you have already submitted your profile upstream. +The only requirements are `bash` and `sudo`, everything else will be installed automatically. + +```bash +# Provision default profile +curl https://raw.githubusercontent.com/cytopia/ansible-debian-testing/master/bootstrap | bash + +# Provision profile 'generic-all' +curl https://raw.githubusercontent.com/cytopia/ansible-debian-testing/master/bootstrap | bash -s generic-all ``` -##### Provision only a specific role +#### Manually provision your system from scratch + +Use this to provision your system from scratch, when you don't have a profile submitted to upstream yet. + +```bash +# 1. Clone this project +git clone https://github.com/cytopia/ansible-debian-testing +cd ansible-debian-testing + +# 2. Add your profile 'bob' (See 'Create custom profiles' section of this README) + +# 3. Provision your system (with profile 'bob') +sudo make deploy-init +sudo make deploy-dist-upgrade PROFILE=bob +sudo make deploy-tools PROFILE=bob ``` -ansible-playbook -i inventory playbook.yml --diff --limit debian-stretch --ask-become-pass -t i3-gaps + +#### Dry-run the tools installation + +```bash +# Dry-run everything for profile 'generic-all' +ansible-playbook -i inventory playbook.yml --diff --limit generic-all --ask-become-pass --check + +# Dry-run a specific role 'i3-gaps' +ansible-playbook -i inventory playbook.yml --diff --limit generic-all --ask-become-pass -t i3-gaps ``` @@ -303,8 +328,7 @@ Additionally you can (but don't have to) manage the following: * Custom apt packages can be added per profile * Custom pip packages can be added per profile * Custom Debian repositories can be added per profile -* Debian distribution (stable or testing) - +* Debian distribution (stable is upgraded to testing) ## Create custom profiles @@ -313,7 +337,7 @@ In order to customize your workstation or Debian infrastructure, you can create By the way Ansible works, each profile inherits all settings from [group_vars/all.yml](group_vars/all.yml). This file holds a sane default showing you all available options and with all packages unmanaged. -In order to actually **customize your profile**, you will have to create a file in [host_vars/](host_vars/) by the same name you have specified in [inventory](inventory). You can copy [group_vars/all.yml](group_vars/all.yml) directly or use an already existing profile from `host_vars`, such as [host_vars/debian-stretch.yml](host_vars/debian-stretch.yml). +In order to actually **customize your profile**, you will have to create a file in [host_vars/](host_vars/) by the same name you have specified in [inventory](inventory). You can copy [group_vars/all.yml](group_vars/all.yml) directly or use an already existing profile from `host_vars`, such as [host_vars/generic-all.yml](host_vars/generic-all.yml). To better understand how it works, you can follow this step-by-step example for creating a new profile: @@ -322,7 +346,7 @@ For the sake of this example, let's assume your profile is called `dell-xps-i3wm #### Add a new profile Add the following line to the bottom of [inventory](inventory): -``` +```bash dell-xps-i3wm ansible_connection=local ``` @@ -332,12 +356,12 @@ dell-xps-i3wm ansible_connection=local As already mentioned earlier, you can copy [group_vars/all.yml](group_vars/all.yml) or an already existing `host_vars` file. Use group_vars/all.yml as a default template: -``` +```bash cp group_vars/all.yml host_vars/dell-xps-i3wm.yml ``` Use an already existing host_vars file as a default template: -``` -cp host_vars/debian-stretch.yml host_vars/dell-xps-i3wm.yml +```bash +cp host_vars/generic-all.yml host_vars/dell-xps-i3wm.yml ``` #### Customize your profile @@ -347,45 +371,51 @@ Simply edit `host_vars/dell-xps-i3wm.yml` and adjust the values to your needs. I If you want to test your profile in a Docker container prior actually provisioning your own system, skip to the next section, otherwise just run the following commands. Run the following command to see what would happen: -```shell +```bash ansible-playbook -i inventory playbook.yml --diff --limit dell-xps-i3wm --ask-become-pass --check ``` Run the following command to actually apply your profile: -```shell +```bash ansible-playbook -i inventory playbook.yml --diff --limit dell-xps-i3wm --ask-become-pass ``` ## Test your profile -Before actually running any new profile on your own system, you can and you should test that beforehand in a **Docker container** in order to see if everything works as expected. This might also be very handy in case you are creating a new role and want to see if it works. -#### Build the Docker image -``` -docker build -t ansible-debian . -``` -#### Run the Docker container +Before actually running any new profile on your own system, you can and you should test that beforehand. This can be done in a **Docker container** or in a **Vagrant box** in order to see if everything works as expected. This might also be very handy in case you are creating a new role and want to see if it works. -Before running you should be aware of a few environment variables that can change the bevaviour of the test run. See the table below: +#### Docker + +**Note:** The Docker image will always be auto-build before running the tests. + +Before running you should be aware of a few arguments that can be applied to the `make` commands. See the table below: | Variable | Required | Description | |-----------|----------|-------------| -| `MY_HOST` | yes | The inventory hostname (your profile) | -| `verbose` | no | Ansible verbosity. Valid values: `0`, `1`, `2` or `3` | -| `tag` | no | Only run this specific tag (role name) | -| `random` | no | When running everything, do it in a random order. Valid values: `0` or `1` | +| `PROFILE` | yes | The inventory hostname (your profile) | +| `VERBOSE` | no | Ansible verbosity. Valid values: `0`, `1`, `2` or `3` | +| `ROLE` | no | Only run this specific tag (role name) | -Run a full test of profile `debian-testing`: -``` -docker run --rm -e MY_HOST=debian-testing -t ansible-debian +Run a full test of profile `generic-all`: +```bash +make test-docker-full PROFILE=generic-all ``` -Run a full test of profile `debian-testing` in a random order: +Run a full test of profile `generic-all` in a random order: +```bash +make test-docker-random PROFILE=generic-all ``` -docker run --rm -e MY_HOST=debian-testing -e random=1 -t ansible-debian +Only run `i3-gaps` role in profile `generic-all` +```bash +make test-docker-single PROFILE=generic-all ROLE=i3-gaps ``` -Only runt `i3-gaps` role in profile `debian-stretch` -``` -docker run --rm -e MY_HOST=debian-stretch -e tag=i3-gaps -t ansible-debian + +#### Vagrant + +If you don't trust the tests in Docker and want to see the end results graphically in a VM, you can also use Vagrant to do the same. + +```bash +make test-vagrant PROFILE=generic-all ``` @@ -394,9 +424,10 @@ docker run --rm -e MY_HOST=debian-stretch -e tag=i3-gaps -t ansible-debian #### Enable / Disable Management Look for the package section and set them to a desired state. `install` or `remove` or any other value to ignore them. -```yml +```bash $ vi host_vars/.yml - +``` +```yml ... i3-gaps: 'install' font_ubuntu: 'install' @@ -411,9 +442,10 @@ hipchat: 'ignore' #### Package options Many packages also come with options that you can tweak. You can for example define the Python version your system should provide: -```yml +```bash $ vi host_vars/.yml - +``` +```yml ... python_2: yes python_3: yes @@ -421,9 +453,10 @@ python_3: yes ``` Another customization could be the default program to use when opening speficif file types: -```yml +```bash $ vi host_vars/.yml - +``` +```yml ... xdg_mime_defaults: - desktop_file: chromium.desktop @@ -438,9 +471,10 @@ xdg_mime_defaults: ``` Or to set your **DPI** and other options for `lxdm` -```yml +```bash $ vi host_vars/.yml - +``` +```yml ... lxdm_dpi: 132 lxdm_gtk_theme: Arc-Darker @@ -449,9 +483,10 @@ lxdm_show_user_list: no ``` Choose your GPU and touchpad driver: -```yml +```bash $ vi host_vars/.yml - +``` +```yml # Supported values: 'amdgpu' 'ati' 'intel' 'modesetting' 'nouveau' 'nvidia' 'radeon' xorg_gpu: modesetting # Enable VDPAU_DRIVER=va_gl systemwide @@ -472,15 +507,8 @@ Before you can start there are a few tools required that must be present on the ``` apt-get update apt-get install --no-install-recommends --no-install-suggests -y \ - python-apt \ - python-dev \ - python-jmespath \ - python-pip \ - python-setuptools \ + make \ sudo - -pip install wheel -pip install ansible ``` #### Sudo permissions @@ -496,7 +524,7 @@ usermod -aG sudo In order to guarantee the most possible stability of this setup, extensive [travis-ci](https://travis-ci.org/cytopia/ansible-debian) checks have been defined which automatically run every night. Those tests are run inside a Docker container. The following test cases have been defined: * Each run is done randomized and in order as well as for each role separately -* Each run is done for Debian stable and Debian testing +* Each run is done for Debian stable and upgraded to testing * Each run is done against all defined profiles (repositories: main vs main, extra and non-free) @@ -516,6 +544,6 @@ Please feel free to contribute and add new roles as desired. When doing so have ## License -[MIT License](LICENSE.md) +**[MIT License](LICENSE.md)** Copyright (c) 2017 [cytopia](https://github.com/cytopia) diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..148c142 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,74 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "debian/stretch64" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + #config.vm.synced_folder "./", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + config.vm.provision "shell", privileged: false, inline: <<-SHELL + cd /vagrant + sudo apt-get update -qq + sudo apt-get install --no-install-recommends --no-install-suggests -y make + sudo make deploy-init + sudo make deploy-dist-upgrade PROFILE=#{ENV['PROFILE']} + sudo make deploy-tools PROFILE=#{ENV['PROFILE']} + SHELL +end diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..a3d70fa --- /dev/null +++ b/bootstrap @@ -0,0 +1,47 @@ +#!/bin/sh + +set -eu + +# Default profile to use +# Overwrite via command line argument +PROFILE="${1:-cytopia-t470p}" + +if ! command -v sudo >/dev/null 2>&1; then + >&2 echo "This script requires 'sudo' binary to be installed" + exit 1 +fi + +if [ "$(id -u)" -eq "0" ]; then + >&2 echo "This script must be run as normal user" + exit 1 +fi + + +### +### Install requirements to use this repository +### +sudo DEBIAN_FRONTEND=noninteractive apt update -qq +sudo apt-get install --no-install-recommends --no-install-suggests -y \ + git \ + make + + +### +### Download GitHub repository +### +git clone https://github.com/cytopia/ansible-debian-testing +cd ansible-debian-testing + + +### +### Deploy +### + +# (Step 1/3) Ensure required software is present +sudo make deploy-init + +# (Step 2/3) Add new Debian sources and dist-upgrade your system +sudo make deploy-dist-upgrade PROFILE=${PROFILE} + +# (Step 3/3) Deploy your system +sudo make deploy-tools PROFILE=${PROFILE}