diff --git a/.github/workflows/ansible-linting-check.yml b/.github/workflows/ansible-linting-check.yml index eb30892..5ed3e8a 100644 --- a/.github/workflows/ansible-linting-check.yml +++ b/.github/workflows/ansible-linting-check.yml @@ -2,7 +2,11 @@ name: Ansible Lint check # yamllint disable-line rule:truthy -on: [push, pull_request] +on: + push: + branches: '*' + pull_request: + branches: '*' jobs: build: @@ -10,9 +14,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - name: Lint Ansible Playbook - uses: ansible/ansible-lint-action@master + - name: 'checkout git repo' + uses: actions/checkout@v3 with: - targets: "site.yml" + lfs: true + submodules: true + fetch-depth: 0 + + - name: 'Lint Ansible Playbook' + uses: ansible/ansible-lint-action@v6 + with: + path: "." diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 0000000..876c6ad --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,15 @@ +--- +name: 'Pylint GitHub Actions' + +# yamllint disable-line rule:truthy +on: [push, pull_request] + +jobs: + pylint: + name: 'Pylint' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@master + - name: GitHub Action for pylint + uses: cclauss/GitHub-Action-for-pylint@0.7.0 diff --git a/.github/workflows/yamllint.yaml b/.github/workflows/yamllint.yaml index 39c49f8..c4894bd 100644 --- a/.github/workflows/yamllint.yaml +++ b/.github/workflows/yamllint.yaml @@ -18,5 +18,3 @@ jobs: yamllint_config_filepath: './.yamllint' yamllint_strict: false yamllint_comment: true -# env: -# GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN } diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83b53f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +ansible/ diff --git a/.gitmodules b/.gitmodules index 3419572..b7c545f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,69 +1,98 @@ [submodule "roles/workstation_packages"] path = roles/workstation_packages url = https://github.com/chaos-bodensee/role_install_workstaton_packages.git + branch = master [submodule "roles/dotfiles"] path = roles/dotfiles - url = https://github.com/chaos-bodensee/role_dotfiles.git + url = https://github.com/roles-ansible/ansible_role_dotfiles.git + branch = main [submodule "roles/pulseaudio"] path = roles/pulseaudio url = https://github.com/chaos-bodensee/role_pulseaudio_archlinux.git + branch = master [submodule "roles/authorized_keys"] path = roles/do1jlr.auth - url = https://github.com/ffbsee/role-ssh_authorized_keys.git + url = https://github.com/roles-ansible/ansible_role_auth.git + branch = main [submodule "files/admin_ssh_keys"] path = files/admin_ssh_keys url = https://backwesen.de/ansible/ssh_public_keys.git + branch = main [submodule "roles/sshd"] path = roles/do1jlr.sshd url = https://github.com/roles-ansible/ansible_role_sshd.git + branch = main [submodule "roles/nextcloud"] path = roles/nextcloud url = https://github.com/DO1JLR/role_nextcloud_client.git -[submodule "roles/ntp"] - path = roles/ntp - url = https://github.com/chaos-bodensee/role-ntp.git + branch = master [submodule "roles/arch-fonts"] path = roles/arch-fonts url = https://github.com/chaos-bodensee/role-arch-fonts.git + branch = master [submodule "roles/akku-warning"] path = roles/akku-warning url = https://github.com/roles-ansible/role_akku_warning.git + branch = main [submodule "roles/install-firefox"] path = roles/install-firefox url = https://github.com/roles-ansible/ansible_role_install_firefox.git + branch = main [submodule "roles/xrandr"] path = roles/xrandr - url = https://github.com/chaos-bodensee/role-xrandr.git + url = https://github.com/roles-ansible/ansible_role_xrandr_help.git + branch = main [submodule "roles/winehq"] path = roles/winehq url = https://github.com/ekultails/ansible_role_wine.git + branch = master [submodule "roles/no-sleep"] path = roles/no-sleep url = https://github.com/chaos-bodensee/role_disable_sleep.git + branch = master [submodule "roles/manage_users"] path = roles/do1jlr.users - url = https://github.com/chaos-bodensee/role-manage_users.git + url = https://github.com/roles-ansible/ansible_role_users.git + branch = main [submodule "roles/polybar"] path = roles/polybar url = https://github.com/chaos-bodensee/role_install-polybar.git + branch = master [submodule "roles/ansible_version"] path = roles/ansible_version url = https://github.com/chaos-bodensee/role-ansible_version.git + branch = main [submodule "roles/base"] path = roles/do1jlr.base url = https://github.com/roles-ansible/ansible_role_base.git -[submodule "roles/bat"] - path = roles/bat - url = https://github.com/gantsign/ansible_role_bat.git + branch = main [submodule "roles/amdgpu_firmware"] path = roles/amdgpu_firmware url = https://github.com/DO1JLR/ansible_role_amdgpu_firmware.git + branch = main [submodule "roles/do1jlr.avahi"] path = roles/do1jlr.avahi_daemon url = https://github.com/roles-ansible/ansible_role_avahi_daemon.git + branch = main [submodule "roles/do1jlr.avahi_client"] path = roles/do1jlr.avahi_client url = https://github.com/roles-ansible/ansible_role_avahi_client.git + branch = main [submodule "roles/do1jlr.i3wm"] path = roles/do1jlr.i3wm url = https://github.com/roles-ansible/ansible_role_i3wm.git + branch = main +[submodule "roles/do1jlr.htop"] + path = roles/do1jlr.htop + url = https://github.com/roles-ansible/ansible_role_htop.git + branch = main +[submodule "collections/ansible_collections/community/general"] + path = collections/ansible_collections/community/general + url = https://github.com/ansible-collections/community.general.git + branch = main +[submodule "roles/gantsign.bat"] + path = roles/gantsign.bat + url = https://github.com/gantsign/ansible_role_bat.git +[submodule "roles/l3d.ntp"] + path = roles/l3d.ntp + url = https://github.com/roles-ansible/ansible_role_ntp.git diff --git a/.yamllint b/.yamllint index be0cacf..283da64 100644 --- a/.yamllint +++ b/.yamllint @@ -9,3 +9,5 @@ rules: ignore: | roles/ + collections/ + ansible/ diff --git a/README.md b/README.md index 90b1e27..45b358b 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,20 @@ Ansible Linux Desktop Setup ========================== -This ansible playbook collection creates [L3D](https://chaos.social/@l3d)s Desktop enviroment. Including window manager and some pre-installed programms like [Firefox](https://www.mozilla.org/de/firefox/new/) and some usefull shell programms. +This ansible playbook collection manages some of my workstations and laptops. Because of this it sometimes contains very specific variables like my username, SSH keys or similar data that may not be the best choice for your system. - ATTENTION +Nevertheless, this ansible playbook is not only publicly available on the internet, but by the MIT license a part of free open-source ansible, which may serve you as inspiration within the framework of the MIT license. + + + Inventory ------------- -Different to my other ansible playbooks: +This is my first ansible with dynamic inventory. The [inventory.py](inventory.py) script looks at which hostname it was lauched on. If the hostname is known, the host is mapped to the group stored for it and a local connection to the host is established. -### THIS PLAYBOOK HAS TO BE EXECUTET AT THE TARGET HOST DIRECTLY! +This has the advantage that different environments are automatically recognized and significantly less danger of accidentally rolling out the ansible with the variables for a completely different host and thus configuring things that were not intended for this device. -*It requires some GUI stuff and I did not find the time to forward X or wayland correctly to make it remotely working. Sorry. Feel free to create a Issue or pull-request* +Obviously, this also means that **this playbook must always be run on the host you want to manage** and this ansible playbook is not meant to be run remotely. - Install tipps: + +Install tipps: ----------------------- ```bash # Clone Git @@ -24,6 +28,15 @@ git submodule update --init --recursive # make sure you always check out the submodules git config --global submodule.recurse true + +# Install Ansible in venv +python3 -m venv ansible + +# Activate Venv +source ansible/bin/activate + +# Install Ansible +pip3 install --upgrade ansible-core ansible-lint pylint ``` Which playbook? @@ -41,3 +54,7 @@ Or create a new git repo and be inspired by the roles L3D uses. If you find this usefull please take a few secounds and say thankyou to L3D. He is at the most [chaos events](https://events.ccc.de), simple give him a Tschunk or Club Mate there! + + Additional Infos +------------------ +By the way, to store sensible passwords, I am using the [community.general.passwordstore](https://docs.ansible.com/ansible/latest/collections/community/general/passwordstore_lookup.html) Lookup to access my passwords, stored in [gopass](https://gopass.pw/) Password Manager. diff --git a/ansible.cfg b/ansible.cfg index 0578235..09c82d2 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,11 +1,13 @@ [defaults] -inventory = ./hosts.ini -retry_files_enabled = False -nocows = True -ansible_connection = 'local' +inventory = ./inventory.py +retry_files_enabled = false +nocows = true +transport = local +interpreter_python = /usr/bin/python3 [privilege_escalation] become_method = sudo become_user = root -become_ask_pass = False +[passwordstore_lookup] +backend = "gopass" diff --git a/collections/ansible_collections/community/general b/collections/ansible_collections/community/general new file mode 160000 index 0000000..9b493d5 --- /dev/null +++ b/collections/ansible_collections/community/general @@ -0,0 +1 @@ +Subproject commit 9b493d53a9ff40139c185ff2dc4a7c5d6cf761a6 diff --git a/group_vars/all.yml b/group_vars/all.yml index 3986ddd..29d1e9d 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -68,5 +68,7 @@ i3_run_on_startup: # - nextcloud - sudo nm-applet +htop__compile: true + # globaly enably simple versionscheck - if available submodules_versioncheck: true diff --git a/inventory.py b/inventory.py new file mode 100755 index 0000000..696cd8b --- /dev/null +++ b/inventory.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Create a dynamic inventory for this ansible playbook +""" +import socket +import sys +import json + +# create a dict to match hostnames to enviroments +env_dict = { + 'work': + ['workstation.local', 'daringdoo.local'], + 'private': + ['derpy.local', 'applejack.local', 'rarity.local'] +} + +def fqdn(): + """ + return fully qualified domain name + """ + hostname = socket.gethostname() + if '.' not in hostname: + hostname = f"{hostname}.local" + return str(hostname) + +def become_pass(host): + """ + return variable for become password using gopass lookup + """ + passstring = str("\"ansible_become_pass\": " + + "\"{{ lookup('community.general.passwordstore', 'ansible/hosts/" + + host + "/users/root') }}\"") + return passstring + +def env(domain): + """ + map a hostname to a space + or print empty list if no one matched and exit + """ + for key, values in env_dict.items(): + if domain in values: + return key + print(json.dumps(empty_host_list(domain), sort_keys=True, indent=2)) + sys.exit() + +def empty_host_list(domain): + """ + return empty host list + """ + comment = f"No valid host found. Found '{domain}'. Return empty host list!" + return json.loads('{"_meta": {"comment": "' + comment + + '", "hostvars": {}}, "instances": {"hosts": []}}') + +def hostvars(host): + """ + set variables to local connection + """ + local = str('"' + host + '": {"ansible_connection": "local", ' + str(become_pass(host)) + '}') + return local + +def formated_host_group_list(host, group): + """ + build inventory and return it + """ + # pylint: disable=line-too-long + return json.loads('{"_meta": {"hostvars": {' + str(hostvars(host)) + '}},"' + str(group) + '": {"hosts": ["' + str(host) + '"]},"instances": {"children": ["' + str(group) + '"]}}') + +def main(): + """ + main funktion + will analyse on which host this script is started + and will print the dynamic inventory to tell ansible + which host_vars and group_vars should be used + """ + host = fqdn() + group = env(host) + print(json.dumps(formated_host_group_list(host, group), sort_keys=True, indent=2)) + +main() diff --git a/roles/ansible_version b/roles/ansible_version index ef4cf76..2bf5d7c 160000 --- a/roles/ansible_version +++ b/roles/ansible_version @@ -1 +1 @@ -Subproject commit ef4cf763795d61e883b1867f4a3149568d4acb2d +Subproject commit 2bf5d7c4369a8213b42829b14f78920e9906d099 diff --git a/roles/bat b/roles/bat deleted file mode 160000 index 10c6fdb..0000000 --- a/roles/bat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 10c6fdb93cd4332e444f8c2a5bc135ff123588f7 diff --git a/roles/do1jlr.htop b/roles/do1jlr.htop new file mode 160000 index 0000000..46a2dde --- /dev/null +++ b/roles/do1jlr.htop @@ -0,0 +1 @@ +Subproject commit 46a2dde4efe40245f461cac542c0b3993a833850 diff --git a/roles/gantsign.bat b/roles/gantsign.bat new file mode 160000 index 0000000..b263e5e --- /dev/null +++ b/roles/gantsign.bat @@ -0,0 +1 @@ +Subproject commit b263e5e140ee3c5e868f9392b2e4a2eaa37eaf79 diff --git a/roles/l3d.ntp b/roles/l3d.ntp new file mode 160000 index 0000000..c4ff771 --- /dev/null +++ b/roles/l3d.ntp @@ -0,0 +1 @@ +Subproject commit c4ff7711a14a9a34af60cfa122c9331d15760582 diff --git a/roles/ntp b/roles/ntp deleted file mode 160000 index 8d33019..0000000 --- a/roles/ntp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8d330190c4052981bdb146136dc7f41071a66289 diff --git a/setup_desk_minni.yml b/setup_desk_minni.yml deleted file mode 100644 index 3a573a0..0000000 --- a/setup_desk_minni.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: check if ansible is not to old - hosts: localhost - roles: - - {role: ansible_version, tags: always, gather_facts: false} - -- name: base packages setup - hosts: desk_minni.local - roles: - - {role: workstation_packages, tags: [base, packages, workstation]} - -- name: user and ssh(d) setup - hosts: desk_minni.local - roles: - - {role: do1jlr.users, tags: [users, base]} - - {role: do1jlr.auth, tags: [auth, base]} - - {role: do1jlr.sshd, tags: [sshd, base]} - - {role: dotfiles, tags: [dotfiles, base]} - -- name: fancy schnickschnack - hosts: desk_minni.local - roles: - - {role: akku-warning, tags: akku} - # - {role: pulseaudio, tags: [pulse, audio, pulseaudio]} - - {role: networkmanager, tags: networkmanager, when: ansible_os_family == 'Archlinux'} - - {role: openvpn, tags: ovpn} - - {role: nextcloud, tags: nextcloud, when: ansible_os_family == 'Archlinux'} - - {role: bat, tags: bat, when: ansible_os_family == 'Debian'} - - {role: install-firefox, tags: firefox} - - {role: copy_files} - - {role: do1jlr.i3wm, tags: i3wm} - - {role: ntp, tags: ntp} - - {role: xrandr, tags: xrandr} - - {role: arch-fonts, tags: fonts} - # - {role: winehq, tags: wine} - - {role: no-sleep, tags: sleep} - - {role: do1jlr.avahi_daemon, tags: [avahi_daemon, avahi]} - - {role: do1jlr.avahi_client, tags: [avahi_client, mdns]} diff --git a/setup_l14.yml b/setup_l14.yml deleted file mode 100644 index e87c712..0000000 --- a/setup_l14.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- name: check if ansible is not to old - hosts: localhost - roles: - - {role: ansible_version, tags: always, gather_facts: false} - -- name: base packages setup - hosts: l14.local - roles: - - {role: workstation_packages, tags: [base, packages, workstation]} - - {role: amdgpu_firmware, tags: [amdgpu, firmware]} - -- name: user and ssh(d) setup - hosts: l14.local - roles: - - {role: do1jlr.users, tags: [users, base]} - - {role: do1jlr.auth, tags: [auth, base]} - - {role: do1jlr.sshd, tags: [sshd, base]} - - {role: dotfiles, tags: [dotfiles, base]} - -- name: fancy schnickschnack - hosts: l14.local - roles: - - {role: akku-warning, tags: akku} -# - {role: pulseaudio, tags: [pulse, audio, pulseaudio]} - - {role: networkmanager, tags: networkmanager, when: ansible_os_family == 'Archlinux'} - - {role: openvpn, tags: ovpn} - - {role: nextcloud, tags: nextcloud, when: ansible_os_family == 'Archlinux'} - - {role: bat, tags: bat, when: ansible_os_family == 'Debian'} - - {role: install-firefox, tags: firefox} - - {role: copy_files} - - {role: do1jlr.i3wm, tags: i3wm} - - {role: ntp, tags: ntp} - - {role: xrandr, tags: xrandr} - - {role: arch-fonts, tags: fonts} -# - {role: winehq, tags: wine} - - {role: no-sleep, tags: sleep} - - {role: do1jlr.avahi_daemon, tags: [avahi_daemon, avahi]} - - {role: do1jlr.avahi_client, tags: [avahi_client, mdns]} diff --git a/setup_t460p.yml b/setup_t460p.yml deleted file mode 100644 index 6bf5acf..0000000 --- a/setup_t460p.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: check if ansible is not to old - hosts: localhost - roles: - - {role: ansible_version, tags: always, gather_facts: false} - -- name: base packages setup - hosts: t460p.local - roles: - - {role: workstation_packages, tags: [base, packages, workstation]} - -- name: user and ssh(d) setup - hosts: t460p.local - roles: - - {role: do1jlr.users, tags: [users, base]} - - {role: do1jlr.auth, tags: [auth, base]} - - {role: do1jlr.sshd, tags: [sshd, base]} - - {role: dotfiles, tags: [dotfiles, base]} - -- name: fancy schnickschnack - hosts: t460p.local - roles: - - {role: akku-warning, tags: akku} -# - {role: pulseaudio, tags: [pulse, audio, pulseaudio]} - - {role: networkmanager, tags: networkmanager, when: ansible_os_family == 'Archlinux'} - - {role: openvpn, tags: ovpn} - - {role: nextcloud, tags: nextcloud, when: ansible_os_family == 'Archlinux'} - - {role: bat, tags: bat, when: ansible_os_family == 'Debian'} - - {role: install-firefox, tags: firefox} - - {role: copy_files} - - {role: do1jlr.i3wm, tags: i3wm} - - {role: ntp, tags: ntp} - - {role: xrandr, tags: xrandr} - - {role: arch-fonts, tags: fonts} - # - {role: winehq, tags: wine} - - {role: no-sleep, tags: sleep} - - {role: do1jlr.avahi_daemon, tags: [avahi_daemon, avahi]} - - {role: do1jlr.avahi_client, tags: [avahi_client, mdns]} diff --git a/setup_workstation.yml b/setup_workstation.yml deleted file mode 100644 index 825dbdd..0000000 --- a/setup_workstation.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: check if ansible is not to old - hosts: localhost - roles: - - {role: ansible_version, tags: always, gather_facts: false} - -- name: base packages setup - hosts: workstation.local - roles: - - {role: workstation_packages, tags: [base, packages, workstation]} - -- name: user and ssh(d) setup - hosts: workstation.local - roles: - - {role: do1jlr.users, tags: [users, base]} - - {role: do1jlr.auth, tags: [auth, base]} - - {role: do1jlr.sshd, tags: [sshd, base]} - - {role: dotfiles, tags: [dotfiles, base]} - -- name: fancy schnickschnack - hosts: workstation.local - roles: - - {role: akku-warning, tags: akku} - - {role: pulseaudio, tags: [pulse, audio, pulseaudio]} - - {role: networkmanager, tags: networkmanager, when: ansible_os_family == 'Archlinux'} - - {role: openvpn, tags: ovpn} - - {role: nextcloud, tags: nextcloud, when: ansible_os_family == 'Archlinux'} - - {role: bat, tags: bat, when: ansible_os_family == 'Debian'} - - {role: install-firefox, tags: firefox} - - {role: copy_files} - - {role: do1jlr.i3wm, tags: i3wm} - - {role: ntp, tags: ntp} - - {role: xrandr, tags: xrandr} - - {role: arch-fonts, tags: fonts} - - {role: winehq, tags: wine} - - {role: no-sleep, tags: sleep} - - {role: do1jlr.avahi_daemon, tags: [avahi_daemon, avahi]} - - {role: do1jlr.avahi_client, tags: [avahi_client, mdns]} diff --git a/site.yml b/site.yml index 6cc0d3f..a349178 100644 --- a/site.yml +++ b/site.yml @@ -1,32 +1,35 @@ --- - name: check if ansible is not to old - hosts: localhost + hosts: all roles: - {role: ansible_version, tags: always, gather_facts: false} -- name: run do1jlr.base setup roles - hosts: localhost +- name: Generic Workstation Preperation + hosts: all roles: - - {role: do1jlr.base, tags: [default, packages, base]} - - {role: workstation_packages, tags: [default, workstation_packages, packages, setup]} - - {role: ntp, tags: ntp} - - {role: arch-fonts, tags: [font, fonts, arch-fonts]} + # - {role: do1jlr.base, tags: [default, packages, base]} + # - {role: workstation_packages, tags: [default, workstation_packages, packages, setup]} + - {role: l3d.ntp, tags: ntp} + - {role: do1jlr.avahi_client, tags: avahi} + - {role: do1jlr.avahi_daemon, tags: avahi} + - {role: gantsign.bat, tags: bat} + # - {role: arch-fonts, tags: [font, fonts, arch-fonts]} -- name: user specific setup - hosts: localhost - roles: - - {role: dotfiles, tags: [default, dotfiles, fancy]} - - {role: manage_users, tags: [ssh, manage, manage_users]} - - {role: authorized_keys, tags: [ssh, auth, authorized_keys]} - - {role: sshd, tags: [ssh, sshd]} - - {role: akku-warning, tags: [akku, akku_warning, akku-warning]} - - {role: pulseaudio, tags: pulseaudio} - - {role: networkmanager, tags: [nm, networkmanager]} - - {role: copy_files} - - {role: do1jlr.i3wm, tags: i3wm} - - {role: xrandr, tags: xrandr} - - {role: install-firefox, tags: firefox} - - {role: nextcloud, tags: nextcloud} - - {role: openvpn, tags: openvpn} - - {role: winehq, tags: [wine, winehq]} - - {role: no-sleep, tags: no_sleep} +# - name: user specific setup +# hosts: private +# roles: +# - {role: dotfiles, tags: [default, dotfiles, fancy]} +# - {role: manage_users, tags: [ssh, manage, manage_users]} +# - {role: authorized_keys, tags: [ssh, auth, authorized_keys]} +# - {role: sshd, tags: [ssh, sshd]} +# - {role: akku-warning, tags: [akku, akku_warning, akku-warning]} +# - {role: pulseaudio, tags: pulseaudio} +# - {role: networkmanager, tags: [nm, networkmanager]} +# - {role: copy_files} +# - {role: do1jlr.i3wm, tags: i3wm} +# - {role: xrandr, tags: xrandr} +# - {role: install-firefox, tags: firefox} +# - {role: nextcloud, tags: nextcloud} +# - {role: openvpn, tags: openvpn} +# - {role: winehq, tags: [wine, winehq]} +# - {role: no-sleep, tags: no_sleep}