Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev volatile #126

Merged
merged 11 commits into from
May 3, 2024
10 changes: 3 additions & 7 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
check_container:
env:
IMAGE: ${{ matrix.image }}
USER: random_user
REMOTE_USER: random_user
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
Expand All @@ -20,9 +20,7 @@ jobs:
- name: Check config
run: make check_host
- name: Check idempotence
run: |
make check_host | tee __build__/log
! (grep -oP "changed=\d+" __build__/log | grep -oPq "changed=[1-9]")
run: make check_host VERIFY_UNCHANGED=true
strategy:
matrix:
image: ["ubuntu:22.04", "ubuntu:23.04", "ubuntu:23.10", "ubuntu:24.04"]
Expand All @@ -35,9 +33,7 @@ jobs:
- name: Config
run: make
- name: Check idempotence
run: |
make | tee __build__/log
! (grep -oP "changed=\d+" __build__/log | grep -oPq "changed=[1-9]")
run: make VERIFY_UNCHANGED=true
# All format checks only available after complete machine setup
- name: Check format
run: |
Expand Down
11 changes: 11 additions & 0 deletions bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ if ! command -v make &>/dev/null; then
fi
fi

if ! command -v git &>/dev/null; then
if [[ $distro == ubuntu ]]; then
sudo apt-get update
sudo apt-get install --yes --no-install-recommends git
elif [[ $distro == fedora ]]; then
sudo dnf install --assumeyes git
fi
fi

if [[ "$BUILD_DIR/venv" -ot "$PROJECT_DIR/requirements.txt" ]]; then
python3 -m venv "$BUILD_DIR/venv"
source "$BUILD_DIR/venv/bin/activate"
Expand All @@ -60,6 +69,8 @@ fi

source "$BUILD_DIR/venv/bin/activate"

export ANSIBLE_LOG_PATH="$BUILD_DIR/ansible_logs/bootstrap_control_node.log"

if [[
("$BUILD_DIR/bootstrap_control_node" -ot "$BUILD_DIR/venv") ||
("$BUILD_DIR/bootstrap_control_node" -ot "$PROJECT_DIR/playbook_bootstrap_control_node.yaml") ||
Expand Down
86 changes: 86 additions & 0 deletions config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash

set -o errexit
set -o pipefail
set -o nounset
set -o xtrace

# Script parameters
# HOSTS
# IMAGE
# BUILD_DIR
# REMOTE_USER

PROJECT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")

if [[ "$HOSTS" =~ localhost || "$HOSTS" =~ 127.0.0.1 ]]; then
LOCAL=true
else
LOCAL=false
fi

logs_path="$(realpath "$BUILD_DIR")/ansible_logs"
mkdir -p "$logs_path"

if [[ $LOCAL == true ]]; then
# In case of local execution, privileges escalation is equvalent of calling sudo
# We must call it beforehand, so Ansible will not ask for password
sudo bash -c ''
fi

if [[ "$VERIFY_UNCHANGED" == true ]]; then
# Clear logs from previous runs
rm "$logs_path"/*
fi

if [[ "$HOSTS" =~ ^dotfiles_ ]]; then
ANSIBLE_LOG_PATH="$logs_path/container.log" \
ansible-playbook --extra-vars "container=$HOSTS image=$IMAGE" \
--inventory "$PROJECT_DIR/inventory.yaml" "$PROJECT_DIR/playbook_dotfiles_container.yaml"
fi

ANSIBLE_LOG_PATH="$logs_path/bootstrap_hosts.log" \
ansible-playbook --extra-vars "hosts_var=$HOSTS" \
--extra-vars "user=$REMOTE_USER" \
--inventory "$PROJECT_DIR/inventory.yaml" "$PROJECT_DIR/playbook_bootstrap_hosts.yaml"

if [[ $LOCAL == true ]] && [[ "$REMOTE_USER" != $(id --user --name) ]]; then
# A special case with local execution from a different user
# In such case Ansible does not change any environment variables, including $HOME or $USER
# Effectively Ansible executes playbook as a current user instead or $REMOTE_USER
# Thus, we must manually change user beforehand with a sudo call
#
# This, however, introduces another problem:
# After user change, privileges escalation from Ansible playbooks no longer works,
# since we have opened another shell
# To fix this, we have to call nested sudo alongside ansible call
#
# One more problem is that nested shell disguises parent's python virtual environment,
# which results in picking wrong Ansible binary.
# We have to set $PATH and $VIRTUAL_ENV manually back to their original values
chmod 777 "$logs_path"
sudo --user "$REMOTE_USER" \
bash -c " \
sudo bash -c '' && \
PATH=$PATH \
VIRTUAL_ENV=$VIRTUAL_ENV \
ANSIBLE_LOG_PATH=\"$logs_path/main.log\" \
ansible-playbook --extra-vars \"hosts_var=$HOSTS\" \
--user \"$REMOTE_USER\" \
--inventory \"$PROJECT_DIR/inventory.yaml\" \"$PROJECT_DIR/playbook.yaml\" \
"
else
ANSIBLE_LOG_PATH="$logs_path/main.log" \
ansible-playbook --extra-vars "hosts_var=$HOSTS" \
--user "$REMOTE_USER" \
--inventory "$PROJECT_DIR/inventory.yaml" "$PROJECT_DIR/playbook.yaml"
fi

if [[ "$VERIFY_UNCHANGED" == true ]]; then
for log in "$logs_path"/*; do
if (grep -oP "changed=\d+" "$log" | grep -oPq "changed=[1-9]"); then
echo "IDEMPOTENCY CHECK FAILED"
exit 1
fi
done
fi
29 changes: 11 additions & 18 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,26 @@ SHELL = /usr/bin/env bash

############################# Arguments ############################
HOSTS ?= localhost
USER ?= $(shell id --user --name)
REMOTE_USER ?= $(shell id --user --name)
VERIFY_UNCHANGED ?= false


############################## Setup ###############################
# DO NOT MANUALLY CHANGE BUILD_DIR
# This parameter is used for in-container checks
BUILD_DIR ?= __build__
BUILD_DIR := __build__
VENV := source $(BUILD_DIR)/venv/bin/activate
BOOTSTRAP := $(BUILD_DIR)/bootstrap_control_node


########################### Main targets ###########################
.PHONY: config
config: $(BOOTSTRAP)
if [[ "$(HOSTS)" =~ "localhost" || "$(HOSTS)" =~ "127.0.0.1" ]]; then \
# Before we set up a new password, we need to ask user for the existing one \
sudo bash -c ''; \
fi
if [[ "$(HOSTS)" =~ ^dotfiles_ ]]; then \
$(VENV) && ansible-playbook --extra-vars "container=$(HOSTS) image=$(IMAGE)" \
--inventory inventory.yaml playbook_dotfiles_container.yaml; \
fi
$(VENV) && ansible-playbook --extra-vars "hosts_var=$(HOSTS)" \
--inventory inventory.yaml playbook_bootstrap_hosts.yaml
$(VENV) && ansible-playbook --extra-vars "hosts_var=$(HOSTS)" \
--extra-vars "user=$(USER)" \
--inventory inventory.yaml playbook.yaml
$(VENV) && \
HOSTS=$(HOSTS) \
REMOTE_USER=$(REMOTE_USER) \
VERIFY_UNCHANGED=$(VERIFY_UNCHANGED) \
BUILD_DIR=$(BUILD_DIR) \
IMAGE=$(IMAGE) \
./config.sh

.PHONY: update
update: $(BOOTSTRAP)
Expand Down Expand Up @@ -107,4 +100,4 @@ $(BOOTSTRAP): \
requirements.txt \
roles/manifest/vars/main.yaml \

./bootstrap.sh
BUILD_DIR=$(BUILD_DIR) ./bootstrap.sh
27 changes: 26 additions & 1 deletion playbook_bootstrap_hosts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
gather_facts: false
tasks:
- name: Install python
become: true
ansible.builtin.raw: |
if ! command -v python3 &> /dev/null; then \
if command -v apt-get &> /dev/null; then \
Expand All @@ -23,3 +22,29 @@
executable: bash
register: bootstrap
changed_when: ("bootstrapped" in bootstrap.stdout)

- name: Install sudo
ansible.builtin.package:
name: sudo

- name: Set correct credentials for {{ user }}
ansible.builtin.include_tasks:
file: "roles/secrets/tasks/credentials.yaml"
vars:
secrets_user: "{{ user }}"

- name: Append admin groups for {{ user }}
become: true
ansible.builtin.user:
name: "{{ user }}"
groups:
- adm
- sudo
append: true

- name: Add authorized_key for {{ user }}
become: true
ansible.posix.authorized_key:
user: "{{ user }}"
key: "{{ lookup('file', '{{ secrets_ssh_local_path }}/id_rsa.pub') }}"
when: ansible_connection == "ssh"
10 changes: 8 additions & 2 deletions roles/basic_utils/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
- name: Check sanity
ansible.builtin.assert:
that:
- user == ansible_user
- ansible_distribution in "Ubuntu|Fedora"

- name: Install common utils for other Ansible tasks
Expand Down Expand Up @@ -33,6 +32,13 @@
database: passwd
key: "{{ ansible_user }}"

- name: Check if inside container
ansible.builtin.shell: ([[ -f /.dockerenv || -f /run/.containerenv ]]) && echo true || echo false
args:
executable: bash
changed_when: false
register: basic_utils_container_out

- name: Check if inside WSL
ansible.builtin.shell: |
set -o pipefail
Expand Down Expand Up @@ -63,7 +69,7 @@
home: "{{ getent_passwd[ansible_user].4 }}"
user_id: "{{ getent_passwd[ansible_user].1 }}"
trusted: "{{ hostvars[inventory_hostname]['trusted'] }}"
in_container: "{{ in_container }}"
in_container: "{{ basic_utils_container_out.stdout }}"
in_wsl: "{{ basic_utils_wsl.stdout }}"
use_gui: "{{ basic_utils_x_list.files | length > 0 }}"

Expand Down
1 change: 0 additions & 1 deletion roles/profile/defaults/main.yaml

This file was deleted.

31 changes: 0 additions & 31 deletions roles/profile/tasks/main.yaml

This file was deleted.

5 changes: 3 additions & 2 deletions roles/secrets/tasks/credentials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@
secrets_pass: ""
when: not secrets_creds_status.stat.exists or in_container

- name: credentials | Set user password "{{ user }}"
- name: credentials | Set password for {{ secrets_user }}
become: true
ansible.builtin.user:
name: "{{ user }}"
name: "{{ secrets_user }}"
password: "{{ secrets_hashed_pass }}"

- name: credentials | Set ansible_sudo_pass
ansible.builtin.set_fact:
ansible_sudo_pass: "{{ secrets_pass }}"
no_log: true
when: ansible_user == secrets_user
2 changes: 1 addition & 1 deletion roles/secrets/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@
when: ("secret key imported" in secrets_gpg_imported.stdout) or (secrets_gpg_imported_now is not skipped)
changed_when: false

- name: Set correct credentials for the user {{ user }}
- name: Set correct credentials for {{ ansible_user }}
ansible.builtin.include_tasks:
file: credentials.yaml
1 change: 1 addition & 0 deletions roles/secrets/vars/main.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
secrets_user: "{{ ansible_user }}"
secrets_gpg_key_path: "{{ dotfiles_path }}/private.gpg"
secrets_ssh_path: "{{ dotfiles_path }}/roles/secrets/files/ssh"
secrets_vpn_path: "{{ dotfiles_path }}/roles/secrets/files/vpn"
Loading