From 6e1a52886edcd523ff2c3400f4634f0fed1fb5bf Mon Sep 17 00:00:00 2001 From: shenlan Date: Sat, 29 Nov 2025 19:51:22 +0800 Subject: [PATCH] Add zot vhost role --- playbooks/roles/vhosts/zot/defaults/main.yml | 33 ++++++ playbooks/roles/vhosts/zot/tasks/main.yml | 102 ++++++++++++++++++ .../roles/vhosts/zot/templates/config.json.j2 | 45 ++++++++ .../roles/vhosts/zot/templates/zot.service.j2 | 17 +++ 4 files changed, 197 insertions(+) create mode 100644 playbooks/roles/vhosts/zot/defaults/main.yml create mode 100644 playbooks/roles/vhosts/zot/tasks/main.yml create mode 100644 playbooks/roles/vhosts/zot/templates/config.json.j2 create mode 100644 playbooks/roles/vhosts/zot/templates/zot.service.j2 diff --git a/playbooks/roles/vhosts/zot/defaults/main.yml b/playbooks/roles/vhosts/zot/defaults/main.yml new file mode 100644 index 0000000..e4ac31b --- /dev/null +++ b/playbooks/roles/vhosts/zot/defaults/main.yml @@ -0,0 +1,33 @@ +zot_version: v2.1.11 +zot_binary_url: "https://github.com/project-zot/zot/releases/download/{{ zot_version }}/zot-linux-amd64" +zot_binary_path: /usr/bin/zot +zot_user: zot +zot_group: zot +zot_data_dir: /data/zot +zot_log_dir: /var/log/zot +zot_config_dir: /etc/zot +zot_config_path: /etc/zot/config.json +zot_htpasswd_path: /etc/zot/htpasswd +zot_service_name: zot +zot_service_limits: + nofile: 500000 + memory_high: 30G + memory_max: 32G +zot_http_address: 0.0.0.0 +zot_http_port: 5000 +zot_tls_cert_path: "" +zot_tls_key_path: "" +zot_log_level: info +zot_sync_enabled: false +zot_sync_registries: + - urls: + - https://mirror.gcr.io/library + onDemand: true + maxRetries: 3 + retryDelay: 5m + pollInterval: 6h + - urls: + - https://docker.io/library + onDemand: true +zot_auth_users: [] +zot_verify_config: false diff --git a/playbooks/roles/vhosts/zot/tasks/main.yml b/playbooks/roles/vhosts/zot/tasks/main.yml new file mode 100644 index 0000000..1dab2dd --- /dev/null +++ b/playbooks/roles/vhosts/zot/tasks/main.yml @@ -0,0 +1,102 @@ +- name: Ensure zot group exists + ansible.builtin.group: + name: "{{ zot_group }}" + when: inventory_hostname in groups[group] + +- name: Ensure zot user exists + ansible.builtin.user: + name: "{{ zot_user }}" + group: "{{ zot_group }}" + create_home: false + shell: /usr/sbin/nologin + when: inventory_hostname in groups[group] + +- name: Ensure zot configuration directory exists + ansible.builtin.file: + path: "{{ zot_config_dir }}" + state: directory + owner: root + group: root + mode: '0755' + when: inventory_hostname in groups[group] + +- name: Ensure zot data directory exists + ansible.builtin.file: + path: "{{ zot_data_dir }}" + state: directory + owner: "{{ zot_user }}" + group: "{{ zot_group }}" + mode: '0755' + when: inventory_hostname in groups[group] + +- name: Ensure zot log directory exists + ansible.builtin.file: + path: "{{ zot_log_dir }}" + state: directory + owner: "{{ zot_user }}" + group: "{{ zot_group }}" + mode: '0755' + when: inventory_hostname in groups[group] + +- name: Download zot binary + ansible.builtin.get_url: + url: "{{ zot_binary_url }}" + dest: "{{ zot_binary_path }}" + mode: '0755' + when: inventory_hostname in groups[group] + +- name: Ensure htpasswd file exists + ansible.builtin.file: + path: "{{ zot_htpasswd_path }}" + state: touch + owner: "{{ zot_user }}" + group: "{{ zot_group }}" + mode: '0640' + when: (inventory_hostname in groups[group]) and (zot_auth_users | length > 0) + +- name: Configure local authentication users + community.general.htpasswd: + path: "{{ zot_htpasswd_path }}" + name: "{{ item.name }}" + password: "{{ item.password }}" + crypt_scheme: bcrypt + mode: '0640' + owner: "{{ zot_user }}" + group: "{{ zot_group }}" + loop: "{{ zot_auth_users }}" + when: (inventory_hostname in groups[group]) and (zot_auth_users | length > 0) + +- name: Install zot configuration + ansible.builtin.template: + src: config.json.j2 + dest: "{{ zot_config_path }}" + mode: '0644' + owner: root + group: root + when: inventory_hostname in groups[group] + +- name: Install zot systemd service + ansible.builtin.template: + src: zot.service.j2 + dest: "/etc/systemd/system/{{ zot_service_name }}.service" + mode: '0644' + owner: root + group: root + when: inventory_hostname in groups[group] + +- name: Verify zot configuration + ansible.builtin.command: + cmd: "{{ zot_binary_path }} verify {{ zot_config_path }}" + become: true + become_user: "{{ zot_user }}" + register: zot_verify_result + changed_when: false + when: (inventory_hostname in groups[group]) and zot_verify_config + +- name: Enable and start zot service + ansible.builtin.systemd: + name: "{{ zot_service_name }}" + enabled: true + state: restarted + daemon_reload: true + when: inventory_hostname in groups[group] diff --git a/playbooks/roles/vhosts/zot/templates/config.json.j2 b/playbooks/roles/vhosts/zot/templates/config.json.j2 new file mode 100644 index 0000000..77bdb46 --- /dev/null +++ b/playbooks/roles/vhosts/zot/templates/config.json.j2 @@ -0,0 +1,45 @@ +{ + "distSpecVersion": "1.1.0", + "storage": { + "rootDirectory": "{{ zot_data_dir }}" + }, + "http": { + "address": "{{ zot_http_address }}", + "port": "{{ zot_http_port }}"{% if zot_tls_cert_path and zot_tls_key_path %}, + "tls": { + "cert": "{{ zot_tls_cert_path }}", + "key": "{{ zot_tls_key_path }}" + }{% endif %}{% if zot_auth_users | length > 0 %}, + "auth": { + "htpasswd": { + "path": "{{ zot_htpasswd_path }}" + } + }, + "accessControl": { + "repositories": { + "**": { + "policies": [ + { + "users": ["*"], + "actions": ["read"] + }, + { + "users": ["{{ zot_user }}"], + "actions": ["*"] + } + ] + } + } + }{% endif %} + }, + "log": { + "level": "{{ zot_log_level }}", + "output": "{{ zot_log_dir }}/zot.log" + }, + "extensions": { + "sync": { + "enable": {{ zot_sync_enabled | string | lower }}, + "registries": {{ zot_sync_registries | to_json }} + } + } +} diff --git a/playbooks/roles/vhosts/zot/templates/zot.service.j2 b/playbooks/roles/vhosts/zot/templates/zot.service.j2 new file mode 100644 index 0000000..7b25ba0 --- /dev/null +++ b/playbooks/roles/vhosts/zot/templates/zot.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=OCI Distribution Registry (zot) +Documentation=https://zotregistry.dev/ +After=network.target auditd.service local-fs.target + +[Service] +Type=simple +User={{ zot_user }} +Group={{ zot_group }} +ExecStart={{ zot_binary_path }} serve {{ zot_config_path }} +Restart=on-failure +LimitNOFILE={{ zot_service_limits.nofile }} +MemoryHigh={{ zot_service_limits.memory_high }} +MemoryMax={{ zot_service_limits.memory_max }} + +[Install] +WantedBy=multi-user.target