From 2fd41f4c9c90522989854761e385e7b5ff2be940 Mon Sep 17 00:00:00 2001 From: Federico Ressi Date: Mon, 11 Jul 2022 11:32:16 +0200 Subject: [PATCH] [Vagrant] Update Vagranfile and its playbooks - add multinode support for devstack nodes - write clouds.yaml and ssh_config file to devstack-tobiko-deploy source dir - update tobiko.conf file - create simple functional test cases to test vagrant configuration - remove local projects synchronization Change-Id: I9d2517d5fa6c72b98726af8aa3ba9fa8bcf0918f --- .gitignore | 12 +++ Vagrantfile | 75 ++++++++-------- playbooks/vagrant/ovn/local.conf | 88 +++++++++++-------- playbooks/vagrant/provision.yaml | 53 ++++------- .../devstack-tobiko-common/defaults/main.yaml | 17 ++-- .../devstack-tobiko-deploy/defaults/main.yaml | 5 ++ .../tasks/copy-devstack-plugin-tobiko.yaml | 33 +++++++ .../tasks/deploy-local-conf.yaml | 12 ++- .../tasks/deploy-project.yaml | 52 ----------- .../tasks/deploy-projects.yaml | 21 ----- .../tasks/get-devstack.yaml | 20 +++++ .../tasks/install-bindeps.yaml | 3 +- roles/devstack-tobiko-deploy/tasks/main.yaml | 5 +- .../tasks/register-compute-node.yaml | 31 +++++++ .../defaults/main.yaml | 3 + roles/devstack-tobiko-vagrant/tasks/main.yaml | 33 +++++++ roles/get-clouds-file/defaults/main.yaml | 4 + roles/get-clouds-file/meta/main.yaml | 4 + .../tasks/get-clouds-file.yaml | 40 +++++++++ roles/get-clouds-file/tasks/main.yaml | 3 + .../get-vagrant-ssh-config/defaults/main.yaml | 3 + roles/get-vagrant-ssh-config/meta/main.yaml | 4 + .../tasks/get-ssh-config.yaml | 38 ++++++++ roles/get-vagrant-ssh-config/tasks/main.yaml | 3 + test-requirements.txt | 14 +++ tests/functional/test_server.py | 38 ++++++++ tests/functional/test_topology.py | 32 +++++++ tobiko.conf.example | 8 ++ tox.ini | 9 ++ 29 files changed, 469 insertions(+), 194 deletions(-) create mode 100644 roles/devstack-tobiko-deploy/tasks/copy-devstack-plugin-tobiko.yaml delete mode 100644 roles/devstack-tobiko-deploy/tasks/deploy-project.yaml delete mode 100644 roles/devstack-tobiko-deploy/tasks/deploy-projects.yaml create mode 100644 roles/devstack-tobiko-deploy/tasks/get-devstack.yaml create mode 100644 roles/devstack-tobiko-deploy/tasks/register-compute-node.yaml create mode 100644 roles/devstack-tobiko-vagrant/defaults/main.yaml create mode 100644 roles/devstack-tobiko-vagrant/tasks/main.yaml create mode 100644 roles/get-clouds-file/defaults/main.yaml create mode 100644 roles/get-clouds-file/meta/main.yaml create mode 100644 roles/get-clouds-file/tasks/get-clouds-file.yaml create mode 100644 roles/get-clouds-file/tasks/main.yaml create mode 100644 roles/get-vagrant-ssh-config/defaults/main.yaml create mode 100644 roles/get-vagrant-ssh-config/meta/main.yaml create mode 100644 roles/get-vagrant-ssh-config/tasks/get-ssh-config.yaml create mode 100644 roles/get-vagrant-ssh-config/tasks/main.yaml create mode 100644 test-requirements.txt create mode 100644 tests/functional/test_server.py create mode 100644 tests/functional/test_topology.py create mode 100644 tobiko.conf.example diff --git a/.gitignore b/.gitignore index 7e94d84..1e5989b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,15 @@ # Vagrant files .vagrant + +# Configuration files +clouds.yaml +ssh_config +tobiko.conf + +# Cache files +__pycache__ +.pytest_cache + +# Log files +*.log diff --git a/Vagrantfile b/Vagrantfile index f781704..f689c40 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -16,7 +16,7 @@ MEMORY = ENV.fetch("VM_SIZE", "8192").to_i BOX = ENV.fetch("VM_BOX", "generic/ubuntu2004") # Machine host name -HOSTNAME = "tobiko" +HOSTNAME = "devstack" # Top vagrantfile dir VAGRANTFILE_DIR = File.dirname(__FILE__) @@ -29,7 +29,8 @@ PROVISION_PLAYBOOK = ENV.fetch( PROVISION_DIR = File.dirname(PROVISION_PLAYBOOK) # Host IP address to be assigned to OpenStack in DevStack -HOST_IP = "192.168.56.10" +HOST_NETWORK = "192.168.56" +TENANT_NETWORK = "192.168.57" # Local directory from where look for required projects files PROJECTS_DIR = File.dirname(ENV.fetch('PROJECTS_DIR', VAGRANTFILE_DIR)) @@ -40,30 +41,16 @@ TOX_ENVLIST = ENV.fetch('TOX_ENVLIST', '') TOX_EXTRA_ARGS = ENV.fetch('TOX_EXTRA_ARGS', '--notest') # Allow to switch configuration -DEVSTACK_CONF_NAME = ENV.fetch('DEVSTACK_CONF_NAME', 'ovs') +DEVSTACK_CONF_NAME = ENV.fetch('DEVSTACK_CONF_NAME', 'ovn') DEVSTACK_LOCAL_CONF_FILE = ENV.fetch( 'DEVSTACK_LOCAL_CONF_FILE', "#{PROVISION_DIR}/#{DEVSTACK_CONF_NAME}/local.conf" ) -# Local project directories to be copied -DEVSTACK_PROJECTS = { - # Local directory from where look for devstack project files - 'devstack' => { - 'src_dir' => ENV.fetch("DEVSTACK_DIR", "#{PROJECTS_DIR}/devstack"), - }, - # Local directory from where look for devstack tobiko plugin project files - 'devstack-plugin-tobiko' => { - 'src_dir' => ENV.fetch("DEVSTACK_PLUGIN_TOBIKO_SRC_DIR", VAGRANTFILE_DIR), - }, - - # Local directory from where looking for Tobiko project files - 'tobiko' => { - 'src_dir' => ENV.fetch("TOBIKO_SRC_DIR", "#{PROJECTS_DIR}/tobiko"), - }, - -} +# Multi-node configuration is still not working. There are issues with setting up +# networking to be handled. +NODES_COUNT = 1 # All Vagrant configuration is done below. The "2" in Vagrant.configure @@ -99,7 +86,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Create a private network, which allows host-only access to the machine # using a specific IP. - config.vm.network "private_network", ip: HOST_IP + # config.vm.network "private_network", ip: HOST_IP # Create a public network, which generally matched to bridged network. # Bridged networks make the machine appear as another physical device on @@ -116,30 +103,46 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # backing providers for Vagrant. These expose provider-specific options. # Example for VirtualBox: # + + node_memory = [4096, (MEMORY / NODES_COUNT).to_i].max + node_cpus = [4, (CPUS / NODES_COUNT).to_i].max config.vm.provider "virtualbox" do |vb| # Display the VirtualBox GUI when booting the machine vb.gui = false - - vb.cpus = CPUS - vb.memory = MEMORY + vb.cpus = node_cpus + vb.memory = node_memory end config.vm.provider "libvirt" do |libvirt| libvirt.qemu_use_session = false - libvirt.cpus = CPUS - libvirt.memory = MEMORY + libvirt.cpus = node_cpus + libvirt.memory = node_memory end - # Run provision playbook - config.vm.provision "ansible" do |ansible| - ansible.limit = 'all' - ansible.playbook = PROVISION_PLAYBOOK - ansible.extra_vars = ansible.extra_vars = { - 'devstack_projects' => DEVSTACK_PROJECTS, - 'devstack_local_conf_file' => DEVSTACK_LOCAL_CONF_FILE, - 'tox_envlist' => TOX_ENVLIST, - 'tox_extra_args' => TOX_EXTRA_ARGS, - } + for node_id in 0..(NODES_COUNT - 2) + secondary_hostname = "#{HOSTNAME}-secondary-#{node_id}" + config.vm.define secondary_hostname, primary: false do |secondary| + secondary.vm.hostname = secondary_hostname + secondary.vm.network "private_network", ip: "#{HOST_NETWORK}.#{20 + node_id}" + secondary.vm.network "private_network", ip: "#{TENANT_NETWORK}.#{20 + node_id}" + end end + primary_hostname = "#{HOSTNAME}-primary" + config.vm.define "devstack-primary", primary: true do |primary| + primary.vm.hostname = primary_hostname + primary.vm.network "private_network", ip: "#{HOST_NETWORK}.10" + primary.vm.network "private_network", ip: "#{TENANT_NETWORK}.10" + + # Run provision playbook + primary.vm.provision "ansible" do |ansible| + ansible.limit = 'all' + ansible.playbook = PROVISION_PLAYBOOK + ansible.extra_vars = ansible.extra_vars = { + 'devstack_local_conf_file' => DEVSTACK_LOCAL_CONF_FILE, + 'tox_envlist' => TOX_ENVLIST, + 'tox_extra_args' => TOX_EXTRA_ARGS, + } + end + end end diff --git a/playbooks/vagrant/ovn/local.conf b/playbooks/vagrant/ovn/local.conf index 4dbbc9b..758d9fe 100644 --- a/playbooks/vagrant/ovn/local.conf +++ b/playbooks/vagrant/ovn/local.conf @@ -1,14 +1,55 @@ [[local|localrc]] ADMIN_PASSWORD=secret -DATABASE_PASSWORD=$ADMIN_PASSWORD +DATABASE_PASSWORD=${ADMIN_PASSWORD} KEYSTONE_ADMIN_ENDPOINT=True -RABBIT_PASSWORD=$ADMIN_PASSWORD -SERVICE_PASSWORD=$ADMIN_PASSWORD +RABBIT_PASSWORD=${ADMIN_PASSWORD} +SERVICE_PASSWORD=${ADMIN_PASSWORD} + +DATABASE_TYPE=mysql LOGFILE=/opt/stack/devstack/stack.log VERBOSE=True LOG_COLOR=True -MULTI_HOST="0" +MULTI_HOST=1 + +IP_VERSION=4 +HOST_IP={{ devstack_host_ip }} +# FLOATING_RANGE=192.168.56.128/25 +SERVICE_HOST={{ devstack_primary_host_ip }} +MYSQL_HOST=${SERVICE_HOST} +RABBIT_HOST=${SERVICE_HOST} +GLANCE_HOSTPORT=${SERVICE_HOST}:9292 + +# ENABLE_CHASSIS_AS_GW=True +ENABLE_TLS=False +KEYSTONE_ADMIN_ENDPOINT=True +ML2_L3_PLUGIN=ovn-router,trunk +OVN_BUILD_MODULES=False +OVN_DBS_LOG_LEVEL=dbg +OVN_IGMP_SNOOPING_ENABLE=True +OVN_L3_CREATE_PUBLIC_NETWORK=True +# PHYSICAL_NETWORK=public +# PUBLIC_INTERFACE={{ devstack_public_interface }} +Q_AGENT=ovn +Q_ML2_PLUGIN_MECHANISM_DRIVERS=ovn,logger +Q_ML2_PLUGIN_TYPE_DRIVERS=local,flat,vlan,geneve +Q_ML2_TENANT_NETWORK_TYPE=geneve +Q_USE_PROVIDERNET_FOR_PUBLIC=True + +# Whether or not to build custom openvswitch kernel modules from the ovs git +# tree. This is disabled by default. This is required unless your distro kernel +# includes ovs+conntrack support. This support was first released in Linux 4.3, +# and will likely be backported by some distros. +# NOTE(mjozefcz): We need to compile the module for Ubuntu Bionic, because default +# shipped kernel module doesn't openflow meter action support. +OVN_BUILD_MODULES=False + +GLANCE_ENABLE_QUOTAS=False +TOBIKO_NEUTRON_IPV4_DNS_NAMESERVERS=1.1.1.1,8.8.8.8 + + +{% if devstack_primary %} +# Devstack primary node ======================================================= # Enable required services ---------------------------------------------------- enable_service key @@ -57,41 +98,12 @@ disable_service q-l3 disable_service q-dhcp disable_service q-meta -HOST_IP=192.168.56.10 -IP_VERSION=4 - -# ENABLE_CHASSIS_AS_GW=True -ENABLE_TLS=False -KEYSTONE_ADMIN_ENDPOINT=True -ML2_L3_PLUGIN=ovn-router,trunk -OVN_BUILD_MODULES=False -OVN_DBS_LOG_LEVEL=dbg -OVN_IGMP_SNOOPING_ENABLE=True -OVN_L3_CREATE_PUBLIC_NETWORK=True -# PHYSICAL_NETWORK=public -# PUBLIC_INTERFACE=eth0 -Q_AGENT=ovn -Q_ML2_PLUGIN_MECHANISM_DRIVERS=ovn,logger -Q_ML2_PLUGIN_TYPE_DRIVERS=local,flat,vlan,geneve -Q_ML2_TENANT_NETWORK_TYPE=geneve -Q_USE_PROVIDERNET_FOR_PUBLIC=True - -# Whether or not to build custom openvswitch kernel modules from the ovs git -# tree. This is disabled by default. This is required unless your distro kernel -# includes ovs+conntrack support. This support was first released in Linux 4.3, -# and will likely be backported by some distros. -# NOTE(mjozefcz): We need to compile the module for Ubuntu Bionic, because default -# shipped kernel module doesn't openflow meter action support. -OVN_BUILD_MODULES=False - - # Configure Horizon ----------------------------------------------------------- disable_service horizon # Configure Glance ------------------------------------------------------------ -enable_service g-api -GLANCE_ENABLE_QUOTAS="False" +enable_service g-api # Configure Cinder ------------------------------------------------------------ enable_service c-api @@ -106,4 +118,10 @@ enable_plugin heat https://opendev.org/openstack/heat.git # Configure Tobiko ------------------------------------------------------------ enable_plugin devstack-plugin-tobiko https://opendev.org/x/devstack-plugin-tobiko.git -TOBIKO_NEUTRON_IPV4_DNS_NAMESERVERS=1.1.1.1,8.8.8.8 +{% elif devstack_secondary %} +# Devstack secondary node ===================================================== + +enable_plugin neutron https://opendev.org/openstack/neutron.git +ENABLED_SERVICES=n-cpu,c-vol,placement-client,ovn-controller,ovs-vswitchd,ovsdb-server,q-ovn-metadata-agent + +{% endif %} diff --git a/playbooks/vagrant/provision.yaml b/playbooks/vagrant/provision.yaml index cd01592..5a373e5 100644 --- a/playbooks/vagrant/provision.yaml +++ b/playbooks/vagrant/provision.yaml @@ -1,44 +1,23 @@ --- - hosts: all - vars: - resolv_conf_file: /etc/resolv.conf - dest_dir: /opt/stack + roles: + - devstack-tobiko-vagrant - pre_tasks: - - - name: copy '{{ resolv_conf_file}}' file - become: true - copy: - src: '{{ resolv_conf_file }}' - dest: /etc/resolv.conf - owner: root - group: root - mode: '0644' - - - name: update APT database - apt: - update_cache: true - cache_valid_time: 3600 - become: true - when: - - ansible_os_family == 'Debian' - - - become: true - when: - - ansible_distribution == "CentOS" - - ansible_distribution_major_version == "8" - block: - - name: Switch from CentOS Linux repos to Centos Stream repos - command: dnf -y swap centos-linux-repos centos-stream-repos - args: - warn: false - - - name: Switch packages from CentOS Linux to to Centos Stream - command: dnf -y distro-sync - args: - warn: false +- hosts: devstack-primary roles: - devstack-tobiko-deploy - - devstack-tobiko-run-tests + - get-clouds-file + - get-vagrant-ssh-config + vars: + devstack_primary: true + devstack_plugin_tobiko_src_dir: >- + {{ playbook_dir | realpath | dirname | dirname }} + + +- hosts: devstack-secondary-* + roles: + - role: devstack-tobiko-deploy + vars: + devstack_primary: false diff --git a/roles/devstack-tobiko-common/defaults/main.yaml b/roles/devstack-tobiko-common/defaults/main.yaml index b8b7bb5..df35914 100644 --- a/roles/devstack-tobiko-common/defaults/main.yaml +++ b/roles/devstack-tobiko-common/defaults/main.yaml @@ -7,17 +7,14 @@ devstack_local_conf_file: '{{ playbook_dir }}/local.conf' devstack_projects_dir: '{{ playbook_dir | dirname }}' -devstack_projects_base: - devstack: - git_repo: 'https://opendev.org/openstack/devstack.git' - devstack-plugin-tobiko: - git_repo: 'https://opendev.org/x/devstack-plugin-tobiko.git' - tobiko: - git_repo: 'https://opendev.org/x/tobiko.git' - -devstack_projects: {} - devstack_dir: '{{ devstack_dest_dir }}/devstack' +devstack_git_repo: 'https://opendev.org/openstack/devstack.git' + +devstack_plugin_tobiko_dir: '{{ devstack_dest_dir }}/devstack-plugin-tobiko' +devstack_plugin_tobiko_src_dir: '' + +tobiko_config_path: '{{ devstack_plugin_tobiko_src_dir }}/tobiko.conf' +tobiko_config_dir: '{{ tobiko_config_path | realpath | dirname }}' sudo_secure_path: '' diff --git a/roles/devstack-tobiko-deploy/defaults/main.yaml b/roles/devstack-tobiko-deploy/defaults/main.yaml index 2997e9f..de3a293 100644 --- a/roles/devstack-tobiko-deploy/defaults/main.yaml +++ b/roles/devstack-tobiko-deploy/defaults/main.yaml @@ -3,3 +3,8 @@ force_restack: false stack_succeeded_file: '{{ devstack_dir }}/SUCCEEDED' swap_file_size: 8192 +devstack_primary: true +devstack_secondary: '{{ not devstack_primary }}' +devstack_host_interface: eth1 +devstack_primary_host_ip: 192.168.56.10 +devstack_public_interface: eth2 diff --git a/roles/devstack-tobiko-deploy/tasks/copy-devstack-plugin-tobiko.yaml b/roles/devstack-tobiko-deploy/tasks/copy-devstack-plugin-tobiko.yaml new file mode 100644 index 0000000..3be6b96 --- /dev/null +++ b/roles/devstack-tobiko-deploy/tasks/copy-devstack-plugin-tobiko.yaml @@ -0,0 +1,33 @@ +--- + +- name: consolidate file paths + set_fact: + devstack_plugin_tobiko_dir: >- + {{ devstack_plugin_tobiko_dir | realpath }} + devstack_plugin_tobiko_src_dir: >- + {{ devstack_plugin_tobiko_src_dir | realpath }} + + +- name: ensure '{{ devstack_plugin_tobiko_dir }}' exists + become: true + become_user: root + file: + path: '{{ devstack_plugin_tobiko_dir }}' + state: directory + mode: '0755' + owner: stack + group: stack + + +- name: copy '{{ devstack_plugin_tobiko_src_dir }}' + synchronize: + group: false + owner: false + src: '{{ devstack_plugin_tobiko_src_dir }}/.' + dest: '{{ devstack_plugin_tobiko_dir }}' + use_ssh_args: true + recursive: true + rsync_opts: + - '--exclude-from={{ devstack_plugin_tobiko_src_dir }}/.gitignore' + become: true + become_user: stack diff --git a/roles/devstack-tobiko-deploy/tasks/deploy-local-conf.yaml b/roles/devstack-tobiko-deploy/tasks/deploy-local-conf.yaml index 825debd..27c9f1f 100644 --- a/roles/devstack-tobiko-deploy/tasks/deploy-local-conf.yaml +++ b/roles/devstack-tobiko-deploy/tasks/deploy-local-conf.yaml @@ -1,8 +1,18 @@ --- +- name: get {{ devstack_host_interface }} host IP + shell: >- + ip addr list {{ devstack_host_interface }} | grep 'inet ' | awk '{print $2}' + register: get_devstack_host_ip + +- name: parse host IP + set_fact: + devstack_host_ip: >- + {{ get_devstack_host_ip.stdout.split('/', 1)[0] }} + - name: copy local.conf file become: true - copy: + template: owner: stack group: stack src: '{{ devstack_local_conf_file }}' diff --git a/roles/devstack-tobiko-deploy/tasks/deploy-project.yaml b/roles/devstack-tobiko-deploy/tasks/deploy-project.yaml deleted file mode 100644 index 19a144c..0000000 --- a/roles/devstack-tobiko-deploy/tasks/deploy-project.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- - -- name: "ensure '{{ project_dest_dir }}' exists" - become: true - become_user: root - file: - path: '{{ project_dest_dir | realpath }}' - state: directory - mode: '0755' - owner: stack - group: stack - when: >- - ( project_src_dir | length) > 0 or - ( project_git_repo | length) > 0 - - -- name: "check '{{ project_src_dir }}' exists" - stat: - path: '{{ project_src_dir }}' - delegate_to: localhost - register: check_project_src_dir_exists - when: ( project_src_dir | length) > 0 - - -- become: true - become_user: stack - block: - - - name: copy '{{ project_src_dir }}' to '{{ project_dest_dir }}' - synchronize: - group: false - owner: false - src: "{{ project_src_dir | realpath }}/." - dest: "{{ project_dest_dir | realpath }}" - use_ssh_args: true - recursive: true - rsync_opts: - - '--exclude-from={{ project_src_dir | realpath }}/.gitignore' - register: copy_project_src_dir - when: check_project_src_dir_exists.stat.isdir | default(False) - - - name: >- - fetch project sources from '{{ project_git_repo }}' to - '{{ project_dest_dir }}' - git: - repo: '{{ project_git_repo }}' - dest: '{{ project_dest_dir }}' - version: '{{ project_git_version }}' - force: true - when: - - copy_project_src_dir is skipped - - ( project_git_repo | length) > 0 diff --git a/roles/devstack-tobiko-deploy/tasks/deploy-projects.yaml b/roles/devstack-tobiko-deploy/tasks/deploy-projects.yaml deleted file mode 100644 index a1aec7a..0000000 --- a/roles/devstack-tobiko-deploy/tasks/deploy-projects.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- - -- name: combine DevStack projects - set_fact: - devstack_projects_combined: >- - {{ [devstack_projects_base, devstack_projects] | - combine(recursive=True) }} - - -- name: show resulting DevStack projects - debug: var=devstack_projects_combined - - -- name: deploy projects - include_tasks: deploy-project.yaml - with_dict: '{{ devstack_projects_combined }}' - vars: - project_dest_dir: '{{ devstack_dest_dir }}/{{ item.key }}' - project_src_dir: '{{ item.value.src_dir | default("") }}' - project_git_repo: '{{ item.value.git_repo | default("") }}' - project_git_version: '{{ item.value.git_version | default("HEAD") }}' diff --git a/roles/devstack-tobiko-deploy/tasks/get-devstack.yaml b/roles/devstack-tobiko-deploy/tasks/get-devstack.yaml new file mode 100644 index 0000000..c4606a0 --- /dev/null +++ b/roles/devstack-tobiko-deploy/tasks/get-devstack.yaml @@ -0,0 +1,20 @@ +--- + +- name: ensure '{{ devstack_dir }}' exists + become: true + become_user: root + file: + path: '{{ devstack_dir | realpath }}' + state: directory + mode: '0755' + owner: stack + group: stack + + +- name: checkout devstack files from '{{ devstack_git_repo }}' + git: + repo: '{{ devstack_git_repo }}' + dest: '{{ devstack_dir | realpath }}' + update: no + become: true + become_user: stack diff --git a/roles/devstack-tobiko-deploy/tasks/install-bindeps.yaml b/roles/devstack-tobiko-deploy/tasks/install-bindeps.yaml index 5e01808..9db8338 100644 --- a/roles/devstack-tobiko-deploy/tasks/install-bindeps.yaml +++ b/roles/devstack-tobiko-deploy/tasks/install-bindeps.yaml @@ -1,9 +1,10 @@ --- -- name: "ensure DevStack bindeps are installed" +- name: "ensure required packages are installed" become: true package: name: + - acl - git - iptables - python3 diff --git a/roles/devstack-tobiko-deploy/tasks/main.yaml b/roles/devstack-tobiko-deploy/tasks/main.yaml index 74f9ea3..35b3bd9 100644 --- a/roles/devstack-tobiko-deploy/tasks/main.yaml +++ b/roles/devstack-tobiko-deploy/tasks/main.yaml @@ -4,7 +4,10 @@ - include_tasks: install-bindeps.yaml - include_tasks: ensure-stack-user.yaml - include_tasks: run-unstack.yaml -- include_tasks: deploy-projects.yaml +- include_tasks: get-devstack.yaml +- include_tasks: copy-devstack-plugin-tobiko.yaml + when: devstack_plugin_tobiko_src_dir - include_tasks: deploy-local-conf.yaml - include_tasks: run-stack.yaml - include_tasks: setup-profile.yaml +- include_tasks: register-compute-node.yaml diff --git a/roles/devstack-tobiko-deploy/tasks/register-compute-node.yaml b/roles/devstack-tobiko-deploy/tasks/register-compute-node.yaml new file mode 100644 index 0000000..9b89021 --- /dev/null +++ b/roles/devstack-tobiko-deploy/tasks/register-compute-node.yaml @@ -0,0 +1,31 @@ +--- + +- name: wait for nova service registration + shell: | + export OS_CLOUD=devstack-admin + openstack compute service list -f value -c Host | grep $(hostname) + until: get_compute_service_list is not failed + retries: 30 + delay: 5 + register: get_compute_service_list + changed_when: false + +- name: run tools/discover_hosts.sh + shell: + cmd: >- + ./tools/discover_hosts.sh + chdir: '{{ devstack_dir }}' + become: true + become_user: stack + delegate_to: devstack-primary + +- name: wait for nova hypervisor registration + shell: | + export OS_CLOUD=devstack-admin + openstack hypervisor list -f value -c 'Hypervisor Hostname' |\ + grep $(hostname) + until: get_compute_service_list is not failed + retries: 3 + delay: 5 + register: get_compute_service_list + changed_when: false diff --git a/roles/devstack-tobiko-vagrant/defaults/main.yaml b/roles/devstack-tobiko-vagrant/defaults/main.yaml new file mode 100644 index 0000000..44f293d --- /dev/null +++ b/roles/devstack-tobiko-vagrant/defaults/main.yaml @@ -0,0 +1,3 @@ +--- + +resolv_conf_file: /etc/resolv.conf diff --git a/roles/devstack-tobiko-vagrant/tasks/main.yaml b/roles/devstack-tobiko-vagrant/tasks/main.yaml new file mode 100644 index 0000000..a482a94 --- /dev/null +++ b/roles/devstack-tobiko-vagrant/tasks/main.yaml @@ -0,0 +1,33 @@ +--- + +- name: copy '{{ resolv_conf_file}}' file + become: true + copy: + src: '{{ resolv_conf_file }}' + dest: /etc/resolv.conf + owner: root + group: root + mode: '0644' + +- name: update APT database + apt: + update_cache: true + cache_valid_time: 3600 + become: true + when: + - ansible_os_family == 'Debian' + +- become: true + when: + - ansible_distribution == "CentOS" + - ansible_distribution_major_version == "8" + block: + - name: Switch from CentOS Linux repos to Centos Stream repos + command: dnf -y swap centos-linux-repos centos-stream-repos + args: + warn: false + + - name: Switch packages from CentOS Linux to to Centos Stream + command: dnf -y distro-sync + args: + warn: false diff --git a/roles/get-clouds-file/defaults/main.yaml b/roles/get-clouds-file/defaults/main.yaml new file mode 100644 index 0000000..e7b901a --- /dev/null +++ b/roles/get-clouds-file/defaults/main.yaml @@ -0,0 +1,4 @@ +--- + +devstack_clouds_file_path: /etc/openstack/clouds.yaml +tobiko_clouds_file_path: '{{ tobiko_config_dir }}/clouds.yaml' diff --git a/roles/get-clouds-file/meta/main.yaml b/roles/get-clouds-file/meta/main.yaml new file mode 100644 index 0000000..13a388c --- /dev/null +++ b/roles/get-clouds-file/meta/main.yaml @@ -0,0 +1,4 @@ +--- + +dependencies: + - devstack-tobiko-common diff --git a/roles/get-clouds-file/tasks/get-clouds-file.yaml b/roles/get-clouds-file/tasks/get-clouds-file.yaml new file mode 100644 index 0000000..9c47088 --- /dev/null +++ b/roles/get-clouds-file/tasks/get-clouds-file.yaml @@ -0,0 +1,40 @@ +--- + +- name: Read {{ devstack_clouds_file_path }} file + slurp: + src: '{{ devstack_clouds_file_path }}' + register: read_devstack_clouds_file + + +- name: Write clouds file to '{{ tobiko_clouds_file_path }}' + copy: + content: '{{ read_devstack_clouds_file.content | b64decode }}' + dest: '{{ tobiko_clouds_file_path }}' + delegate_to: localhost + + +- name: Write clouds file dir to {{ tobiko_config_path }} + ini_file: + path: '{{ tobiko_config_path }}' + section: keystone + option: clouds_file_dirs + value: '{{ tobiko_clouds_file_path | dirname }}' + delegate_to: localhost + + +- name: Write clouds file name to {{ tobiko_config_path }} + ini_file: + path: '{{ tobiko_config_path }}' + section: keystone + option: clouds_file_names + value: '{{ tobiko_clouds_file_path | basename }}' + delegate_to: localhost + + +- name: Write cloud name dir to {{ tobiko_config_path }} + ini_file: + path: '{{ tobiko_config_path }}' + section: keystone + option: cloud_name + value: devstack-admin + delegate_to: localhost diff --git a/roles/get-clouds-file/tasks/main.yaml b/roles/get-clouds-file/tasks/main.yaml new file mode 100644 index 0000000..81f0e2a --- /dev/null +++ b/roles/get-clouds-file/tasks/main.yaml @@ -0,0 +1,3 @@ +--- + +- include_tasks: get-clouds-file.yaml diff --git a/roles/get-vagrant-ssh-config/defaults/main.yaml b/roles/get-vagrant-ssh-config/defaults/main.yaml new file mode 100644 index 0000000..c28f263 --- /dev/null +++ b/roles/get-vagrant-ssh-config/defaults/main.yaml @@ -0,0 +1,3 @@ +--- + +tobiko_ssh_config_path: '{{ tobiko_config_dir }}/ssh_config' diff --git a/roles/get-vagrant-ssh-config/meta/main.yaml b/roles/get-vagrant-ssh-config/meta/main.yaml new file mode 100644 index 0000000..13a388c --- /dev/null +++ b/roles/get-vagrant-ssh-config/meta/main.yaml @@ -0,0 +1,4 @@ +--- + +dependencies: + - devstack-tobiko-common diff --git a/roles/get-vagrant-ssh-config/tasks/get-ssh-config.yaml b/roles/get-vagrant-ssh-config/tasks/get-ssh-config.yaml new file mode 100644 index 0000000..6496b40 --- /dev/null +++ b/roles/get-vagrant-ssh-config/tasks/get-ssh-config.yaml @@ -0,0 +1,38 @@ +--- + +- delegate_to: localhost + block: + + - name: ensure '{{ tobiko_ssh_config_path | dirname }}' exists + file: + path: '{{ tobiko_ssh_config_path | dirname }}' + state: directory + + - name: get ssh_config content' + shell: + cmd: vagrant ssh-config + chdir: '{{ devstack_plugin_tobiko_src_dir }}' + register: get_ssh_config + changed_when: false + + - debug: var=get_ssh_config + + - name: write ssh_config to file '{{ tobiko_ssh_config_path }}' + copy: + content: | + {{ get_ssh_config.stdout }} + dest: '{{ tobiko_ssh_config_path }}' + + - name: write ssh_config file path to {{ tobiko_config_path }} + ini_file: + path: '{{ tobiko_config_path }}' + section: ssh + option: config_files + value: '{{ tobiko_ssh_config_path }}' + + - name: write SSH proxy jump host to {{ tobiko_config_path }} + ini_file: + path: '{{ tobiko_config_path }}' + section: ssh + option: proxy_jump + value: devstack-primary diff --git a/roles/get-vagrant-ssh-config/tasks/main.yaml b/roles/get-vagrant-ssh-config/tasks/main.yaml new file mode 100644 index 0000000..0eb8a49 --- /dev/null +++ b/roles/get-vagrant-ssh-config/tasks/main.yaml @@ -0,0 +1,3 @@ +--- + +- include_tasks: get-ssh-config.yaml diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..4ac0a7d --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,14 @@ +ansi2html # LGPLv3+ +dpkt # BSD +pandas # BSD +podman # Apache-2.0 + +pytest # MIT +pytest-cov # MIT +pytest-html # MPL-2.0 +pytest-reportportal # Apache-2.0 +pytest-rerunfailures # MPL-2.0 +pytest-timeout # MIT +pytest-xdist[psutil] # MIT +tobiko # Apache-2.0 +varlink # Apache-2.0 diff --git a/tests/functional/test_server.py b/tests/functional/test_server.py new file mode 100644 index 0000000..d1b2387 --- /dev/null +++ b/tests/functional/test_server.py @@ -0,0 +1,38 @@ +# Copyright (c) 2019 Red Hat +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +import pytest + +import tobiko +from tobiko.openstack import stacks +from tobiko.shell import ping +from tobiko.shell import sh + + +@pytest.fixture +def server_stack() -> stacks.ServerStackFixture: + return tobiko.setup_fixture(stacks.CirrosServerStackFixture) + + +def test_ssh(server_stack: stacks.ServerStackFixture): + """Test SSH connectivity to floating IP address""" + hostname = sh.ssh_hostname(ssh_client=server_stack.ssh_client) + assert server_stack.server_name.lower() == hostname + + +def test_ping(server_stack: stacks.ServerStackFixture): + """Test ICMP connectivity to floating IP address""" + ping.assert_reachable_hosts([server_stack.floating_ip_address]) diff --git a/tests/functional/test_topology.py b/tests/functional/test_topology.py new file mode 100644 index 0000000..97d04f6 --- /dev/null +++ b/tests/functional/test_topology.py @@ -0,0 +1,32 @@ +# Copyright (c) 2019 Red Hat +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from __future__ import absolute_import + +from tobiko.openstack import topology +from tobiko.shell import ping +from tobiko.shell import sh + + +def test_ssh(): + """Test SSH connectivity to devstack nodes""" + for node in topology.list_openstack_nodes(): + assert node.name == sh.ssh_hostname(ssh_client=node.ssh_client) + + +def test_ping(): + """Test ICMP connectivity to devstack nodes""" + ips = [node.public_ip + for node in topology.list_openstack_nodes()] + ping.assert_reachable_hosts(ips) diff --git a/tobiko.conf.example b/tobiko.conf.example new file mode 100644 index 0000000..5af3f10 --- /dev/null +++ b/tobiko.conf.example @@ -0,0 +1,8 @@ + +[keystone] +clouds_file_dirs = . +clouds_file_names = clouds.yaml + +[ssh] +config_files = ssh_config +proxy_jump = devstack-primary diff --git a/tox.ini b/tox.ini index 1262c60..a917a11 100644 --- a/tox.ini +++ b/tox.ini @@ -26,3 +26,12 @@ deps = changedir = doc/source commands = sphinx-build -W -b html . ../build/html + + +[testenv:functional] +deps = + -r test-requirements.txt +setenv = + TESTS_DIR = {toxinidir}/tests/functional +commands = + pytest {posargs:{env:TESTS_DIR}}