From e8f9b253123d42a7e4e603762831a5faaaa88973 Mon Sep 17 00:00:00 2001 From: Merlin Mathesius Date: Jul 05 2017 21:42:31 +0000 Subject: [PATCH 1/2] - Implement configuration of SSH key-based authentication to docker image - Revised docker and rhts role usage conventions to be compatible and interchangeable with cloud and beakerlib roles --- diff --git a/roles/standard-test-docker/files/docker-inventory b/roles/standard-test-docker/files/docker-inventory index 3a5fcf6..b23a7d0 100644 --- a/roles/standard-test-docker/files/docker-inventory +++ b/roles/standard-test-docker/files/docker-inventory @@ -1 +1,2 @@ localhost ansible_ssh_port=2222 ansible_ssh_host=127.0.0.3 ansible_ssh_user=root ansible_ssh_pass=foobar ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' +executor ansible_ssh_host=127.0.0.1 ansible_connection=local diff --git a/roles/standard-test-docker/files/docker-run-ssh b/roles/standard-test-docker/files/docker-run-ssh index 16faf06..75d530a 100644 --- a/roles/standard-test-docker/files/docker-run-ssh +++ b/roles/standard-test-docker/files/docker-run-ssh @@ -1,15 +1,30 @@ #!/bin/sh +authorized_key= python_version=2 +rootpass=foobar while [ $# -gt 0 ]; do case "$1" in - --py3) python_version=3 ;; + --py3) + python_version=3 + ;; + --authorized-key) + authorized_key="$2" + shift + ;; esac shift done -dnf install -y openssh-server python${python_version}-dnf +# install minimum requirements to run ansible +dnf install -y openssh-server python${python_version}-dnf rsync findutils +# configure SSH ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key -echo 'root:foobar' | chpasswd -# start sshd in background +echo "root:$rootpass" | chpasswd +if [ -n "$authorized_key" ]; then + mkdir -p /root/.ssh + echo "$authorized_key" >> /root/.ssh/authorized_keys + chmod 644 /root/.ssh/authorized_keys +fi +# start SSHD in background /usr/sbin/sshd echo SSHD READY # wait forever diff --git a/roles/standard-test-docker/tasks/main.yml b/roles/standard-test-docker/tasks/main.yml index e6372aa..2f6013c 100644 --- a/roles/standard-test-docker/tasks/main.yml +++ b/roles/standard-test-docker/tasks/main.yml @@ -29,11 +29,28 @@ my_playbook_extra_args: "{{my_playbook_extra_args}} -e \"rpms='{{rpms}}'\"" when: rpms|default("") != "" +- name: Create temporary directory + tempfile: + state: directory + suffix: docker + register: my_docker_tempdir + +- name: Create key pair for SSH authentication in container + shell: "/usr/bin/ssh-keygen -t rsa -N '' -f {{ my_docker_tempdir.path + '/key' }}" + +- name: Read contents of generated SSH public key file + set_fact: + my_public_key: "{{ lookup('file', my_docker_tempdir.path + '/key.pub') }}" + +- name: Configure arguments for SSH key based authentication + set_fact: + my_playbook_extra_args: "{{my_playbook_extra_args}} --private-key '{{ my_docker_tempdir.path + \'/key\' }}'" + my_run_cmd_extra_args: "{{my_run_cmd_extra_args}} --authorized-key '{{ my_public_key }}'" + - name: Start ansible-ready docker container running SSHD shell: > docker run -d -p '{{docker_ssh_port}}:22' - -v '{{artifacts}}:/artifacts:z,rw' -v '{{role_path}}/files/docker-run-ssh:/run.sh:z' {{docker_extra_args}} '{{subjects}}' @@ -47,19 +64,12 @@ - name: Wait for container to initialize wait_for: port="{{docker_ssh_port}}" search_regex=OpenSSH -# ******************************** -# HELP! -# There must be a better way to run the actual test playbook without running -# another instance of ansible-playbook in an external shell command. -# The external run means we can't track the return status of the invidual -# tasks in the test playbook--which is the whole point. -# ******************************** - name: Run the playbook in the container shell: > ANSIBLE_LOG_PATH='{{artifacts}}/container-playbook.log' ansible-playbook '{{playbooks}}' -i '{{role_path}}/files/docker-inventory' - -e artifacts='/artifacts' + -e artifacts='{{artifacts}}' {{my_playbook_extra_args}} register: playbook_output @@ -75,6 +85,12 @@ Continue when ready when: lookup('env','FEDORA_TEST_DIAGNOSE')|bool + - name: Remove temporary directory + file: + path: "{{ my_docker_tempdir.path }}/" + state: absent + when: my_docker_tempdir is defined + - name: Save the container log as an artifact shell: docker logs "{{ container_id }}" >"{{artifacts}}/docker.log" 2>&1 diff --git a/roles/standard-test-rhts/README.md b/roles/standard-test-rhts/README.md index 50efb62..338ce10 100644 --- a/roles/standard-test-rhts/README.md +++ b/roles/standard-test-rhts/README.md @@ -4,6 +4,9 @@ Put this role in your test_local.yml playbook. You'll need to have the following variables defined: * tests: A list of RHTS test directories - * artifacts: An artifacts directory + * artifacts: An artifacts directory on localhost to store logs + * remote_artifacts: The directory on the system under test + where the logs are stored. Note: if this variable is left + undefined, it will default to /tmp/artifacts * required_packages: A list of prerequisite packages required by RHTS tests * rpms: Space separated list of RPMs to install (optional, may include SRPMs) diff --git a/roles/standard-test-rhts/tasks/main.yml b/roles/standard-test-rhts/tasks/main.yml index 89cc28c..d3cb844 100644 --- a/roles/standard-test-rhts/tasks/main.yml +++ b/roles/standard-test-rhts/tasks/main.yml @@ -1,8 +1,9 @@ --- -- name: Install the RHTS pre-requirements +- name: Install the Ansible and RHTS pre-requirements package: name={{item}} state=latest with_items: - - dnf-plugins-core # COPR plugin needed + - rsync # need rsync for Ansible synchronize module + - dnf-plugins-core # need COPR plugin - beakerlib - make - createrepo @@ -22,6 +23,11 @@ with_items: - "{{ required_packages }}" +- name: Define remote_artifacts if it is not already defined + set_fact: + remote_artifacts: /tmp/artifacts + when: remote_artifacts is not defined + - name: Create legacy beakerlib directories file: dest: "{{ item }}" @@ -134,49 +140,51 @@ chmod 644 /root/.ssh/authorized_keys - name: Make artifacts directory - file: path={{ artifacts }} state=directory owner=root mode=755 recurse=yes + file: path={{ remote_artifacts }} state=directory owner=root mode=755 recurse=yes - name: Start restraintd # instead of using service module, daemon is started directly since we want the # output as an artifact (and this could be running in a container) - shell: nohup /usr/bin/restraintd >"{{ artifacts }}/restraintd.log" 2>&1 & + shell: nohup /usr/bin/restraintd >"{{ remote_artifacts }}/restraintd.log" 2>&1 & - name: Start local web server for restraint - shell: nohup /usr/bin/python -m SimpleHTTPServer "{{ local_www_port }}" >"{{ artifacts }}/httpd.log" 2>&1 & + shell: nohup /usr/bin/python -m SimpleHTTPServer "{{ local_www_port }}" >"{{ remote_artifacts }}/httpd.log" 2>&1 & args: chdir: "{{ local_www_dir }}/" - block: - name: Execute RHTS tests using restraint - shell: /usr/bin/restraint --host localhost --job "{{ job_xml_file }}" >"{{ artifacts }}/restraint.log" 2>&1 + shell: /usr/bin/restraint --host localhost --job "{{ job_xml_file }}" >"{{ remote_artifacts }}/restraint.log" 2>&1 args: - chdir: "{{ artifacts }}/" + chdir: "{{ remote_artifacts }}/" ignore_errors: True +- always: - name: Extract job output directory from restraint logfile - shell: sed -n 's/^Using \([^ ]*\).*$/\1/p' "{{ artifacts }}/restraint.log" + shell: sed -n 's/^Using \([^ ]*\).*$/\1/p' "{{ remote_artifacts }}/restraint.log" register: restraint_job_dir - name: Make job ouput directory tree readable by all file: - path: "{{ artifacts }}/{{restraint_job_dir.stdout}}" + path: "{{ remote_artifacts }}/{{restraint_job_dir.stdout}}" mode: u=rwX,g=rX,o=rX recurse: yes - name: Set name of restraint XML job results file - set_fact: results_xml="{{ artifacts }}/{{restraint_job_dir.stdout}}/job.xml" + set_fact: results_xml="{{ remote_artifacts }}/{{restraint_job_dir.stdout}}/job.xml" - name: Convert restraint XML job results to text as main output artifact - shell: xsltproc /usr/local/share/job2text.xsl "{{ results_xml }}" >"{{ artifacts }}/test.log" + shell: xsltproc /usr/local/share/job2text.xsl "{{ results_xml }}" >"{{ remote_artifacts }}/test.log" + + - name: Pull out the logs + synchronize: + dest: "{{ artifacts }}/" + src: "{{ remote_artifacts }}/" + mode: pull + ssh_args: "-o UserKnownHostsFile=/dev/null" + when: artifacts|default("") != "" - name: Check the results for failures - shell: grep '^FAIL ' "{{ artifacts }}/test.log" + shell: grep '^FAIL ' "{{ remote_artifacts }}/test.log" register: test_fails failed_when: test_fails.stdout or test_fails.stderr - -- always: - - name: Pull out the logs - fetch: - dest: "{{artifacts}}/" - src: "{{artifacts}}/" - flat: yes diff --git a/roles/standard-test-rhts/vars/main.yml b/roles/standard-test-rhts/vars/main.yml index 9dbdcfa..902f0cb 100644 --- a/roles/standard-test-rhts/vars/main.yml +++ b/roles/standard-test-rhts/vars/main.yml @@ -1,5 +1,6 @@ --- artifacts: ./artifacts +remote_artifacts: /tmp/artifacts tests: [] required_packages: [] local_www_dir: "/var/www-test" From b5e1ba3538ecfb3cd51f12221ff2cb9fb4d738b8 Mon Sep 17 00:00:00 2001 From: Merlin Mathesius Date: Jul 06 2017 12:56:45 +0000 Subject: [PATCH 2/2] Remove forced install of rsync and findutils --- diff --git a/roles/standard-test-docker/files/docker-run-ssh b/roles/standard-test-docker/files/docker-run-ssh index 75d530a..e5ec652 100644 --- a/roles/standard-test-docker/files/docker-run-ssh +++ b/roles/standard-test-docker/files/docker-run-ssh @@ -15,7 +15,7 @@ while [ $# -gt 0 ]; do shift done # install minimum requirements to run ansible -dnf install -y openssh-server python${python_version}-dnf rsync findutils +dnf install -y openssh-server python${python_version}-dnf # configure SSH ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key echo "root:$rootpass" | chpasswd