diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index b3f12c0d..5297ee00 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -54,7 +54,7 @@ jobs: uses: actions/setup-python@v5 id: setup-python with: - python-version: "3.12" + python-version: "3.11" # minimum supported version - name: Cache homebrew packages if: ${{ github.event_name == 'pull_request' }} @@ -125,5 +125,5 @@ jobs: - name: Run repo clean and reset shell: bash run: | - task repo:clean - task repo:reset --yes + task repository:clean + task repository:reset --yes diff --git a/.taskfiles/Ansible/Taskfile.yaml b/.taskfiles/Ansible/Taskfile.yaml index a232416e..0e24c969 100644 --- a/.taskfiles/Ansible/Taskfile.yaml +++ b/.taskfiles/Ansible/Taskfile.yaml @@ -2,13 +2,6 @@ # yaml-language-server: $schema=https://taskfile.dev/schema.json version: "3" -vars: - PYTHON_BIN: python3 - ANSIBLE_LINT_FILE: "{{.ANSIBLE_DIR}}/.ansible-lint" - ANSIBLE_INVENTORY_FILE: "{{.ANSIBLE_DIR}}/inventory/hosts.yaml" - ANSIBLE_REQUIREMENTS_FILE: "{{.ROOT_DIR}}/requirements.yaml" - PIP_REQUIREMENTS_FILE: "{{.ROOT_DIR}}/requirements.txt" - env: PATH: "{{.ROOT_DIR}}/.venv/bin:$PATH" VIRTUAL_ENV: "{{.ROOT_DIR}}/.venv" @@ -18,12 +11,18 @@ env: ANSIBLE_LOCALHOST_WARNING: "False" ANSIBLE_INVENTORY_UNPARSED_WARNING: "False" +vars: + ANSIBLE_LINT_FILE: "{{.ANSIBLE_DIR}}/.ansible-lint" + ANSIBLE_INVENTORY_FILE: "{{.ANSIBLE_DIR}}/inventory/hosts.yaml" + ANSIBLE_REQUIREMENTS_FILE: "{{.ROOT_DIR}}/requirements.yaml" + PIP_REQUIREMENTS_FILE: "{{.ROOT_DIR}}/requirements.txt" + tasks: deps: desc: Set up Ansible dependencies for the environment cmds: - - task: .venv + - task: .setup-virtual-env vars: force: '{{.force | default "true"}}' @@ -36,52 +35,45 @@ tasks: deps: ["deps"] cmd: .venv/bin/ansible-playbook --inventory {{.ANSIBLE_INVENTORY_FILE}} {{.ANSIBLE_DIR}}/playbooks/{{.playbook}}.yaml {{.CLI_ARGS}} preconditions: - - sh: test -n {{.playbook}} - - sh: test -d {{.ROOT_DIR}}/.venv - - sh: test -f {{.ANSIBLE_INVENTORY_FILE}} - - sh: test -f {{.ANSIBLE_DIR}}/playbooks/{{.playbook}}.yaml + - { msg: "Missing playbook arg", sh: "test -n {{.playbook}}" } + - { msg: "Missing Ansible inventory file", sh: "test -f {{.ANSIBLE_INVENTORY_FILE}}" } poweroff: desc: Shutdown all the k8s nodes deps: ["deps"] cmd: .venv/bin/ansible kubernetes --inventory {{.ANSIBLE_INVENTORY_FILE}} -a '/usr/bin/systemctl poweroff' --become preconditions: - - sh: test -d {{.ROOT_DIR}}/.venv - - sh: test -f {{.ANSIBLE_INVENTORY_FILE}} + - { msg: "Missing Ansible inventory file", sh: "test -f {{.ANSIBLE_INVENTORY_FILE}}" } list: desc: List all the hosts deps: ["deps"] cmd: .venv/bin/ansible kubernetes --inventory {{.ANSIBLE_INVENTORY_FILE}} --list-hosts preconditions: - - sh: test -d {{.ROOT_DIR}}/.venv - - sh: test -f {{.ANSIBLE_INVENTORY_FILE}} + - { msg: "Missing Ansible inventory file", sh: "test -f {{.ANSIBLE_INVENTORY_FILE}}" } ping: desc: Ping all the hosts deps: ["deps"] cmd: .venv/bin/ansible kubernetes --inventory {{.ANSIBLE_INVENTORY_FILE}} --one-line -m 'ping' preconditions: - - sh: test -d {{.ROOT_DIR}}/.venv - - sh: test -f {{.ANSIBLE_INVENTORY_FILE}} + - { msg: "Missing Ansible inventory file", sh: "test -f {{.ANSIBLE_INVENTORY_FILE}}" } uptime: desc: Uptime of all the hosts deps: ["deps"] cmd: .venv/bin/ansible kubernetes --inventory {{.ANSIBLE_INVENTORY_FILE}} --one-line -a 'uptime' preconditions: - - sh: test -d {{.ROOT_DIR}}/.venv - - sh: test -f {{.ANSIBLE_INVENTORY_FILE}} + - { msg: "Missing Ansible inventory file", sh: "test -f {{.ANSIBLE_INVENTORY_FILE}}" } lint: desc: Lint Ansible deps: ["deps"] cmd: ./.venv/bin/ansible-lint --config-file {{.ANSIBLE_LINT_FILE}} {{.ANSIBLE_DIR}}/**/*.yaml preconditions: - - sh: test -d {{.ANSIBLE_DIR}} - - sh: test -f {{.ANSIBLE_LINT_FILE}} + - { msg: "Missing Ansible lint file", sh: "test -f {{.ANSIBLE_LINT_FILE}}" } - .venv: + .setup-virtual-env: internal: true cmds: - "{{.PYTHON_BIN}} -m venv {{.ROOT_DIR}}/.venv" @@ -94,6 +86,11 @@ tasks: generates: - "{{.ROOT_DIR}}/.venv/pyvenv.cfg" preconditions: - - sh: command -v {{.PYTHON_BIN}} + - { msg: "Missing Ansible requirements file", sh: "test -f {{.ANSIBLE_REQUIREMENTS_FILE}}" } + - { msg: "Missing Pip requirements file", sh: "test -f {{.PIP_REQUIREMENTS_FILE}}" } vars: force: '{{.force | default "true"}}' + + .reset: + internal: true + cmd: rm -rf {{.ANSIBLE_DIR}} diff --git a/.taskfiles/Flux/Taskfile.yaml b/.taskfiles/Flux/Taskfile.yaml index cfdde0b8..d2267970 100644 --- a/.taskfiles/Flux/Taskfile.yaml +++ b/.taskfiles/Flux/Taskfile.yaml @@ -5,33 +5,31 @@ version: "3" vars: # renovate: datasource=github-releases depName=prometheus-operator/prometheus-operator PROMETHEUS_OPERATOR_VERSION: "v0.70.0" + CLUSTER_SECRET_SOPS_FILE: "{{.KUBERNETES_DIR}}/flux/vars/cluster-secrets.sops.yaml" + CLUSTER_SECRET_USER_SOPS_FILE: "{{.KUBERNETES_DIR}}/flux/vars/cluster-secrets-user.sops.yaml" + CLUSTER_SETTINGS_FILE: "{{.KUBERNETES_DIR}}/flux/vars/cluster-settings.yaml" + CLUSTER_SETTINGS_USER_FILE: "{{.KUBERNETES_DIR}}/flux/vars/cluster-settings-user.yaml" tasks: bootstrap: desc: Bootstrap Flux into a Kubernetes cluster cmds: - # Install essential Prometheus Operator CRDs - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/{{.PROMETHEUS_OPERATOR_VERSION}}/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/{{.PROMETHEUS_OPERATOR_VERSION}}/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/{{.PROMETHEUS_OPERATOR_VERSION}}/example/prometheus-operator-crd/monitoring.coreos.com_scrapeconfigs.yaml - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/{{.PROMETHEUS_OPERATOR_VERSION}}/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml - # Install Flux - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --kustomize {{.KUBERNETES_DIR}}/bootstrap - # Install Secrets and Kustomizations - cat {{.SOPS_AGE_FILE}} | kubectl -n flux-system create secret generic sops-age --from-file=age.agekey=/dev/stdin - - sops --decrypt {{.KUBERNETES_DIR}}/flux/vars/cluster-secrets.sops.yaml | kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename - - - sops --decrypt {{.KUBERNETES_DIR}}/flux/vars/cluster-secrets-user.sops.yaml | kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename - - - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename {{.KUBERNETES_DIR}}/flux/vars/cluster-settings.yaml - - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename {{.KUBERNETES_DIR}}/flux/vars/cluster-settings-user.yaml + - sops --decrypt {{.CLUSTER_SECRET_SOPS_FILE}} | kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename - + - sops --decrypt {{.CLUSTER_SECRET_USER_SOPS_FILE}} | kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename - + - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename {{.CLUSTER_SETTINGS_FILE}} + - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename {{.CLUSTER_SETTINGS_USER_FILE}} - kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --kustomize {{.KUBERNETES_DIR}}/flux/config preconditions: - - sh: command -v flux - - sh: command -v kubectl - - sh: command -v sops - - sh: test -f {{.SOPS_AGE_FILE}} - - sh: test -f {{.KUBECONFIG_FILE}} - - sh: kubectl get namespace flux-system &>/dev/null && exit 1 || exit 0 + - { msg: "Flux already installed", sh: "kubectl get namespace flux-system &>/dev/null && exit 1 || exit 0" } + - { msg: "Missing kubeconfig", sh: "test -f {{.KUBECONFIG_FILE}}" } + - { msg: "Missing Sops Age key file", sh: "test -f {{.SOPS_AGE_FILE}}" } apply: desc: Apply a Flux Kustomization resource for a cluster @@ -48,28 +46,25 @@ tasks: | \ kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side \ --field-manager=kustomize-controller -f - - preconditions: - - sh: command -v flux - - sh: command -v kubectl - - sh: test -f {{.KUBECONFIG_FILE}} - - sh: test -f {{.KUBERNETES_DIR}}/apps/{{.path}}/ks.yaml vars: path: '{{ or .path (fail "Argument (path) is required") }}' ns: '{{.ns | default "flux-system"}}' ks: sh: flux --kubeconfig {{.KUBECONFIG_FILE}} --namespace {{.ns}} get kustomizations $(basename {{.path}}) 2>&1 + preconditions: + - { msg: "Flux already installed", sh: "kubectl get namespace flux-system &>/dev/null && exit 1 || exit 0" } + - { msg: "Missing Flux Kustomization", sh: "test -f {{.KUBERNETES_DIR}}/apps/{{.path}}/ks.yaml" } + - { msg: "Missing kubeconfig", sh: "test -f {{.KUBECONFIG_FILE}}" } reconcile: desc: Force update Flux to pull in changes from your Git repository cmd: flux --kubeconfig {{.KUBECONFIG_FILE}} reconcile --namespace flux-system kustomization cluster --with-source preconditions: - - sh: command -v flux - - sh: test -f {{.KUBECONFIG_FILE}} + - { msg: "Flux not installed", sh: "kubectl get namespace flux-system" } + - { msg: "Missing kubeconfig", sh: "test -f {{.KUBECONFIG_FILE}}" } github-deploy-key: cmd: sops --decrypt {{.KUBERNETES_DIR}}/bootstrap/github-deploy-key.sops.yaml | kubectl apply --kubeconfig {{.KUBECONFIG_FILE}} --server-side --filename - preconditions: - - sh: command -v kubectl - - sh: command -v sops - - sh: test -f {{.KUBECONFIG_FILE}} - - sh: kubectl get namespace flux-system &>/dev/null && exit 0 || exit 1 + - { msg: "Flux already installed", sh: "kubectl get namespace flux-system &>/dev/null && exit 1 || exit 0" } + - { msg: "Missing kubeconfig", sh: "test -f {{.KUBECONFIG_FILE}}" } diff --git a/.taskfiles/K0s/Taskfile.yaml b/.taskfiles/K0s/Taskfile.yaml index 7d247dac..94ec0923 100644 --- a/.taskfiles/K0s/Taskfile.yaml +++ b/.taskfiles/K0s/Taskfile.yaml @@ -5,6 +5,9 @@ env: DISABLE_TELEMETRY: "true" DISABLE_UPGRADE_CHECK: "true" +vars: + K0S_CONFIG_FILE: "{{.ROOT_DIR}}/k0s-config.yaml" + tasks: apply: @@ -13,11 +16,10 @@ tasks: - k0sctl apply --config {{.K0S_CONFIG_FILE}} - task: kubeconfig preconditions: - - sh: command -v k0sctl - - sh: test -f {{.K0S_CONFIG_FILE}} + - { msg: "Missing K0s config file", sh: "test -f {{.K0S_CONFIG_FILE}}" } - reset: - desc: Resets k0s cluster + nuke: + desc: Nuke the k0s cluster deps: [":ansible:deps"] cmds: - k0sctl reset --config {{.K0S_CONFIG_FILE}} @@ -25,16 +27,19 @@ tasks: vars: playbook: cluster-nuke preconditions: - - sh: command -v k0sctl - - sh: test -f {{.K0S_CONFIG_FILE}} + - { msg: "Missing K0s config file", sh: "test -f {{.K0S_CONFIG_FILE}}" } kubeconfig: desc: Gets k0s cluster kubeconfig - cmd: k0sctl kubeconfig --config {{.K0S_CONFIG_FILE}} > {{.KUBECONFIG_FILE}} + cmds: + - k0sctl kubeconfig --config {{.K0S_CONFIG_FILE}} > {{.KUBECONFIG_FILE}} sources: - "{{.K0S_CONFIG_FILE}}" generates: - "{{.KUBECONFIG_FILE}}" preconditions: - - sh: command -v k0sctl - - sh: test -f {{.K0S_CONFIG_FILE}} + - { msg: "Missing K0s config file", sh: "test -f {{.K0S_CONFIG_FILE}}" } + + .reset: + internal: true + cmd: rm -rf {{.K0S_CONFIG_FILE}} diff --git a/.taskfiles/Kubernetes/Taskfile.yaml b/.taskfiles/Kubernetes/Taskfile.yaml index c3453809..8e69a614 100644 --- a/.taskfiles/Kubernetes/Taskfile.yaml +++ b/.taskfiles/Kubernetes/Taskfile.yaml @@ -7,58 +7,13 @@ vars: tasks: - mount: - desc: Mount a PersistentVolumeClaim to a temporary pod for a cluster - summary: | - Args: - ns: Namespace the PVC is in (default: default) - claim: PVC to mount (required) - interactive: true - cmd: | - kubectl run -n {{.ns}} debug-{{.claim}} -i --tty --rm --image=null --privileged --overrides=' - { - "apiVersion": "v1", - "spec": { - "containers": [ - { - "name": "debug", - "image": "ghcr.io/onedr0p/alpine:rolling", - "command": ["/bin/bash"], - "stdin": true, - "stdinOnce": true, - "tty": true, - "volumeMounts": [ - { - "name": "config", - "mountPath": "/config" - } - ] - } - ], - "volumes": [ - { - "name": "config", - "persistentVolumeClaim": { - "claimName": "{{.claim}}" - } - } - ], - "restartPolicy": "Never" - } - }' - vars: - ns: '{{.ns | default "default"}}' - claim: '{{ or .claim (fail "Argument (claim) is required") }}' - preconditions: - - sh: kubectl -n {{.ns}} get persistentvolumeclaim {{.claim}} - resources: desc: Gather common resources in your cluster, useful when asking for support cmds: - - for: { var: RESOURCES } + - for: { var: resource } cmd: kubectl get {{.ITEM}} {{.CLI_ARGS | default "-A"}} vars: - RESOURCES: >- + resource: >- nodes gitrepositories kustomizations @@ -73,6 +28,8 @@ tasks: desc: Validate Kubernetes manifests with kubeconform cmd: bash {{.KUBECONFORM_SCRIPT}} {{.KUBERNETES_DIR}} preconditions: - - sh: command -v kubeconform - - sh: command -v kustomize - - sh: test -f {{.KUBECONFORM_SCRIPT}} + - { msg: "Missing kubeconform script", sh: "test -f {{.KUBECONFORM_SCRIPT}}" } + + .reset: + internal: true + cmd: rm -rf {{.KUBERNETES_DIR}} diff --git a/.taskfiles/Repo/Taskfile.yaml b/.taskfiles/Repository/Taskfile.yaml similarity index 73% rename from .taskfiles/Repo/Taskfile.yaml rename to .taskfiles/Repository/Taskfile.yaml index f5001a0c..dade642f 100644 --- a/.taskfiles/Repo/Taskfile.yaml +++ b/.taskfiles/Repository/Taskfile.yaml @@ -16,18 +16,18 @@ tasks: # Update renovate.json5 - sed -i {{if eq OS "darwin"}}''{{end}} 's/(..\.j2)\?(..\.j2)\?//g' {{.ROOT_DIR}}/.github/renovate.json5 preconditions: - - sh: test -d {{.BOOTSTRAP_DIR}} - - sh: test -d {{.PRIVATE_DIR}} - - sh: test -f {{.ROOT_DIR}}/.github/renovate.json5 + - { msg: "Missing bootstrap directory", sh: "test -d {{.BOOTSTRAP_DIR}}" } + - { msg: "Missing private directory", sh: "test -d {{.PRIVATE_DIR}}" } + - { msg: "Missing Renovate config file", sh: "test -f {{.ROOT_DIR}}/.github/renovate.json5" } reset: desc: Reset templated configuration files prompt: Reset templated configuration files... continue? cmds: - - rm -rf {{.SOPS_CONFIG_FILE}} - - rm -rf {{.ANSIBLE_DIR}} - - rm -rf {{.KUBERNETES_DIR}} - - rm -rf {{.K0S_CONFIG_FILE}} + - task: :ansible:.reset + - task: :k0s:.reset + - task: :kubernetes:.reset + - task: :sops:.reset force-reset: desc: Reset repo back to HEAD diff --git a/.taskfiles/Sops/Taskfile.yaml b/.taskfiles/Sops/Taskfile.yaml index 07b05242..ba5ae71c 100644 --- a/.taskfiles/Sops/Taskfile.yaml +++ b/.taskfiles/Sops/Taskfile.yaml @@ -2,6 +2,9 @@ # yaml-language-server: $schema=https://taskfile.dev/schema.json version: "3" +vars: + SOPS_CONFIG_FILE: "{{.ROOT_DIR}}/.sops.yaml" + tasks: age-keygen: @@ -11,24 +14,23 @@ tasks: - test -f "{{.SOPS_AGE_FILE}}" encrypt: - desc: Encrypt a secret - summary: | - Args: - file: Path to file to encrypt (required) - cmd: sops --encrypt --in-place {{.file}} - vars: - claim: '{{ or .file (fail "Argument (file) is required") }}' - preconditions: - - sh: test -f {{.SOPS_CONFIG_FILE}} - - sh: test -f {{.SOPS_AGE_FILE}} - - encrypt:all: desc: Encrypt all Kubernetes SOPS secrets cmds: - for: { var: file } - task: encrypt + task: .encrypt-file vars: file: "{{.ITEM}}" vars: file: sh: find {{.KUBERNETES_DIR}} -type f -name "*.sops.*" + + .encrypt-file: + internal: true + cmd: sops --encrypt --in-place {{.file}} + preconditions: + - { msg: "Missing Sops config file", sh: "test -f {{.SOPS_CONFIG_FILE}}" } + - { msg: "Missing Sops Age key file", sh: "test -f {{.SOPS_AGE_FILE}}" } + + .reset: + internal: true + cmd: rm -rf {{.SOPS_CONFIG_FILE}} diff --git a/.taskfiles/Workstation/Taskfile.yaml b/.taskfiles/Workstation/Taskfile.yaml index 3e035afa..5e2b7f3a 100644 --- a/.taskfiles/Workstation/Taskfile.yaml +++ b/.taskfiles/Workstation/Taskfile.yaml @@ -12,19 +12,19 @@ tasks: desc: Install workstation dependencies with Brew cmd: brew bundle --file {{.BREWFILE}} preconditions: - - sh: command -v brew - - sh: test -f {{.BREWFILE}} + - { msg: "Missing Homebrew", sh: "command -v brew" } + - { msg: "Missing Brewfile", sh: "test -f {{.BREWFILE}}" } paru: desc: Install workstation dependencies with Paru cmd: paru -Syu --needed --noconfirm --noprogressbar $(cat {{.ARCHFILE}} | xargs) preconditions: - - sh: command -v paru - - sh: test -f {{.ARCHFILE}} + - { msg: "Missing Paru", sh: "command -v paru" } + - { msg: "Missing Archfile", sh: "test -f {{.ARCHFILE}}" } yay: desc: Install workstation dependencies with Yay cmd: yay -Syu --needed --noconfirm --noprogressbar $(cat {{.ARCHFILE}} | xargs) preconditions: - - sh: command -v yay - - sh: test -f {{.ARCHFILE}} + - { msg: "Missing Yay", sh: "command -v yay" } + - { msg: "Missing Archfile", sh: "test -f {{.ARCHFILE}}" } diff --git a/Taskfile.yaml b/Taskfile.yaml index f9da7000..8491e2b1 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -11,11 +11,12 @@ vars: # Files BOOTSTRAP_ADDONS_FILE: "{{.BOOTSTRAP_DIR}}/vars/addons.yaml" BOOTSTRAP_CONFIG_FILE: "{{.BOOTSTRAP_DIR}}/vars/config.yaml" - K0S_CONFIG_FILE: "{{.ROOT_DIR}}/k0s-config.yaml" KUBECONFIG_FILE: "{{.ROOT_DIR}}/kubeconfig" MAKEJINJA_CONFIG_FILE: "{{.ROOT_DIR}}/makejinja.toml" + PYTHON_VERSION_CHECK_FILE: "{{.BOOTSTRAP_DIR}}/scripts/py_version_check.py" SOPS_AGE_FILE: "{{.ROOT_DIR}}/age.key" - SOPS_CONFIG_FILE: "{{.ROOT_DIR}}/.sops.yaml" + # Binaries + PYTHON_BIN: python3 includes: ansible: .taskfiles/Ansible/Taskfile.yaml @@ -24,7 +25,9 @@ includes: taskfile: .taskfiles/Kubernetes/Taskfile.yaml flux: .taskfiles/Flux/Taskfile.yaml k0s: .taskfiles/K0s/Taskfile.yaml - repo: .taskfiles/Repo/Taskfile.yaml + repository: + aliases: ["repo"] + taskfile: .taskfiles/Repository/Taskfile.yaml sops: .taskfiles/Sops/Taskfile.yaml workstation: .taskfiles/Workstation/Taskfile.yaml @@ -33,7 +36,7 @@ tasks: default: task -l init: - desc: Initialize template files and directories + desc: Initialize files and directories cmds: - mkdir -p {{.PRIVATE_DIR}} - cp -n {{.BOOTSTRAP_ADDONS_FILE | replace ".yaml" ".sample.yaml"}} {{.BOOTSTRAP_ADDONS_FILE}} @@ -57,6 +60,9 @@ tasks: - task: .pre-validate - task: .template - task: .post-validate + preconditions: + - { msg: "Missing Python version check script", sh: "test -f {{.PYTHON_VERSION_CHECK_FILE}}" } + - { msg: "Python version must be 3.11 or greater", sh: "{{.PYTHON_BIN}} {{.PYTHON_VERSION_CHECK_FILE}}" } .pre-validate: internal: true @@ -64,19 +70,18 @@ tasks: env: ANSIBLE_DISPLAY_SKIPPED_HOSTS: "false" preconditions: - - sh: test -f {{.BOOTSTRAP_ADDONS_FILE}} - - sh: test -f {{.BOOTSTRAP_CONFIG_FILE}} + - { msg: "Missing virtual environment", sh: "test -d {{.ROOT_DIR}}/.venv" } + - { msg: "Missing bootstrap addons file", sh: "test -f {{.BOOTSTRAP_ADDONS_FILE}}" } + - { msg: "Missing bootstrap config file", sh: "test -f {{.BOOTSTRAP_CONFIG_FILE}}" } .template: internal: true cmds: - ./.venv/bin/makejinja --keep-trailing-newline --force - - task: sops:encrypt:all + - task: sops:encrypt preconditions: - - sh: test -f {{.BOOTSTRAP_ADDONS_FILE}} - - sh: test -f {{.BOOTSTRAP_CONFIG_FILE}} - - sh: test -f {{.BOOTSTRAP_DIR}}/scripts/loader.py - - sh: test -f {{.MAKEJINJA_CONFIG_FILE}} + - { msg: "Missing Makejinja config file", sh: "test -f {{.MAKEJINJA_CONFIG_FILE}}" } + - { msg: "Missing Makejinja loader file", sh: "test -f {{.BOOTSTRAP_DIR}}/scripts/loader.py" } .post-validate: internal: true diff --git a/bootstrap/scripts/py_version_check.py b/bootstrap/scripts/py_version_check.py new file mode 100644 index 00000000..3abb2ba5 --- /dev/null +++ b/bootstrap/scripts/py_version_check.py @@ -0,0 +1,9 @@ +import sys + +required_version = (3, 11, 0) + +if sys.version_info >= required_version: + print(f"Python version is greater than or equal to 3.11") +else: + print("Python version is below 3.11. Please upgrade.") + exit(1)