diff --git a/README.md b/README.md index b0b59a93..d95521ff 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,35 @@ For OSP deploy with Ceph using Composable Roles, After setting the above specifi Note: User can customize [internal.yml.j2](templates/internal.yml.j2) template for Ceph deployment based on their requirement if needed +2) set composable_roles: true true in group_vars/all.yml + +## Pbench agent Installations +To install Pbench agent on the compute nodes and vm's (i.e client and server),you have to follow the below steps and set the below params install/group_vars/all.yml + +``` + pbench_key_url: + pbench_config_url: + + #check the infrared inv to update the value + id_rsa_overcloud: ~/.infrared/.workspaces//id_rsa_overcloud + undercloud_hostname: +``` + +`cd {{ ansible_user_dir}}/jetpack/install` + +1) To create the client and server + `ansible-playbook boot_vms.yml` + +To install Pbench agent on Trafficgen host, set the below params + +``` +trafficgen_host: + ip: + ssh_pass: password + ssh_user: root +``` +2) Install Pbench agent bootstrapping + `ansible-playbook pbench_agent_bootstrap.yml -e "repos=" ` +3) Install Pbench agent install + `ansible-playbook pbench_agent_install.yml` + diff --git a/install/ansible.cfg b/install/ansible.cfg new file mode 100644 index 00000000..864961b1 --- /dev/null +++ b/install/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +host_key_checking = false +inventory = ~/.infrared/.workspaces/active/hosts +timeout = 120 diff --git a/install/boot_vms.yml b/install/boot_vms.yml new file mode 100644 index 00000000..77e77087 --- /dev/null +++ b/install/boot_vms.yml @@ -0,0 +1,100 @@ +--- + +# Playbook to create client and server vm on Openstack +# +# ansible-playbook boot_vms.yml + +- hosts: undercloud + gather_facts: yes + become: true + vars: + vm_password: centos + external_network: public + pre_tasks: + - name: generate pass_auth.sh + template: + src: pass_auth.sh.j2 + dest: "{{ user_dir }}/pass_auth.sh" + mode: a+rwx + + - name: install packages + package: + name: "{{ item }}" + state: present + loop: + - wget + - libguestfs-tools + - sshpass + - libvirt + + - name: restart libvirt service + service: + name: libvirtd + state: restarted + + roles: + - images + - flavors + - network + - create_vm + + post_tasks: + - name: check router exists + shell: | + . {{ overcloudrc }} + openstack router list | grep 'r1' + register: router_exists + ignore_errors: yes + + - name: router + shell: | + . {{ overcloudrc }} + openstack router create r1 + cidr=10.0.0.0 + subnet_id=`openstack subnet list -c ID -c Subnet -f value | grep $cidr | cut -d' ' -f1` + neutron router-interface-add r1 $subnet_id + neutron router-gateway-set r1 {{ external_network }} + when: router_exists.stdout == "" + + - name: create floating ip for client and server + shell: | + . {{ overcloudrc }} + client_port_id=`openstack port show {{ ports[0] }} -c id -f value` + server_port_id=`openstack port show {{ ports[1] }} -c id -f value` + neutron floatingip-create --port-id $client_port_id {{ external_network }} + neutron floatingip-create --port-id $server_port_id {{ external_network }} + ignore_errors: yes + + - name: get floating ip of server and client + shell: | + . {{ overcloudrc }} + openstack server list | grep {{ item }} | cut -d \| -f 5 | cut -d \, -f 2 | awk '{$1=$1;print}' + register: vms_fip + with_items: + - "{{ vm_names }}" + + - name: update user to root + lineinfile: + path: "{{ user_dir}}/.ssh/config" + regexp: ' User heat-admin' + line: ' User root' + + - name: copy the ssh keys + shell: | + . {{ overcloudrc }} + echo '{{ vm_password }}' | sshpass ssh-copy-id -i {{ user_dir }}/.ssh/id_rsa -o 'StrictHostKeyChecking no' -f root@{{ item.stdout }} + with_items: "{{ vms_fip.results }}" + changed_when: false + + - name: get default route + shell: | + ip r | grep default | cut -d ' ' -f5 + register: default_route + + - name: flush iptables on undercloud and add masquerade rule + become: true + shell: | + iptables -F + iptables -t nat -L --line-numbers + iptables -t nat -A POSTROUTING -o {{ default_route.stdout }} -j MASQUERADE + iptables -t nat -A POSTROUTING -o br-ctlplane -j MASQUERADE diff --git a/install/filter_plugins/install_filters.py b/install/filter_plugins/install_filters.py new file mode 100644 index 00000000..a449e577 --- /dev/null +++ b/install/filter_plugins/install_filters.py @@ -0,0 +1,10 @@ +def dict_remove_item( dict, item): + """Remove an item from a dictionary.""" + del dict[item] + return dict + +class FilterModule(object): + def filters(self): + return { + 'dict_remove_item': dict_remove_item, + } diff --git a/install/group_vars/all.yml b/install/group_vars/all.yml new file mode 100644 index 00000000..b2e1f480 --- /dev/null +++ b/install/group_vars/all.yml @@ -0,0 +1,41 @@ +--- +guest_image_name: pbench_image +# user can add the guest_image url required below +guest_images: + pbench_image: + name: pbench_image + url_centos8: http://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2 + url_centos7: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2 + type: qcow2 + convert_to_raw: false + +# rhel 8 +epel_repo: + el8: https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm + el7: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + +pbench_image_rhel: false + +#name for the client and server +vm_names: [ client, server ] +# port names +ports: [ 'client_port', 'server_port'] +timeout: 15 + +# trafficgen host ip address +#trafficgen_host: +# ip: +# ssh_pass: password +# ssh_user: root + +user_dir: /home/stack +overcloudrc: /home/stack/overcloudrc +stackrc: /home/stack/stackrc + +# update the values to install pbench agent +#check the infrared inv +#id_rsa_overcloud: ~/.infrared/.workspaces//id_rsa_overcloud +#undercloud_hostname: +#pbench_key_url: +#pbench_config_url: +pbench_configuration_environment: "production" diff --git a/install/pbench_agent_bootstrap.yml b/install/pbench_agent_bootstrap.yml new file mode 100644 index 00000000..fd54b015 --- /dev/null +++ b/install/pbench_agent_bootstrap.yml @@ -0,0 +1,65 @@ +--- +# +# Playbook for installing pbench_bootstrap +# +# Usage: +# ansible-playbook pbench_agent_bootstrap.yml -e "repos=" + +- hosts: compute + tasks: + - name: copy the keys + shell: | + sudo cp -r ~/.ssh /root/ + +- hosts: undercloud + gather_facts: yes + tasks: + - name: clone perf-dept + shell: | + GIT_SSL_NO_VERIFY=true git clone {{ repos }} + ignore_errors: yes + + - name: copy keys to trafficgen host + shell: | + echo '{{ trafficgen_host.ssh_pass }}' | sshpass ssh-copy-id -i ~/.ssh/id_rsa -o 'StrictHostKeyChecking no' -f {{ trafficgen_host.ssh_user }}@{{ trafficgen_host.ip }} + register: ssh_result + changed_when: false + ignore_errors: true + when: trafficgen_host is defined + + - name: get computes ip + shell: | + . {{ stackrc }} + nova list | grep -i "compute" | cut -d \| -f 7 |cut -d \= -f 2 | awk '{$1=$1;print}' + register: computes_ip + + - name: get floating ip of server and client + shell: | + . {{ overcloudrc }} + openstack server list | grep {{ item }} | cut -d \| -f 5 | cut -d \, -f 2 | awk '{$1=$1;print}' + register: vms_fip + with_items: + - "{{ vm_names }}" + + - name: copy the keys + shell: | + sudo cp -r ~/.ssh /root/ + + - name: create inventories + file: + path: "{{ user_dir }}/.config/Inventories/" + state: directory + + - name: generate a inventory + template: + src: repo_bootstrap.hosts.j2 + dest: "{{ user_dir }}/.config/Inventories/repo-bootstrap.hosts" + + - name: run repo-bootstrap.yml + shell: | + ansible-playbook --user=root -i "{{ user_dir}}/.config/Inventories/repo-bootstrap.hosts" repo-bootstrap.yml + register: repo_bootstrap + args: + chdir: "{{ user_dir }}/perf-dept/sysadmin/Ansible" + - debug: + msg: "{{ repo_bootstrap }}" diff --git a/install/pbench_agent_install.yml b/install/pbench_agent_install.yml new file mode 100644 index 00000000..01619a83 --- /dev/null +++ b/install/pbench_agent_install.yml @@ -0,0 +1,98 @@ +# ansible-playbook pbench_agent_install.yml + +- hosts: compute + gather_facts: yes + tasks: + - name: install latest epel and perl-Data-UUID + yum: + name: "{{ epel_repo.el7 }}" + state: present + become: yes + loop: + - "{{ epel_repo.el7 }}" + - perl-Data-UUID + when: ansible_distribution_major_version < '8' + + - name: install perl-Data-UUID on Compute nodes + become: true + dnf: + name: perl-Data-UUID + state: present + when: ansible_distribution_major_version == '8' + +- hosts: undercloud + gather_facts: yes + tasks: + - name: get floating ip of server and client + shell: | + . {{ overcloudrc }} + openstack server list | grep {{ item }} | cut -d \| -f 5 | cut -d \, -f 2 | awk '{$1=$1;print}' + register: vms_fip + with_items: + - "{{ vm_names }}" + +- hosts: localhost + vars: + pbench_agent_install: true + vms_fip: "{{ hostvars['undercloud']['vms_fip'] }}" + host_file: "{{ ansible_user_dir }}/.config/hosts" + infrared_inv: "{{ ansible_user_dir }}/.infrared/.workspaces/active/hosts" + + tasks: + - name: copy keys to trafficgen host + shell: | + echo '{{ trafficgen_host.ssh_pass }}' | sshpass ssh-copy-id -i ~/.ssh/id_rsa -o 'StrictHostKeyChecking no' -f {{ trafficgen_host.ssh_user }}@{{ trafficgen_host.ip }} + register: ssh_result + changed_when: false + ignore_errors: true + when: trafficgen_host is defined + + - name: Install the pbench-agent roles from Galaxy + shell: | + ansible-galaxy collection install pbench.agent + export ANSIBLE_ROLES_PATH=$HOME/.ansible/collections/ansible_collections/pbench/agent/roles:$ANSIBLE_ROLES_PATH + + - name: generate pbench agent playbook + template: + src: pbench_agent_install.yml.j2 + dest: "{{ ansible_user_dir }}/.ansible/collections/ansible_collections/pbench/agent/roles/pbench_agent_install.yml" + + - name: create .config dir + file: + path: "{{ ansible_user_dir }}/.config/" + state: directory + + - name: copy the infrared inv in ~/.config + shell: | + cp {{ infrared_inv }} {{ host_file }} + + - name: Add client and server in inventory + blockinfile: + path: "{{ host_file }}" + marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item[0] }}" + regexp: "[local]" + block: | + {{ item[0] }} original_name= ansible_host={{ item[1].stdout }} ansible_connection=ssh ansible_user=root ansible_ssh_private_key_file={{ id_rsa_overcloud }} ansible_ssh_common_args='-o ProxyCommand="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p -i {{ ansible_user_dir }}/.ssh/id_rsa stack@{{ undercloud_hostname }}"' + with_together: + - "{{ vm_names }}" + - "{{ vms_fip.results }}" + + - name: create a inventory file + template: + src: my.hosts.j2 + dest: "{{ ansible_user_dir }}/.config/myhosts.inv" + + - name: generate a pbench_agent_install inv + shell: | + cat "{{ ansible_user_dir }}/.config/myhosts.inv" >> {{ host_file }} + + - name: run the playbook pbench_agent_install.yml + shell: | + export ANSIBLE_HOST_KEY_CHECKING=False + ansible-playbook -i {{ host_file }} pbench_agent_install.yml -T {{ timeout }} --user=root + register: agent_install + args: + chdir: "{{ ansible_user_dir }}/.ansible/collections/ansible_collections/pbench/agent/roles/" + - debug: + msg: "{{ agent_install }}" + diff --git a/install/roles/create_vm/tasks/main.yml b/install/roles/create_vm/tasks/main.yml new file mode 100644 index 00000000..02a28d09 --- /dev/null +++ b/install/roles/create_vm/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: create a vm's + shell: . {{ overcloudrc }}; openstack server create --flavor pbench_flavor --image {{ guest_image_name }} --nic port-id={{ item[0].stdout }} --user-data {{ user_dir }}/pass_auth.sh {{ item[1] }} + with_together: + - "{{ port_ids.results }}" + - "{{ vm_names }}" + ignore_errors: yes + +- name: create a vm's + shell: . {{ overcloudrc }}; openstack server create --flavor pbench_flavor --image {{ guest_image_name }} --nic port-id={{ item[0].stdout }} --user-data {{ user_dir }}/pass_auth.sh {{ item[1] }} + with_together: + - "{{ get_port_ids.results }}" + - "{{ vm_names }}" + ignore_errors: yes + + +- name: wait for vm to boot + wait_for: + timeout: "{{ timeout }}" diff --git a/install/roles/flavors/tasks/main.yml b/install/roles/flavors/tasks/main.yml new file mode 100644 index 00000000..aa187fa4 --- /dev/null +++ b/install/roles/flavors/tasks/main.yml @@ -0,0 +1,8 @@ +--- +# Add flavors to OpenStack Cloud +# Ignore errors here incase the flavors already exist. + +- name: Add flavors to overcloud + shell: . {{ overcloudrc }}; openstack flavor create --public {{ item.name }} --id auto --ram {{ item.ram }} --disk {{ item.disk }} --vcpus {{ item.cpu }} + with_items: "{{ pbench_flavors }}" + ignore_errors: true diff --git a/install/roles/flavors/vars/main.yml b/install/roles/flavors/vars/main.yml new file mode 100644 index 00000000..b6a04345 --- /dev/null +++ b/install/roles/flavors/vars/main.yml @@ -0,0 +1,7 @@ +--- +pbench_flavors: + - name: pbench_flavor + cpu: 8 + disk: 160 + ram: 16384 + diff --git a/install/roles/images/tasks/main.yml b/install/roles/images/tasks/main.yml new file mode 100644 index 00000000..16724010 --- /dev/null +++ b/install/roles/images/tasks/main.yml @@ -0,0 +1,43 @@ +--- +# Obtain/Upload guest_images to OpenStack Cloud + +- name: Fetch image centos7 + get_url: + url: "{{ guest_images[item].url_centos7 }}" + dest: "/home/stack/{{ guest_images[item].name }}.{{ guest_images[item].type }}" + with_items: "{{ guest_images }}" + when: ansible_distribution_major_version < '8' + +- name: Fetch image centos8 + get_url: + url: "{{ guest_images[item].url_centos8 }}" + dest: "/home/stack/{{ guest_images[item].name }}.{{ guest_images[item].type }}" + with_items: "{{ guest_images }}" + when: ansible_distribution_major_version == '8' + +- name: Determine if image exists + shell: . {{ overcloudrc }}; openstack image list | grep '{{ guest_images[item].name }}' + register: image_exists + ignore_errors: true + changed_when: false + with_items: "{{ guest_images }}" + +- name: Remove image from dictionary of images if image exists + set_fact: + guest_images: "{{ guest_images|dict_remove_item(item[0]) }}" + when: item[0] in item[1].stdout and + item[1] is defined + with_nested: + - "{{ guest_images }}" + - "{{ image_exists.results }}" + +- name: change the root password for qcow2 image + shell: | + export LIBGUESTFS_BACKEND=direct + virt-customize -a {{user_dir }}/{{ guest_images[item].name }}.{{ guest_images[item].type }} --root-password password:"{{ vm_password }}" + with_items: "{{ guest_images }}" + +- name: Upload image into cloud + shell: . {{ overcloudrc }}; openstack image create --public --disk-format={{ guest_images[item].type }} --container-format=bare {{ guest_images[item].name }} < {{ user_dir }}/{{ guest_images[item].name }}.{{ guest_images[item].type }} + ignore_errors: true + with_items: "{{ guest_images }}" diff --git a/install/roles/network/tasks/main.yml b/install/roles/network/tasks/main.yml new file mode 100644 index 00000000..f55d75f9 --- /dev/null +++ b/install/roles/network/tasks/main.yml @@ -0,0 +1,47 @@ +--- + +#Create a network, subnet, ports for client and server vms + +- name: Determine if network exists + shell: . {{ overcloudrc }}; openstack network list | grep '{{ network_name }}' + register: network_exists + ignore_errors: true + +- name: create a network + shell: . {{ overcloudrc }}; neutron net-create '{{ network_name }}' | egrep '\sid\s' | awk '{print $4}' + register: network_id + +- name: get dns server + shell: | + cat /etc/resolv.conf | grep nameserver | head -n1 | cut -d ' ' -f2 + register: dns_server + +- name: create subnet + shell: . {{ overcloudrc }}; neutron subnet-create --dns-nameserver {{ dns_server.stdout }} {{ network_id.stdout }} 10.0.0.0/24 + ignore_errors: yes + +- name: Determine if ports exists + shell: . {{ overcloudrc }}; openstack port list | grep '{{ item }}' + register: port_exists + with_items: "{{ ports }}" + ignore_errors: true + +- name: Create ports for client and server + shell: | + . {{ overcloudrc }} + openstack port create --no-security-group --disable-port-security --network {{ network_id.stdout }} {{ item.0 }} | egrep '\sid\s' | awk '{print $4}' + register: port_ids + when: item.1.stdout == "" + with_together: + - "{{ ports }}" + - "{{ port_exists.results }}" + +- name: get port ids for client and server + shell: | + . {{ overcloudrc }} + openstack port list | grep "{{ item.0 }}" | cut -d \| -f 2 | awk '{$1=$1;print}' + register: get_port_ids + when: item.1.stdout != "" + with_together: + - "{{ ports }}" + - "{{ port_exists.results }}" diff --git a/install/roles/network/vars/main.yml b/install/roles/network/vars/main.yml new file mode 100644 index 00000000..f23a46a7 --- /dev/null +++ b/install/roles/network/vars/main.yml @@ -0,0 +1,3 @@ +--- + +network_name: pbench_network diff --git a/install/templates/.pass_auth.sh.j2.swp b/install/templates/.pass_auth.sh.j2.swp new file mode 100644 index 00000000..49efbbcf Binary files /dev/null and b/install/templates/.pass_auth.sh.j2.swp differ diff --git a/install/templates/my.hosts.j2 b/install/templates/my.hosts.j2 new file mode 100644 index 00000000..4318aa50 --- /dev/null +++ b/install/templates/my.hosts.j2 @@ -0,0 +1,25 @@ +[vms] +{% for item in vm_names %} +{{ item }} +{% endfor %} + +{% if trafficgen_host is defined %} +[trafficgen_host] +{{ trafficgen_host.ip }} +{% endif %} + +[servers:children] +compute +vms +{% if trafficgen_host is defined %} +trafficgen_host +{% endif %} + +{% if pbench_agent_install|default(false) %} +[servers:vars] +# where to get the key +pbench_key_url = {{ pbench_key_url }} + +# where to get the config file +pbench_config_url = {{ pbench_config_url }} +{% endif %} diff --git a/install/templates/pass_auth.sh.j2 b/install/templates/pass_auth.sh.j2 new file mode 100644 index 00000000..826bc974 --- /dev/null +++ b/install/templates/pass_auth.sh.j2 @@ -0,0 +1,19 @@ +#!/bin/bash + +sed -i s/^PasswordAuthentication.*/PasswordAuthentication\ yes/ /etc/ssh/sshd_config +systemctl restart sshd +cat /etc/ssh/sshd_config +echo "Enabled PasswordAuthentication" +{% if ansible_distribution_major_version == '8' %} +sudo dnf clean all +sudo dnf install {{ epel_repo.el8 }} -y +sudo dnf module install -y python36 +sudo alternatives --set python /usr/bin/python3 +sudo dnf --enablerepo=PowerTools install perl-Data-UUID -y +{% endif %} +{% if ansible_distribution_major_version < '8' %} +sudo yum clean all +sudo yum install {{ epel_repo.el7 }} -y +sudo yum install centos-release-scl-rh -y +sudo yum install rh-python36-python -y +{% endif %} diff --git a/install/templates/pbench_agent_install.yml.j2 b/install/templates/pbench_agent_install.yml.j2 new file mode 100644 index 00000000..b41fa8fc --- /dev/null +++ b/install/templates/pbench_agent_install.yml.j2 @@ -0,0 +1,15 @@ +--- +- name: install pbench-agent + hosts: servers + become: yes + become_user: root + + # The default value ('production') can be overriddent by cenv, a host-specific + # inventory variable. + vars: + pbench_configuration_environment: "{{ cenv | default('production') }}" + + roles: + - pbench_repo_install + - pbench_agent_install + - pbench_agent_config diff --git a/install/templates/repo_bootstrap.hosts.j2 b/install/templates/repo_bootstrap.hosts.j2 new file mode 100644 index 00000000..707ac930 --- /dev/null +++ b/install/templates/repo_bootstrap.hosts.j2 @@ -0,0 +1,14 @@ +[servers] + +{% if (pbench_agent_install is defined) or pbench_image_rhel %} +{% for item in vms_fip.results %} +{{ item.stdout }} +{% endfor %} +{% endif %} +{% for item in computes_ip.stdout_lines%} +{{ item }} +{% endfor %} + +{% if trafficgen_host is defined %} +{{ trafficgen_host.ip }} +{% endif %}