diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5b1ce4f..b6f528e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -49,10 +49,10 @@ "files.associations": { ".ansible-lint": "yaml", ".gitmessage": "git-commit", - "**/pb_*.yml": "ansible", "**/playbooks/*.yml": "ansible", "**/roles/**/tasks/*.yml": "ansible", - "inventory_*": "ansible" + "**/inventory*.yml": "ansible", + "**/*.just": "just" }, // Ansible configuration "ansible.validation.enabled": true, @@ -97,6 +97,7 @@ "mutantdino.resourcemonitor", "redhat.ansible", "redhat.vscode-yaml", + "skellock.just", "streetsidesoftware.code-spell-checker-german", "streetsidesoftware.code-spell-checker", "tamasfe.even-better-toml" diff --git a/.devcontainer/install-dev-tools.sh b/.devcontainer/install-dev-tools.sh index 495eba5..d66f033 100644 --- a/.devcontainer/install-dev-tools.sh +++ b/.devcontainer/install-dev-tools.sh @@ -35,7 +35,7 @@ echo -e "${YELLOW}Installing project dependencies${ENDCOLOR}" echo "" poetry install --no-root -C /workspaces/forge/ansible -Install ansible dependencies +# Install ansible dependencies echo "" echo -e "${YELLOW}Installing ansible dependencies${ENDCOLOR}" echo "" diff --git a/.vscode/cspell_custom.txt b/.vscode/cspell_custom.txt index 3515fa6..c6cc326 100644 --- a/.vscode/cspell_custom.txt +++ b/.vscode/cspell_custom.txt @@ -27,5 +27,7 @@ rvproxy serverstransport traefik ublue +varnames venvs +wantlist websecure diff --git a/README.md b/README.md index 3b75af0..c23dee1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -# forge +# Universal Blue - Forge -On-premises Universal Blue - -This repo is intended to provide the service units necessary to set up a -self-hosted OS forge for custom images. +On-premises Universal Blue. This repository is intended to provide the service units +necessary to set up a self-hosted OS forge for custom images. > **Warning** > This project is "work in progress" and not ready for production @@ -55,12 +53,42 @@ The shiny GUI is missing but this should not shy us away. See [usage](#usage) fo You can use the `forge.sh` to **setup**, **heat-up** and **cool-down** the forge. + + | Command | Description | | ---------------------- | ----------------------------------------------------------- | | `./forge.sh setup` | Setup the forge for the first time or update existing setup | | `./forge.sh heat-up` | Start the forge | | `./forge.sh cool-down` | Stop the forge | + + ### Usage -..tbd... +Once the forge has been setup the following recipes are available via [just command runner](https://github.com/casey/just). + + + +| Just recipe | Input argument | Default argument value | Description | +| --------------------- | ----------------------- | ------------------------------------------- | -------------------------------------------- | +| `forge_project-clone` | `forge_config_var_file` | $HOME/ublue-os_forge/forge_default_vars.env | Clone git project repository | +| `forge_project-build` | `forge_config_var_file` | $HOME/ublue-os_forge/forge_default_vars.env | Build container image and upload to registry | + + + +All available settings for the `forge_config_var_file` are documented in the [variables.md](./docs/variables.md) +file. To launch a recipe you simple run: + +```sh +just -f forge.just {{ recipe_name }} {{ forge_config_var_file }} +``` + +**_Example:_** + +```sh +just -f forge.just forge_project-clone /var/home/stephan/ublue-os_forge/my-forge-project.env +``` + +In case you don't have [just command runner](https://github.com/casey/just) available. +Have a look at the [forge.just](./forge.just) file. It easy enough to understand which commands +are executed via the just recipes. diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml deleted file mode 100644 index 912fbf4..0000000 --- a/ansible/group_vars/all.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -# variables used for all groups and hosts - -## container registry -forge_registry_url: registry.ublue.local - -## Git -forge_git_repository_url: https://github.com/ublue-os/bluefin.git -forge_git_repository_destination: "{{ ansible_facts.env.HOME }}/ublue-os/forge/bluefin" -forge_git_repository_version: main diff --git a/ansible/group_vars/all/data.yml b/ansible/group_vars/all/data.yml new file mode 100644 index 0000000..c01d5a2 --- /dev/null +++ b/ansible/group_vars/all/data.yml @@ -0,0 +1,4 @@ +--- +# data variables +forge_data_path: "{{ lookup('ansible.builtin.env', 'FORGE_DATA_PATH', default=ansible_facts.env.HOME + '/ublue-os_forge') }}" +forge_data_default_variables_file_path: "{{ forge_data_path }}/forge_default_vars.env" diff --git a/ansible/group_vars/all/git.yml b/ansible/group_vars/all/git.yml new file mode 100644 index 0000000..3ccb118 --- /dev/null +++ b/ansible/group_vars/all/git.yml @@ -0,0 +1,5 @@ +--- +# git variables +forge_git_repository_url: "{{ lookup('ansible.builtin.env', 'FORGE_GIT_REPOSITORY_URL', default='https://github.com/ublue-os/bluefin.git') }}" +forge_git_repository_destination: "{{ lookup('ansible.builtin.env', 'FORGE_GIT_REPOSITORY_DESTINATION', default=forge_data_path + '/bluefin') }}" +forge_git_repository_version: "{{ lookup('ansible.builtin.env', 'FORGE_GIT_REPOSITORY_VERSION', default='main') }}" diff --git a/ansible/group_vars/all/registry.yml b/ansible/group_vars/all/registry.yml new file mode 100644 index 0000000..66fcfaf --- /dev/null +++ b/ansible/group_vars/all/registry.yml @@ -0,0 +1,3 @@ +--- +# container registry variables +forge_registry_url: "{{ lookup('ansible.builtin.env', 'FORGE_REGISTRY_URL', default='registry.ublue.local') }}" diff --git a/ansible/host_vars/host.ublue.local.yml b/ansible/host_vars/host.ublue.local.yml deleted file mode 100644 index 361ccd7..0000000 --- a/ansible/host_vars/host.ublue.local.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# variables used in playbooks with target host.ublue.local diff --git a/ansible/host_vars/localhost.yml b/ansible/host_vars/localhost.yml index e187c8f..72af712 100644 --- a/ansible/host_vars/localhost.yml +++ b/ansible/host_vars/localhost.yml @@ -1,2 +1,4 @@ +--- +# localhost variables ansible_connection: local ansible_python_interpreter: "{{ ansible_playbook_python }}" diff --git a/ansible/playbooks/configure_host.yml b/ansible/playbooks/configure_host.yml index 25fb8bd..aefd887 100644 --- a/ansible/playbooks/configure_host.yml +++ b/ansible/playbooks/configure_host.yml @@ -24,3 +24,26 @@ cmd: update-ca-trust changed_when: false become: true + + - name: Create default directory for forge content + ansible.builtin.file: + path: "{{ forge_data_path }}" + state: directory + mode: "0755" + + - name: Create default configuration variable file + ansible.builtin.copy: + dest: "{{ forge_data_default_variables_file_path }}" + content: | + ## ublue-os forge configuration variables defaults + ## For more details got to https://github.com/ublue-os/forge/blob/main/docs/variables.md + + {% for item in __vars_used %} + #{{ item | upper }}={{ lookup('ansible.builtin.vars', item) }} + {% endfor %} + backup: true + owner: "{{ ansible_facts.env.USER }}" + mode: "0644" + vars: + __vars_used: "{{ lookup('ansible.builtin.varnames', __regex_search, wantlist=true) }}" + __regex_search: ^forge_.+ diff --git a/ansible/playbooks/project_build.yml b/ansible/playbooks/project_build.yml index 8e790ca..cd76580 100644 --- a/ansible/playbooks/project_build.yml +++ b/ansible/playbooks/project_build.yml @@ -2,10 +2,15 @@ - name: Build project hosts: host.ublue.local gather_facts: true + pre_tasks: + - name: DEBUG - forge variables + ansible.builtin.include_role: + name: debug_forge_vars + tasks: - - name: Build and push an image to registry + - name: Build and push image to registry containers.podman.podman_image: - name: bluefin + name: "{{ forge_git_repository_url | regex_search(__regex_search) }}" tag: latest path: "{{ forge_git_repository_destination }}" build: @@ -15,3 +20,10 @@ push: true push_args: dest: "{{ forge_registry_url }}" + vars: + __regex_search: (?<=/)[^/]+(?=\.git) + register: __podman_image_info + + - name: INFO | Status from build and push + ansible.builtin.debug: + msg: "{{ __podman_image_info }}" diff --git a/ansible/playbooks/project_clone.yml b/ansible/playbooks/project_clone.yml index 66e99fb..36bf457 100644 --- a/ansible/playbooks/project_clone.yml +++ b/ansible/playbooks/project_clone.yml @@ -2,9 +2,18 @@ - name: Clone project hosts: host.ublue.local gather_facts: true + pre_tasks: + - name: DEBUG - forge variables + ansible.builtin.include_role: + name: debug_forge_vars tasks: - name: Clone project ansible.builtin.git: repo: "{{ forge_git_repository_url }}" dest: "{{ forge_git_repository_destination }}" version: "{{ forge_git_repository_version }}" + register: __git_clone_info + + - name: INFO | Status from git clone + ansible.builtin.debug: + msg: "{{ __git_clone_info }}" diff --git a/ansible/roles/debug_forge_vars/README.md b/ansible/roles/debug_forge_vars/README.md new file mode 100644 index 0000000..560eb0e --- /dev/null +++ b/ansible/roles/debug_forge_vars/README.md @@ -0,0 +1,46 @@ +# Role - debug_forge_vars + +This role is used for debugging purposes only. + +## Variables + +The role has the following variables defined. + +### default/main.yml + +In the [main.yml](./defaults/main.yml/) all variables are defined which are +used in the context of debugging. Usually end-users should not worry about them to much. + + + +| name | type | default value | description | +| ------------------------------- | ---- | ------------- | ------------------------------------------------------------------------------------------- | +| `forge_debug_vars_regex_search` | str | ^forge\_.+ | Python regex search term. Useful if you want to print out all variables starting with `xyz` | + + + +## Example Playbook Usage + +This role is best included in a playbook as pre-task: + +```yaml +pre_tasks: + - name: DEBUG - forge variables + ansible.builtin.include_role: + name: debug_forge_vars +``` + +With the role included you can launch the playbook in verbose mode `ansible-playbook -v`. +This will print all variables found with the regex search term defined in the `forge_debug_vars_regex_search` +variable. + +You can modify the `forge_debug_vars_regex_search` term by changing it via the vars statement + +```yaml +pre_tasks: + - name: DEBUG - forge git variables + ansible.builtin.include_role: + name: debug_forge_vars + vars: + forge_debug_vars_regex_search: ^forge_git.+ +``` diff --git a/ansible/roles/debug_forge_vars/defaults/main.yml b/ansible/roles/debug_forge_vars/defaults/main.yml new file mode 100644 index 0000000..64ddde6 --- /dev/null +++ b/ansible/roles/debug_forge_vars/defaults/main.yml @@ -0,0 +1,2 @@ +# Default vars for this role +forge_debug_vars_regex_search: "{{ lookup('ansible.builtin.env', 'FORGE_DEBUG_VARS_REGEX_SEARCH', default='^forge_.+') }}" diff --git a/ansible/roles/debug_forge_vars/tasks/main.yml b/ansible/roles/debug_forge_vars/tasks/main.yml new file mode 100644 index 0000000..cebb679 --- /dev/null +++ b/ansible/roles/debug_forge_vars/tasks/main.yml @@ -0,0 +1,13 @@ +--- +# main task file for this role + +- name: DEBUG | forge variables + ansible.builtin.debug: + msg: "{{ item }}: {{ lookup('ansible.builtin.vars', item) }}" + verbosity: 1 + loop: "{{ __forge_vars_used }}" + loop_control: + extended: true + label: "{{ ansible_loop.index }}/{{ ansible_loop.length }}" + vars: + __forge_vars_used: "{{ lookup('ansible.builtin.varnames', forge_debug_vars_regex_search, wantlist=true) }}" diff --git a/docs/variables.md b/docs/variables.md new file mode 100644 index 0000000..5252b53 --- /dev/null +++ b/docs/variables.md @@ -0,0 +1,52 @@ +# Variables + +The following sections contains all important variables defined for daily usage. +All variables mentioned here can be declared in a line-delimited file of environment variables. + +An example file on the host system with all variables available will be created on setup +for you. By default it can be found under `$HOME/ublue-os_forge/forge_default_vars.env`. + +On playbook launch the variable file will be imported into the ansible container so that +the settings are available during playbook execution. + +## group_vars/all/data.yml + +In the [data.yml](../ansible/group_vars/all/data.yml) all variables are defined +which are used in the context of the data handling. + + + +| name | type | environment variable | default value | description | +| ---------------------------------------- | ---- | -------------------- | ------------------------------------------- | --------------------------------------------- | +| `forge_data_path` | str | `FORGE_DATA_PATH` | $HOME/ublue-os_forge | Path where forge will store files per default | +| `forge_data_default_variables_file_path` | str | | $HOME/ublue-os_forge/forge_default_vars.env | Path to default configuration file | + + + +## group_vars/all/git.yml + +In the [git.yml](../ansible/group_vars/all/git.yml/) all variables are defined which are +used in the context of the git repositories. + + + +| name | type | environment variable | default value | description | +| ---------------------------------- | ---- | ---------------------------------- | ----------------------------------------- | ---------------------------------------------- | +| `forge_git_repository_url` | str | `FORGE_GIT_REPOSITORY_URL` | | Git repository url | +| `forge_git_repository_destination` | str | `FORGE_GIT_REPOSITORY_DESTINATION` | $HOME/ublue-os/forge/bluefin | Git destination where repository is cloned to | +| `forge_git_repository_version` | str | `FORGE_GIT_REPOSITORY_VERSION` | main | Git repository branch or tag or commit version | + + + +## group_vars/all/registry.yml + +In the [registry.yml](../ansible/group_vars/all/registry.yml) all variables are defined +which are used in the context of the container registry. + + + +| name | type | environment variable | default value | description | +| -------------------- | ---- | -------------------- | -------------------- | ---------------------- | +| `forge_registry_url` | str | `FORGE_REGISTRY_URL` | registry.ublue.local | Container registry url | + + diff --git a/forge.just b/forge.just index 944520a..d300794 100644 --- a/forge.just +++ b/forge.just @@ -1,8 +1,13 @@ # ublue-os forge just configuration -# Show all messages from this boot -forge_clone-repository: - podman exec ublue-os_forge-anvil-ansible.ublue.local ansible-playbook playbooks/project_clone.yml +## default -forge_build-image: - podman exec ublue-os_forge-anvil-ansible.ublue.local ansible-playbook playbooks/project_build.yml \ No newline at end of file +default := "'${HOME}'/ublue-os_forge/forge_default_vars.env" + +## recipes + +forge_project-clone forge_config_var_file=default: + podman exec --env-file '{{forge_config_var_file}}' ublue-os_forge-anvil-ansible.ublue.local ansible-playbook playbooks/project_clone.yml + +forge_project-build forge_config_var_file=default: + podman exec --env-file '{{forge_config_var_file}}' ublue-os_forge-anvil-ansible.ublue.local ansible-playbook playbooks/project_build.yml