diff --git a/.zuul.yaml b/.zuul.yaml index 1ff14d77ff..0e99c9f41a 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -110,10 +110,10 @@ - job: name: zuul-quick-start parent: opendev-buildset-registry-consumer - description: Run the commands in the Zuul quick-start documentation. - pre-run: playbooks/quick-start/pre.yaml - run: playbooks/quick-start/run.yaml - post-run: playbooks/quick-start/post.yaml + description: Run the commands in the Zuul tutorial quick-start documentation. + pre-run: playbooks/tutorial/pre.yaml + run: playbooks/tutorial/run.yaml + post-run: playbooks/tutorial/post.yaml required-projects: - zuul/zuul diff --git a/doc/source/examples/docker-compose.yaml b/doc/source/examples/docker-compose.yaml index f295ccd015..ec82d7bd4d 100644 --- a/doc/source/examples/docker-compose.yaml +++ b/doc/source/examples/docker-compose.yaml @@ -26,7 +26,7 @@ services: - "../../../tools/:/var/zuul-tools/:z" # NOTE(pabelanger): Be sure to update this line each time we change the # default version of ansible for Zuul. - command: "/usr/local/lib/zuul/ansible/2.8/bin/ansible-playbook /var/playbooks/setup.yaml" + command: "/usr/local/lib/zuul/ansible/2.9/bin/ansible-playbook /var/playbooks/setup.yaml" zk: image: zookeeper hostname: examples_zk_1.examples_default diff --git a/doc/source/examples/etc_nodepool/nodepool.yaml b/doc/source/examples/etc_nodepool/nodepool.yaml index e5d292b7c3..1c18306359 100644 --- a/doc/source/examples/etc_nodepool/nodepool.yaml +++ b/doc/source/examples/etc_nodepool/nodepool.yaml @@ -7,7 +7,7 @@ zookeeper-tls: ca: /var/certs/certs/cacert.pem labels: - - name: ubuntu-bionic + - name: ubuntu-focal providers: - name: static-vms @@ -16,7 +16,7 @@ providers: - name: main nodes: - name: node - labels: ubuntu-bionic - host-key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjDZ9C89nUVGQ1qZzG/X0onkmcju4kWJ2uTLBdIXsy1" + labels: ubuntu-focal + host-key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgHJYejINIKzUiuSJ2MN8uPc+dfFrZ9JH1hLWS8gI+g" python-path: /usr/bin/python3 username: root diff --git a/doc/source/examples/etc_zuul/zuul.conf b/doc/source/examples/etc_zuul/zuul.conf index 518fd57f3d..775aeadf38 100644 --- a/doc/source/examples/etc_zuul/zuul.conf +++ b/doc/source/examples/etc_zuul/zuul.conf @@ -35,6 +35,8 @@ dburi=mysql+pymysql://zuul:%(ZUUL_MYSQL_PASSWORD)s@mysql/zuul [web] listen_address=0.0.0.0 +port=9000 +root=http://localhost:9000 [executor] private_key_file=/var/ssh/nodepool diff --git a/doc/source/examples/node-Dockerfile b/doc/source/examples/node-Dockerfile index 25b5e03f61..90c2d750a6 100644 --- a/doc/source/examples/node-Dockerfile +++ b/doc/source/examples/node-Dockerfile @@ -1,23 +1,29 @@ -FROM rastasheep/ubuntu-sshd +FROM ubuntu:20.04 RUN apt-get update \ - && apt-get -y install \ + && DEBIAN_FRONTEND="noninteractive" apt-get -y install \ git \ - python-tox \ - python3 \ + openssh-server \ rsync \ - && apt-get clean \ - ; + && rm -rf /var/lib/apt/lists/* # If proxy environment variables supplied during build allow pass through via # ~/.ssh/environment, as the test env likely will require these set for any # job launched on the node to be capable of internet access. RUN set -e ; \ + mkdir /var/run/sshd ; \ + mkdir -p -m 0700 ~/.ssh; \ if [ -n "${http_proxy}" ]; then \ sed -ri 's/#PermitUserEnvironment no/PermitUserEnvironment yes/g' /etc/ssh/sshd_config; \ - mkdir -p ~/.ssh; \ echo "http_proxy=${http_proxy}" > ~/.ssh/environment; \ echo "https_proxy=${https_proxy}" >> ~/.ssh/environment; \ echo "no_proxy=${no_proxy}" >> ~/.ssh/environment; \ fi \ ; + +COPY --chown=root:root ./ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key +RUN chmod 0600 /etc/ssh/ssh_host_ed25519_key + +EXPOSE 22 + +ENTRYPOINT ["/usr/sbin/sshd", "-D" ] diff --git a/doc/source/examples/ssh_host_ed25519_key b/doc/source/examples/ssh_host_ed25519_key new file mode 100644 index 0000000000..68ce704731 --- /dev/null +++ b/doc/source/examples/ssh_host_ed25519_key @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDoByWHoyDSCs1IrkidjDfLj3PnXxa2fSR9YS1kvICPoAAAAJiZWqEimVqh +IgAAAAtzc2gtZWQyNTUxOQAAACDoByWHoyDSCs1IrkidjDfLj3PnXxa2fSR9YS1kvICPoA +AAAEA9aXkLh3eloH1HMQ2RR3DQ2bzIMROVxkvKKDmeYsDlLegHJYejINIKzUiuSJ2MN8uP +c+dfFrZ9JH1hLWS8gI+gAAAAEXJvb3RAMzI5NmRjMDg4ODQ2AQIDBA== +-----END OPENSSH PRIVATE KEY----- diff --git a/doc/source/examples/ssh_host_ed25519_key.pub b/doc/source/examples/ssh_host_ed25519_key.pub new file mode 100644 index 0000000000..a95c202d1a --- /dev/null +++ b/doc/source/examples/ssh_host_ed25519_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgHJYejINIKzUiuSJ2MN8uPc+dfFrZ9JH1hLWS8gI+g root@3296dc088846 diff --git a/doc/source/examples/zuul-config/zuul.d/jobs.yaml b/doc/source/examples/zuul-config/zuul.d/jobs.yaml index 6f0434727b..8ad979e461 100644 --- a/doc/source/examples/zuul-config/zuul.d/jobs.yaml +++ b/doc/source/examples/zuul-config/zuul.d/jobs.yaml @@ -3,5 +3,5 @@ parent: null nodeset: nodes: - - name: ubuntu-bionic - label: ubuntu-bionic + - name: ubuntu-focal + label: ubuntu-focal diff --git a/doc/source/examples/zuul-config/zuul.d/jobs2.yaml b/doc/source/examples/zuul-config/zuul.d/jobs2.yaml index 8b70ffecaf..a6ed1a633b 100644 --- a/doc/source/examples/zuul-config/zuul.d/jobs2.yaml +++ b/doc/source/examples/zuul-config/zuul.d/jobs2.yaml @@ -18,5 +18,5 @@ timeout: 1800 nodeset: nodes: - - name: ubuntu-bionic - label: ubuntu-bionic + - name: ubuntu-focal + label: ubuntu-focal diff --git a/doc/source/images/become-select.png b/doc/source/images/become-select.png index caf114ba5c..04afa38da5 100644 Binary files a/doc/source/images/become-select.png and b/doc/source/images/become-select.png differ diff --git a/doc/source/images/check1-1002.png b/doc/source/images/check1-1002.png index 081e420fbc..7230b55d69 100644 Binary files a/doc/source/images/check1-1002.png and b/doc/source/images/check1-1002.png differ diff --git a/doc/source/images/check2-1002.png b/doc/source/images/check2-1002.png index 73930467e5..9cb3a6d699 100644 Binary files a/doc/source/images/check2-1002.png and b/doc/source/images/check2-1002.png differ diff --git a/doc/source/images/orig/become-select.png b/doc/source/images/orig/become-select.png index de544e08f7..e7cad6bd06 100644 Binary files a/doc/source/images/orig/become-select.png and b/doc/source/images/orig/become-select.png differ diff --git a/doc/source/images/orig/check1-1002.png b/doc/source/images/orig/check1-1002.png index 02d2a954f3..37ad58d199 100644 Binary files a/doc/source/images/orig/check1-1002.png and b/doc/source/images/orig/check1-1002.png differ diff --git a/doc/source/images/orig/check2-1002.png b/doc/source/images/orig/check2-1002.png index f22313f907..6ec6827974 100644 Binary files a/doc/source/images/orig/check2-1002.png and b/doc/source/images/orig/check2-1002.png differ diff --git a/doc/source/tutorials/quick-start.rst b/doc/source/tutorials/quick-start.rst index e640ff261e..561f067cfe 100644 --- a/doc/source/tutorials/quick-start.rst +++ b/doc/source/tutorials/quick-start.rst @@ -71,7 +71,7 @@ docker-compose in order to start Zuul, Nodepool and Gerrit. .. code-block:: shell cd zuul/doc/source/examples - sudo -E docker-compose up + sudo -E docker-compose -p zuul-tutorial up For reference, the files in that directory are also `browsable on the web `_. diff --git a/playbooks/quick-start/localtest.yaml b/playbooks/quick-start/localtest.yaml deleted file mode 100644 index ce0ef4362c..0000000000 --- a/playbooks/quick-start/localtest.yaml +++ /dev/null @@ -1,10 +0,0 @@ -- hosts: localhost - vars: - workspace: /tmp/quickstart-test - local: true - ssh_public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - ssh_agent: - stdout: '' - tasks: - - name: Run tasks in ssh agent - include_tasks: main.yaml diff --git a/playbooks/quick-start/post.yaml b/playbooks/quick-start/post.yaml deleted file mode 100644 index 0b007cc535..0000000000 --- a/playbooks/quick-start/post.yaml +++ /dev/null @@ -1,26 +0,0 @@ -- hosts: all - tasks: - - name: Create logs directory - file: - state: directory - path: "{{ ansible_user_dir }}/logs" - mode: 0755 - - name: Save docker log files - become: true - shell: | - docker logs examples_gerrit_1 > {{ ansible_user_dir }}/logs/gerrit.log 2>&1 - docker logs examples_gerritconfig_1 > {{ ansible_user_dir }}/logs/gerritconfig.log 2>&1 - docker logs examples_zk_1 > {{ ansible_user_dir }}/logs/zk.log 2>&1 - docker logs examples_mysql_1 > {{ ansible_user_dir }}/logs/mysql.log 2>&1 - docker logs examples_scheduler_1 > {{ ansible_user_dir }}/logs/scheduler.log 2>&1 - docker logs examples_web_1 > {{ ansible_user_dir }}/logs/web.log 2>&1 - docker logs examples_executor_1 > {{ ansible_user_dir }}/logs/executor.log 2>&1 - docker logs examples_node_1 > {{ ansible_user_dir }}/logs/node.log 2>&1 - docker logs examples_launcher_1 > {{ ansible_user_dir }}/logs/launcher.log 2>&1 - docker logs examples_logs_1 > {{ ansible_user_dir }}/logs/logs.log 2>&1 - - name: Copy docker log files to executor - synchronize: - mode: pull - src: "{{ ansible_user_dir }}/logs/" - dest: "{{ zuul.executor.log_root }}/container_logs/" - verify_host: true diff --git a/playbooks/quick-start/run.yaml b/playbooks/quick-start/run.yaml deleted file mode 100644 index 29dc9a8b83..0000000000 --- a/playbooks/quick-start/run.yaml +++ /dev/null @@ -1,41 +0,0 @@ -- hosts: all - vars: - workspace: /tmp/quickstart-test - local: false - tasks: - - name: Install git-review - command: python3 -m pip install git-review - become: true - - name: Create workspace directory - file: - state: directory - path: "{{ workspace }}" - - name: Generate example user ssh key - command: "ssh-keygen -f {{ workspace }}/id_rsa -N ''" - args: - creates: "{{ workspace }}/id_rsa.pub" - - name: Load example user SSH key - shell: "cat {{ workspace }}/id_rsa.pub" - register: ssh_key_cat - - name: Register example user SSH key - set_fact: - ssh_public_key: "{{ ssh_key_cat.stdout }}" - - name: Start ssh-agent - command: ssh-agent - register: ssh_agent - - name: Add key to ssh agent - shell: - executable: /bin/bash - cmd: | - {{ ssh_agent.stdout }} - ssh-add {{ workspace }}/id_rsa - - block: - - name: Run tasks in ssh agent - include_tasks: main.yaml - always: - - name: Stop ssh-agent - shell: - executable: /bin/bash - cmd: | - {{ ssh_agent.stdout }} - ssh-agent -k diff --git a/playbooks/tutorial/post.yaml b/playbooks/tutorial/post.yaml new file mode 100644 index 0000000000..df4d51f716 --- /dev/null +++ b/playbooks/tutorial/post.yaml @@ -0,0 +1,26 @@ +- hosts: all + tasks: + - name: Create logs directory + file: + state: directory + path: "{{ ansible_user_dir }}/logs" + mode: 0755 + - name: Save docker log files + become: true + shell: | + docker logs zuultutorial_gerrit_1 > {{ ansible_user_dir }}/logs/gerrit.log 2>&1 + docker logs zuultutorial_gerritconfig_1 > {{ ansible_user_dir }}/logs/gerritconfig.log 2>&1 + docker logs zuultutorial_zk_1 > {{ ansible_user_dir }}/logs/zk.log 2>&1 + docker logs zuultutorial_mysql_1 > {{ ansible_user_dir }}/logs/mysql.log 2>&1 + docker logs zuultutorial_scheduler_1 > {{ ansible_user_dir }}/logs/scheduler.log 2>&1 + docker logs zuultutorial_web_1 > {{ ansible_user_dir }}/logs/web.log 2>&1 + docker logs zuultutorial_executor_1 > {{ ansible_user_dir }}/logs/executor.log 2>&1 + docker logs zuultutorial_node_1 > {{ ansible_user_dir }}/logs/node.log 2>&1 + docker logs zuultutorial_launcher_1 > {{ ansible_user_dir }}/logs/launcher.log 2>&1 + docker logs zuultutorial_logs_1 > {{ ansible_user_dir }}/logs/logs.log 2>&1 + - name: Copy docker log files to executor + synchronize: + mode: pull + src: "{{ ansible_user_dir }}/logs/" + dest: "{{ zuul.executor.log_root }}/container_logs/" + verify_host: true diff --git a/playbooks/quick-start/pre.yaml b/playbooks/tutorial/pre.yaml similarity index 100% rename from playbooks/quick-start/pre.yaml rename to playbooks/tutorial/pre.yaml diff --git a/playbooks/tutorial/quick-start.yaml b/playbooks/tutorial/quick-start.yaml new file mode 100644 index 0000000000..f2f4d95c8a --- /dev/null +++ b/playbooks/tutorial/quick-start.yaml @@ -0,0 +1,97 @@ +- name: Init Test1 + include_role: + name: init-repository + vars: + projectname: test1 + +- name: Copy data to test1 + copy: + src: ../../doc/source/examples/test1/ + dest: "{{ workspace }}/test1/" + +- name: Commit and upload test change in test1 + shell: + chdir: "{{ workspace }}/test1/" + executable: /bin/bash + cmd: | + {{ ssh_agent.stdout }} + mv zuul.yaml .zuul.yaml + git add .zuul.yaml playbooks + git commit -m "Add test Zuul job" + git review + +- import_role: + name: check-pipeline + vars: + title: "test job test1" + projectname: test1 + +- name: Save test1 change info + set_fact: + changetest1: "{{ changeinfo }}" + json_query_finger: "messages[?contains(@.message, 'testjob finger://')].message | [0]" + +- name: "Fetch url finger://" + assert: + that: + - (result_json | to_json | from_json | json_query(json_query_finger) | regex_search('(finger://[^ ]*)') | length > 0) + +- name: Configure a Base Job zuul-config + copy: + src: ../../doc/source/examples/zuul-config/playbooks/base/ + dest: "{{ workspace }}/zuul-config/playbooks/base/" + +- name: Update the base job definition + copy: + src: ../../doc/source/examples/zuul-config/zuul.d/jobs2.yaml + dest: "{{ workspace }}/zuul-config/zuul.d/jobs.yaml" + +- name: Commit and upload zuul-config + shell: + chdir: "{{ workspace }}/zuul-config/" + executable: /bin/bash + warn: false + cmd: | + {{ ssh_agent.stdout }} + git add playbooks zuul.d/jobs.yaml + git commit -m "Update Zuul base job" + git review + +- include_role: + name: change-merged + vars: + title: "Update Zuul base job" + projectname: zuul-config + +# Remove the label so Zuul will post again Verified+1 which is what +# check-pipeline is looking for +- include_role: + name: remove-verified + vars: + change_id: "{{ changetest1.id }}" + +- include_role: + name: recheck-change + vars: + change_id: "{{ changetest1.id }}" + +- include_role: + name: check-pipeline + vars: + title: "test job test1" + projectname: test1 + check_number: 2 + +- name: Find the log URL with regex + set_fact: + log_url: "{{ result_json | to_json | from_json | json_query(json_query_log_url) | regex_search('(http://[^ ]*)') }}" + vars: + json_query_log_url: "messages[?contains(@.message, 'http://')].message | [0]" + +- name: Fetch log URL + get_url: + url: "{{ log_url }}job-output.txt" + dest: "{{ workspace }}/job-output.txt" + +- name: Verify log contents + command: "grep 'Hello world!' {{ workspace }}/job-output.txt" diff --git a/playbooks/tutorial/roles/approve-change/defaults/main.yaml b/playbooks/tutorial/roles/approve-change/defaults/main.yaml new file mode 100644 index 0000000000..c9d344a366 --- /dev/null +++ b/playbooks/tutorial/roles/approve-change/defaults/main.yaml @@ -0,0 +1,2 @@ +change_id: "{{ changeinfo.id }}" +change_revision: "{{changeinfo.current_revision}}" diff --git a/playbooks/tutorial/roles/approve-change/tasks/main.yaml b/playbooks/tutorial/roles/approve-change/tasks/main.yaml new file mode 100644 index 0000000000..542feb21b6 --- /dev/null +++ b/playbooks/tutorial/roles/approve-change/tasks/main.yaml @@ -0,0 +1,13 @@ +- name: "Approve changes: {{ projectname }}" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/revisions/{{ change_revision }}/review" + method: POST + user: admin + password: secret + status_code: 200 + body_format: json + body: + labels: + Code-Review: "+2" + Workflow: "+1" + diff --git a/playbooks/tutorial/roles/change-merged/meta/main.yaml b/playbooks/tutorial/roles/change-merged/meta/main.yaml new file mode 100644 index 0000000000..b46f4c6d29 --- /dev/null +++ b/playbooks/tutorial/roles/change-merged/meta/main.yaml @@ -0,0 +1,4 @@ +dependencies: + - role: check-pipeline + - role: approve-change + - role: gate-pipeline diff --git a/playbooks/tutorial/roles/check-pipeline/defaults/main.yaml b/playbooks/tutorial/roles/check-pipeline/defaults/main.yaml new file mode 100644 index 0000000000..4206f6c924 --- /dev/null +++ b/playbooks/tutorial/roles/check-pipeline/defaults/main.yaml @@ -0,0 +1,4 @@ +patchset: 1 +pipeline_expected_result: ok +check_timeout: 180 +check_number: 1 diff --git a/playbooks/tutorial/roles/check-pipeline/tasks/main.yaml b/playbooks/tutorial/roles/check-pipeline/tasks/main.yaml new file mode 100644 index 0000000000..7baec67bc3 --- /dev/null +++ b/playbooks/tutorial/roles/check-pipeline/tasks/main.yaml @@ -0,0 +1,28 @@ +- name: "Check pipeline: query open changes: {{ title }}" + uri: + url: "http://localhost:8080/a/changes/?q=project:{{ projectname }}&o=CURRENT_REVISION&n=1" + method: GET + user: admin + password: secret + return_content: true + register: changes + +- name: "Check pipeline: set variable: {{ title }}" + set_fact: + changeinfo: "{{ {'id': (changes.content[5:]|from_json)[0].id, 'change_id': (changes.content[5:]|from_json)[0].change_id, 'number': (changes.content[5:]|from_json)[0]._number, 'current_revision': (changes.content[5:]|from_json)[0].current_revision} }}" + +- name: "Check pipeline: Wait for Zuul to report check status: {{ title }}" + uri: + url: "http://localhost:8080/a/changes/{{ changeinfo.id }}/detail" + method: GET + user: admin + password: secret + return_content: true + register: result + until: result.status == 200 and (result.content[5:] | from_json | to_json | from_json | json_query(json_query_check) | length == check_number|int) + delay: 1 + retries: "{{ check_timeout }}" + +- name: "Check pipeline: set variable: {{ title }}" + set_fact: + result_json: "{{ result.content[5:] }}" diff --git a/playbooks/tutorial/roles/check-pipeline/vars/main.yaml b/playbooks/tutorial/roles/check-pipeline/vars/main.yaml new file mode 100644 index 0000000000..53efe6918d --- /dev/null +++ b/playbooks/tutorial/roles/check-pipeline/vars/main.yaml @@ -0,0 +1,3 @@ +json_query_check_ko: "messages[?contains(@.message, 'Patch Set {{ patchset }}: Verified-1')]" +json_query_check_ok: "messages[?contains(@.message, 'Patch Set {{ patchset }}: Verified+1')]" +json_query_check: "{{ json_query_check_ok if pipeline_expected_result == 'ok' else json_query_check_ko }}" diff --git a/playbooks/tutorial/roles/gate-pipeline/defaults/main.yaml b/playbooks/tutorial/roles/gate-pipeline/defaults/main.yaml new file mode 100644 index 0000000000..c52ac9729e --- /dev/null +++ b/playbooks/tutorial/roles/gate-pipeline/defaults/main.yaml @@ -0,0 +1,3 @@ +gate_timeout: 180 +pipeline_expected_result: ok +change_id: "{{ changeinfo.id }}" diff --git a/playbooks/tutorial/roles/gate-pipeline/tasks/main.yaml b/playbooks/tutorial/roles/gate-pipeline/tasks/main.yaml new file mode 100644 index 0000000000..eb9ac548a4 --- /dev/null +++ b/playbooks/tutorial/roles/gate-pipeline/tasks/main.yaml @@ -0,0 +1,46 @@ +- name: "Gate pipeline: Wait for Zuul to report gate job has started: {{ title }}" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/detail" + method: GET + user: admin + password: secret + return_content: true + register: result + until: result.status == 200 and (result.content[5:] | from_json | to_json | from_json | json_query(json_query_change_gate_started) | length == 1) + delay: 1 + retries: 30 + +- name: "Gate pipeline: Wait for Zuul to report gate job has finished: {{ title }}" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/detail" + method: GET + user: admin + password: secret + return_content: true + register: result + until: result.status == 200 and (result.content[5:] | from_json | to_json | from_json | json_query(json_query_change_gate) | length == 1) + delay: 1 + retries: "{{ gate_timeout }}" + +- name: "Gate pipeline: set variable: {{ title }}" + when: pipeline_expected_result != "ok" + set_fact: + result_json: "{{ result.content[5:] }}" + +- block: + - name: "Gate pipeline: change is merged: {{ title }}" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/detail" + method: GET + user: admin + password: secret + return_content: true + register: result + until: result.status == 200 and (result.content[5:] | from_json | to_json | from_json | json_query(json_query_change_merged_ok) | length == 1) + delay: 1 + retries: 30 + + - name: "Gate pipeline: set variable: {{ title }}" + set_fact: + result_json: "{{ result.content[5:] }}" + when: pipeline_expected_result == "ok" diff --git a/playbooks/tutorial/roles/gate-pipeline/vars/main.yaml b/playbooks/tutorial/roles/gate-pipeline/vars/main.yaml new file mode 100644 index 0000000000..cc517994a9 --- /dev/null +++ b/playbooks/tutorial/roles/gate-pipeline/vars/main.yaml @@ -0,0 +1,5 @@ +json_query_change_gate_started: "messages[?contains(@.message, 'Starting gate jobs')]" +json_query_change_gate_ko: "messages[?contains(@.message, 'Patch Set 1: Verified-2')]" +json_query_change_gate_ok: "messages[?contains(@.message, 'Patch Set 1: Verified+2')]" +json_query_change_merged_ok: "messages[?contains(@.message, 'Change has been successfully merged')]" +json_query_change_gate: "{{ json_query_change_gate_ok if pipeline_expected_result == 'ok' else json_query_change_gate_ko }}" diff --git a/playbooks/tutorial/roles/init-repository/tasks/main.yaml b/playbooks/tutorial/roles/init-repository/tasks/main.yaml new file mode 100644 index 0000000000..66f72a220f --- /dev/null +++ b/playbooks/tutorial/roles/init-repository/tasks/main.yaml @@ -0,0 +1,23 @@ +- name: "Clone {{ projectname }}" + git: + repo: "http://localhost:8080/{{ projectname }}" + dest: "{{ workspace }}/{{ projectname }}" + +# git-review doesn't support supplying a known_hosts file to scp, so we +# fetch the commit hook ahead of time to avoid that. +- name: Download commit-msg + get_url: + url: http://localhost:8080/tools/hooks/commit-msg + dest: "{{ workspace }}/{{ projectname }}/.git/hooks/commit-msg" + mode: a+x + +- name: "Setup repository {{ projectname }}" + shell: + chdir: "{{ workspace }}/{{ projectname }}/" + executable: /bin/bash + cmd: | + {{ ssh_agent.stdout }} + git config user.email 'user@example.com' + git config user.name 'Example User' + git config gitreview.username 'user' + git review -s diff --git a/playbooks/tutorial/roles/recheck-change/tasks/main.yaml b/playbooks/tutorial/roles/recheck-change/tasks/main.yaml new file mode 100644 index 0000000000..63e8c4ece3 --- /dev/null +++ b/playbooks/tutorial/roles/recheck-change/tasks/main.yaml @@ -0,0 +1,10 @@ +- name: "Set recheck" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/revisions/current/review" + method: POST + user: user + password: secret + status_code: 200 + body_format: json + body: + message: "recheck" diff --git a/playbooks/tutorial/roles/remove-verified/tasks/main.yaml b/playbooks/tutorial/roles/remove-verified/tasks/main.yaml new file mode 100644 index 0000000000..9b2464031d --- /dev/null +++ b/playbooks/tutorial/roles/remove-verified/tasks/main.yaml @@ -0,0 +1,7 @@ +- name: "Delete Verified" + uri: + url: "http://localhost:8080/a/changes/{{ change_id }}/reviewers/zuul/votes/Verified" + method: DELETE + user: user + password: secret + status_code: 204 diff --git a/playbooks/quick-start/main.yaml b/playbooks/tutorial/roles/setup-tutorial/tasks/main.yaml similarity index 51% rename from playbooks/quick-start/main.yaml rename to playbooks/tutorial/roles/setup-tutorial/tasks/main.yaml index 57e1ad3a78..c8792d6bea 100644 --- a/playbooks/quick-start/main.yaml +++ b/playbooks/tutorial/roles/setup-tutorial/tasks/main.yaml @@ -1,19 +1,55 @@ +- name: Create workspace directory + file: + state: directory + path: "{{ workspace }}" + +- block: + - name: Generate example user ssh key + command: "ssh-keygen -f {{ workspace }}/id_rsa -N ''" + args: + creates: "{{ workspace }}/id_rsa.pub" + - name: Load example user SSH key + shell: "cat {{ workspace }}/id_rsa.pub" + register: ssh_key_cat + - name: Register example user SSH key (temp) + set_fact: + ssh_public_key_new: "{{ ssh_key_cat.stdout }}" + stop_ssh_agent: yes + - name: Start ssh-agent + command: ssh-agent + register: ssh_agent_new + - name: Add key to ssh agent + shell: + executable: /bin/bash + cmd: | + {{ ssh_agent_new.stdout }} + ssh-add {{ workspace }}/id_rsa + - name: "Set Fact: ssh_public_key/ssh_agent" + set_fact: + ssh_public_key: "{{ ssh_public_key_new }}" + ssh_agent: "{{ ssh_agent_new }}" + when: ssh_public_key is not defined or ssh_public_key == '' + - name: Run docker-compose up when: not local shell: - cmd: docker-compose up -d + cmd: docker-compose -p zuul-tutorial up -d chdir: src/opendev.org/zuul/zuul/doc/source/examples + - name: Run docker-compose up when: local shell: - cmd: docker-compose up -d + cmd: docker-compose -p zuul-tutorial up -d chdir: ../../doc/source/examples + - name: Print list of images command: docker image ls --all --digests --no-trunc + - name: Wait for Gerrit to start wait_for: host: localhost port: 29418 + - name: Wait for Zuul user to be created uri: url: http://localhost:8080/a/accounts/zuul/sshkeys @@ -21,17 +57,19 @@ user: admin password: secret register: result - until: result.status == 200 and result.redirected == false + until: result.status == 200 and not result.redirected delay: 1 retries: 120 + - name: fetch ssh host keys from gerrit - when: not local - shell: ssh-keyscan -p 29418 localhost >> ~/.ssh/known_hosts + shell: ssh-keyscan -p 29418 localhost > {{ workspace }}/known_hosts + - name: Check if example user exists in Gerrit uri: url: http://localhost:8080/accounts/user status_code: 200, 404 register: user_check + - name: Create example gerrit account when: user_check.status==404 uri: @@ -42,9 +80,12 @@ status_code: 201 body_format: json body: + username: user name: Example User + email: user@example.com ssh_key: "{{ ssh_public_key }}" http_password: secret + - name: Wait for zuul uri: url: http://localhost:9000/api/tenant/example-tenant/status @@ -57,14 +98,29 @@ delay: 10 until: result.status == 200 and result.json["zuul_version"] is defined changed_when: false -- name: Clone zuul-config - git: - repo: http://localhost:8080/zuul-config - dest: "{{ workspace }}/zuul-config" + +# Quick-Start tutorial begin +- name: Init zuul-config + include_role: + name: init-repository + vars: + projectname: zuul-config + - name: Make initial change in zuul-config copy: - src: ../../doc/source/examples/zuul-config/ - dest: "{{ workspace }}/zuul-config/" + src: ../../doc/source/examples/zuul-config/zuul.d/pipelines.yaml + dest: "{{ workspace }}/zuul-config/zuul.d/" + +- name: Make initial change in zuul-config + copy: + src: ../../doc/source/examples/zuul-config/zuul.d/projects.yaml + dest: "{{ workspace }}/zuul-config/zuul.d/" + +- name: Copy basic base job definition + copy: + src: ../../doc/source/examples/zuul-config/zuul.d/jobs.yaml + dest: "{{ workspace }}/zuul-config/zuul.d/jobs.yaml" + - name: Commit and upload initial change in zuul-config shell: chdir: "{{ workspace }}/zuul-config/" @@ -72,13 +128,10 @@ warn: false cmd: | {{ ssh_agent.stdout }} - rm zuul.d/jobs.yaml - git config user.email 'user@example.com' - git config user.name 'Example User' - git config gitreview.username 'user' - git add zuul.d playbooks + git add zuul.d git commit -m "Add initial Zuul configuration" git review -v + - name: Query open changes uri: url: http://localhost:8080/a/changes/?q=status:open+project:zuul-config&o=CURRENT_REVISION @@ -87,9 +140,13 @@ password: secret return_content: true register: changes + +- set_fact: + changeinfo: "{{ {'id': (changes.content[5:]|from_json)[0].id, 'current_revision': (changes.content[5:]|from_json)[0].current_revision} }}" + - name: Approve zuul-config change uri: - url: "http://localhost:8080/a/changes/{{ (changes.content[5:]|from_json)[0].id }}/revisions/{{ (changes.content[5:]|from_json)[0].current_revision }}/review" + url: "http://localhost:8080/a/changes/{{ changeinfo.id }}/revisions/{{ changeinfo.current_revision }}/review" method: POST user: admin password: secret @@ -97,80 +154,34 @@ body_format: json body: labels: - Code-Review: +2 - Verified: +2 - Workflow: +1 + Code-Review: "+2" + Verified: "+2" + Workflow: "+1" + - name: Merge zuul-config change uri: - url: "http://localhost:8080/a/changes/{{ (changes.content[5:]|from_json)[0].id }}/revisions/{{ (changes.content[5:]|from_json)[0].current_revision }}/submit" + url: "http://localhost:8080/a/changes/{{ changeinfo.id }}/revisions/{{ changeinfo.current_revision }}/submit" method: POST user: admin password: secret status_code: 200 + - name: Fetch status page uri: url: http://localhost:9000/t/example-tenant/status return_content: true register: status_page + - name: Verify status page was served assert: that: "'You need to enable JavaScript to run this app.' in status_page.content" + - name: Fetch status data uri: url: http://localhost:9000/api/tenant/example-tenant/status return_content: true register: status_data + - name: Verify status data were served assert: that: "status_data.json.last_reconfigured > 0" -- name: Clone test1 - git: - repo: http://localhost:8080/test1 - dest: "{{ workspace }}/test1" -- name: Make test change in test1 - copy: - src: ../../doc/source/examples/test1/ - dest: "{{ workspace }}/test1/" -- name: Commit and upload test change in test1 - shell: - chdir: "{{ workspace }}/test1/" - executable: /bin/bash - cmd: | - {{ ssh_agent.stdout }} - git config user.email 'user@example.com' - git config user.name 'Example User' - git config gitreview.username 'user' - mv zuul.yaml .zuul.yaml - git add .zuul.yaml playbooks - git commit -m "Add test Zuul job" - git review -- name: Query open changes - uri: - url: http://localhost:8080/a/changes/?q=status:open+project:test1&o=CURRENT_REVISION - method: GET - user: admin - password: secret - return_content: true - register: changes -- name: Wait for Zuul to report - uri: - url: "http://localhost:8080/a/changes/{{ (changes.content[5:]|from_json)[0].id }}//detail" - method: GET - user: admin - password: secret - return_content: true - register: result - until: (result.content[5:]|from_json).messages|length > 1 - delay: 1 - retries: 120 -- name: Find the log URL - set_fact: - log_url: "{{ (result.content[5:]|from_json).messages[1].message|regex_search('(http://[^ ]*)') }}" -- debug: - msg: "{{ log_url }}" -- name: Fetch log URL - get_url: - url: "{{ log_url }}job-output.txt" - dest: "{{ workspace }}/job-output.txt" -- name: Verify log contents - command: "grep 'Hello world!' {{ workspace }}/job-output.txt" diff --git a/playbooks/tutorial/run-localtest-quick-start.yaml b/playbooks/tutorial/run-localtest-quick-start.yaml new file mode 100644 index 0000000000..525d465971 --- /dev/null +++ b/playbooks/tutorial/run-localtest-quick-start.yaml @@ -0,0 +1,34 @@ +- hosts: localhost + vars: + workspace: /tmp/tutorial-zuul + local: true + ssh_public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub', errors='ignore') }}" + ssh_agent: + stdout: '' + environment: + GIT_SSH_COMMAND: "ssh -o UserKnownHostsFile={{ workspace }}/known_hosts" + tasks: + - block: + - name: Run tutorial + include_tasks: run-tutorial.yaml + always: + - name: Stop ssh-agent + when: stop_ssh_agent is defined + shell: + executable: /bin/bash + cmd: | + {{ ssh_agent.stdout }} + ssh-agent -k + - name: Print SSH command + debug: + msg: + - Use GIT_SSH_COMMAND='ssh -o UserKnownHostsFile={{ workspace }}/known_hosts' + - to make further test using /tmp/tutorial-zuul/test1 + + when: stop_ssh_agent is not defined + - name: Print SSH command using temp id_rsa + debug: + msg: + - Use GIT_SSH_COMMAND='ssh -o UserKnownHostsFile={{ workspace }}/known_hosts -i {{ workspace }}/id_rsa' + - to make further test using /tmp/tutorial-zuul/test1 + when: stop_ssh_agent is defined diff --git a/playbooks/tutorial/run-tutorial.yaml b/playbooks/tutorial/run-tutorial.yaml new file mode 100644 index 0000000000..0c85606c2e --- /dev/null +++ b/playbooks/tutorial/run-tutorial.yaml @@ -0,0 +1,12 @@ +- block: + - name: Install git-review + command: python3 -m pip install git-review + become: true + when: not local + +- name: Setup Tutorial Execution + include_role: + name: setup-tutorial + +- name: Run quick-start tutorial + include_tasks: quick-start.yaml diff --git a/playbooks/tutorial/run.yaml b/playbooks/tutorial/run.yaml new file mode 100644 index 0000000000..666987ac29 --- /dev/null +++ b/playbooks/tutorial/run.yaml @@ -0,0 +1,17 @@ +- hosts: all + vars: + workspace: /tmp/tutorial-zuul + local: false + environment: + GIT_SSH_COMMAND: "ssh -o UserKnownHostsFile={{ workspace }}/known_hosts" + tasks: + - block: + - name: Run tutorial + include_tasks: run-tutorial.yaml + always: + - name: Stop ssh-agent + shell: + executable: /bin/bash + cmd: | + {{ ssh_agent.stdout }} + ssh-agent -k