From b52e242218d779bd7b45ffae59112ec580c94f6b Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Wed, 30 May 2018 08:58:42 -0500 Subject: [PATCH 1/6] [fix] Stop readline on success Previous code was blocking on stdout after subprocess completed with success, as `poll()` would return 0, and `not 0` is true. --- chi-appliance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chi-appliance.py b/chi-appliance.py index 9783954..39d48a0 100755 --- a/chi-appliance.py +++ b/chi-appliance.py @@ -190,7 +190,7 @@ def do_configure(argv): universal_newlines=True) while True: err = proc.poll() - if not err: + if err is None: print(proc.stdout.readline(), end='', flush=True) else: if err == 0: -- GitLab From 8db9d2cc7ef41103bf75457771e1d849090486d4 Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Wed, 30 May 2018 09:01:35 -0500 Subject: [PATCH 2/6] [refactor] use ansible playbook standard layout Ansible recommend a specific directory layout to deal with complex playbooks. As we expect this configuration to become trickier, let's adopt good practices right away. --- ansible/main.yaml | 11 ++--------- ansible/roles/common/tasks/main.yaml | 7 +++++++ 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 ansible/roles/common/tasks/main.yaml diff --git a/ansible/main.yaml b/ansible/main.yaml index 3d75323..63b0553 100644 --- a/ansible/main.yaml +++ b/ansible/main.yaml @@ -1,11 +1,4 @@ --- - hosts: all - tasks: - - name: update etc/hosts - lineinfile: - dest: /etc/hosts - line: "{{ hostvars[item].ansible_host }} {{ hostvars[item].inventory_hostname }} {{ hostvars[item].inventory_hostname_short }}" - state: present - with_items: "{{ groups.all }}" - become: yes - + roles: + - common diff --git a/ansible/roles/common/tasks/main.yaml b/ansible/roles/common/tasks/main.yaml new file mode 100644 index 0000000..601e634 --- /dev/null +++ b/ansible/roles/common/tasks/main.yaml @@ -0,0 +1,7 @@ + - name: update etc/hosts + lineinfile: + dest: /etc/hosts + line: "{{ hostvars[item].ansible_host }} {{ hostvars[item].inventory_hostname }} {{ hostvars[item].inventory_hostname_short }}" + state: present + with_items: "{{ groups.all }}" + become: yes -- GitLab From 76694f1e767cdbfbebaf2aea36d28618ca4ef420 Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Wed, 30 May 2018 09:14:07 -0500 Subject: [PATCH 3/6] [feature] make wait optional on create/delete Stack create and delete take an option to wait for the operation to complete. It doesn't actually wait for the operation to complete, just for the Openstack side of it to be done. For creation for exemple, the nodes might still be booting. --- chi-appliance.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/chi-appliance.py b/chi-appliance.py index 39d48a0..f6b3b3b 100755 --- a/chi-appliance.py +++ b/chi-appliance.py @@ -51,7 +51,7 @@ def do_create(argv): template = os.path.abspath(argv.template) try: ret = shade_client.create_stack(argv.name, template_file=template, - wait=True, **extra_args) + wait=argv.wait, **extra_args) print(json.dumps(ret, indent=4)) except shade.exc.OpenStackCloudHTTPError as e: print(e) @@ -60,7 +60,7 @@ def do_create(argv): def do_delete(argv): """Delete an appliance with .""" shade_client = get_shade_client(argv.region) - ret = shade_client.delete_stack(argv.name) + ret = shade_client.delete_stack(argv.name, wait=argv.wait) if ret: print("Appliance successfully deleted.") else: @@ -216,6 +216,8 @@ def main(): # create a lease parser_create = subparsers.add_parser("create", help="Create an appliance") + parser_create.add_argument("--wait", action='store_true', + help="Wait for the operation to complete") parser_create.add_argument("name", help="Name of the appliance") parser_create.add_argument("lease", help="Lease for the appliance") parser_create.add_argument("template", help="Appliance template") @@ -225,6 +227,8 @@ def main(): parser_create.set_defaults(func=do_create) parser_delete = subparsers.add_parser("delete", help="Delete an appliance") + parser_delete.add_argument("--wait", action='store_true', + help="Wait for the operation to complete") parser_delete.add_argument("name", help="Name of the appliance") parser_delete.set_defaults(func=do_delete) -- GitLab From c3308df5785994b7cf7f8855cbd4dfd7659222d0 Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Wed, 30 May 2018 11:05:34 -0500 Subject: [PATCH 4/6] [feature] wait for frontend when configuring Ansible allows us to wait for the node to become available, which should allow us to launch the `configure` command as soon as `create --wait` completes. Uses default wait_for_connection module, which should poll for 10 minutes. Requires that we disable gather_fact, and reactivate it after the connection succeeds. --- chi-appliance.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/chi-appliance.py b/chi-appliance.py index f6b3b3b..ceab383 100755 --- a/chi-appliance.py +++ b/chi-appliance.py @@ -146,7 +146,12 @@ def do_configure(argv): confpath = os.path.join(mypath, 'ansible') playbook = ('---\n' '- hosts: all\n' + ' gather_facts: no\n' ' tasks:\n' + ' - name: Wait for frontend\n' + ' wait_for_connection:\n' + ' - name: Gather info about frontend\n' + ' setup:\n' ' - name: Ensure dependencies are installed\n' ' package:\n' ' name: "{{ item }}"\n' -- GitLab From ac4c713b0b12eec3fb53c2ba52de273d6ca27712 Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Thu, 7 Jun 2018 14:41:15 -0500 Subject: [PATCH 5/6] [feature] add playbook arg to configure Usefull for users that want to try a different set of roles. --- chi-appliance.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/chi-appliance.py b/chi-appliance.py index ceab383..a6812dd 100755 --- a/chi-appliance.py +++ b/chi-appliance.py @@ -144,6 +144,8 @@ def do_configure(argv): # local playbook mypath = os.path.abspath(os.path.dirname(__file__)) confpath = os.path.join(mypath, 'ansible') + # remove potential ./ansible/ from playbook path + playpath = os.path.split(argv.playbook)[1] playbook = ('---\n' '- hosts: all\n' ' gather_facts: no\n' @@ -162,7 +164,7 @@ def do_configure(argv): ' become: yes\n' ' - name: Copy ansible configuration to the frontend\n' ' synchronize:\n' - ' src: '+confpath+'\n' + ' src: ' + confpath + '\n' ' dest: ~/\n' ' - name: Generate ssh-key for appliance\n' ' user:\n' @@ -170,14 +172,14 @@ def do_configure(argv): ' state: present\n' ' generate_ssh_key: yes\n' ' - name: Execute ansible on frontend\n' - ' command: ansible-playbook -i inventory main.yaml\n' + ' shell: ' + ' ansible-playbook -i inventory.yaml ' + playpath + '\n' ' args:\n' ' chdir: ~/ansible\n' ' register: config\n' ' - debug: var=config.stdout_lines') # generate files - # BAD ERROR HANDLING HERE - remote_inv_path = "./ansible/inventory.yaml" + remote_inv_path = os.path.join(confpath, "inventory.yaml") local_temp = NamedTemporaryFile(mode='w+', encoding='utf8', delete=False) play_temp = NamedTemporaryFile(mode='w+', encoding='utf8', delete=False) with open(remote_inv_path, "w+", encoding='utf8') as remote_inv: @@ -247,6 +249,8 @@ def main(): parser_config = subparsers.add_parser("configure", help="Configure an appliance") parser_config.add_argument("name", help="Name of the appliance") + parser_config.add_argument("playbook", default="main.yaml", nargs='?', + help="Playbook for remote configuration") parser_config.set_defaults(func=do_configure) args = parser.parse_args() -- GitLab From e866ec7884b1571f4d690c2ecaa1de4c8b6d209a Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Thu, 7 Jun 2018 14:42:20 -0500 Subject: [PATCH 6/6] [fix] remove host key checks for ansible Until we figure out a way to add host keys to the config without trouble, disable host key checking when calling ansible. Not doing so could result in blocked calls, as ansible was asking questions during the run. --- chi-appliance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chi-appliance.py b/chi-appliance.py index a6812dd..26183e8 100755 --- a/chi-appliance.py +++ b/chi-appliance.py @@ -172,7 +172,7 @@ def do_configure(argv): ' state: present\n' ' generate_ssh_key: yes\n' ' - name: Execute ansible on frontend\n' - ' shell: ' + ' shell: ANSIBLE_HOST_KEY_CHECKING=False' ' ansible-playbook -i inventory.yaml ' + playpath + '\n' ' args:\n' ' chdir: ~/ansible\n' -- GitLab