From d2afe55e8c1201d15d3e9ded46562e4f4d1774f3 Mon Sep 17 00:00:00 2001 From: Jon Pugh Date: Thu, 12 Nov 2020 07:00:28 -0500 Subject: [PATCH] Improve UID reset (#610) * Allow resetting UID/GID of the aegir user on ansible play runs. * Kill all tasks running of the user and chown everything to the new UID. * Separate user create and UID reset plays https://github.com/opendevshop/devshop/pull/610 --- roles/opendevshop.devmaster/defaults/main.yml | 1 - .../tasks/config-devmaster.yml | 2 +- roles/opendevshop.users/defaults/main.yml | 8 +++ roles/opendevshop.users/tasks/main.yml | 27 +-------- .../opendevshop.users/tasks/prepare-user.yml | 60 +++++++++++++++++++ roles/opendevshop.users/tasks/reset-uid.yml | 31 ++++++++++ 6 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 roles/opendevshop.users/tasks/prepare-user.yml create mode 100644 roles/opendevshop.users/tasks/reset-uid.yml diff --git a/roles/opendevshop.devmaster/defaults/main.yml b/roles/opendevshop.devmaster/defaults/main.yml index 4c792c81f5..92c9e0174d 100644 --- a/roles/opendevshop.devmaster/defaults/main.yml +++ b/roles/opendevshop.devmaster/defaults/main.yml @@ -104,7 +104,6 @@ ansible_become_method_aegir: sudo ansible_share_path: /usr/share/ansible # Server Options -php_memory_limit: "512M" # Get a support license at https://devshop.support devshop_support_license_key: "" diff --git a/roles/opendevshop.devmaster/tasks/config-devmaster.yml b/roles/opendevshop.devmaster/tasks/config-devmaster.yml index cfe032bf2e..25503566dd 100644 --- a/roles/opendevshop.devmaster/tasks/config-devmaster.yml +++ b/roles/opendevshop.devmaster/tasks/config-devmaster.yml @@ -1,5 +1,5 @@ --- -- name: DevShop Control | Clear all caches +- name: DevShop Control | Clear drush caches command: "{{ drush_bin_path }} cc drush" become: true become_user: "{{ aegir_user_name }}" diff --git a/roles/opendevshop.users/defaults/main.yml b/roles/opendevshop.users/defaults/main.yml index e63e9cef0b..5340f1a753 100644 --- a/roles/opendevshop.users/defaults/main.yml +++ b/roles/opendevshop.users/defaults/main.yml @@ -2,11 +2,19 @@ # defaults file for aegir.user aegir_user_uid: 12345 aegir_user_gid: 12345 + +# Set to TRUE to always incude the 'reset-uid.yml' task list, forcing a gid/uid reset each time. +aegir_user_force_set_uid: false + aegir_user_name: aegir aegir_user_home: /var/aegir aegir_user_authorized_keys: ReplaceAtRuntime aegir_logs_path: /var/log/aegir +# Populated in prepare-user.yml +aegir_user_uid_current: "{{ aegir_user_uid }}" +aegir_user_gid_current: "{{ aegir_user_gid }}" + # Used for the secondary install scripts for fix-perms and fix-ownership so far aegir_hosting_version: "7.x-3.170" diff --git a/roles/opendevshop.users/tasks/main.yml b/roles/opendevshop.users/tasks/main.yml index 81e2adddf1..b89787ac80 100644 --- a/roles/opendevshop.users/tasks/main.yml +++ b/roles/opendevshop.users/tasks/main.yml @@ -40,30 +40,9 @@ state: present enablerepo: "{{ devshop_prerequisite_enablerepo }}" -- name: Populate service facts - service_facts: - -- name: Create Aegir Group (so we can set the GID) - group: - name: "{{ aegir_user_name }}" - state: present - gid: "{{ aegir_user_gid }}" - -- name: Stop all processes running as aegir. - command: killall -u "{{ aegir_user_name }}" - ignore_errors: true - -- name: Create Aegir user - when: aegir_create_user - ignore_errors: true - user: - name: "{{ aegir_user_name }}" - shell: /bin/bash - group: "{{ aegir_user_name }}" - system: true - home: "{{ aegir_user_home }}" - generate_ssh_key: true - uid: "{{ aegir_user_uid }}" +- name: "Prepare System User" + include_tasks: "prepare-user.yml" + tags: [always] - name: Ensure /var/aegir is owned by aegir user. file: diff --git a/roles/opendevshop.users/tasks/prepare-user.yml b/roles/opendevshop.users/tasks/prepare-user.yml new file mode 100644 index 0000000000..e457ae07f8 --- /dev/null +++ b/roles/opendevshop.users/tasks/prepare-user.yml @@ -0,0 +1,60 @@ +--- +- name: Detect current Aegir user UID + getent: + database: passwd + key: "{{ aegir_user_name }}" + failed_when: false + +- name: Detect current Aegir user GID + getent: + database: group + key: "{{ aegir_user_name }}" + failed_when: false + +- name: Save variables for current user UID and GID + set_fact: + aegir_user_uid_current: "{{ getent_passwd[aegir_user_name][1] }}" + aegir_user_gid_current: "{{ getent_group[aegir_user_name][1] }}" + when: + - getent_passwd is defined + +- name: Current Aegir User UID & GID + debug: + msg: "UID: {{ aegir_user_uid_current }} GID: {{ aegir_user_gid_current }}" + when: + - getent_passwd is defined + +- name: Desired Aegir User UID & GID + debug: + msg: "UID: {{ aegir_user_uid }} GID: {{ aegir_user_gid }}" + when: + - getent_passwd is defined + +- name: Include Reset Aegir User tasks + include_tasks: "reset-uid.yml" + when: + (aegir_user_uid != aegir_user_uid_current) + or (aegir_user_gid != aegir_user_gid_current) + or (aegir_user_force_set_uid) + tags: [always] + +- name: Create Aegir Group (so we can set the GID) + group: + name: "{{ aegir_user_name }}" + state: present + gid: "{{ aegir_user_gid }}" + +- name: Populate service facts + service_facts: + +- name: Create Aegir user + when: + - aegir_create_user + user: + name: "{{ aegir_user_name }}" + shell: /bin/bash + group: "{{ aegir_user_name }}" + system: true + home: "{{ aegir_user_home }}" + generate_ssh_key: true + uid: "{{ aegir_user_uid }}" diff --git a/roles/opendevshop.users/tasks/reset-uid.yml b/roles/opendevshop.users/tasks/reset-uid.yml new file mode 100644 index 0000000000..b2158e19fe --- /dev/null +++ b/roles/opendevshop.users/tasks/reset-uid.yml @@ -0,0 +1,31 @@ +--- + +- name: "User ID Change: Stop supervisord" + service: + name: supervisord + state: stopped + +- name: "User ID Change: Find all user processes" + shell: "ps -ef | grep -v grep | grep -w {{ aegir_user_name }} | awk '{print $2}'" + register: running_processes + +- name: Aegir User Processes + debug: + var: running_processes + +- name: "User ID Change: Kill all user processes" + command: "kill {{ item }}" + ignore_errors: true + with_items: "{{ running_processes.stdout_lines }}" + +- name: "User ID Change: Wait for all processes to end" + wait_for: + path: "/proc/{{ item }}/status" + state: absent + with_items: "{{ running_processes.stdout_lines }}" + ignore_errors: true + register: killed_processes + +- name: "User ID Change: Force stop stuck processes" + command: "kill -9 {{ item }}" + with_items: "{{ killed_processes.results | select('failed') | map(attribute='item') | list }}"