ansible/node: Add tarball_common role
authorMartin Schwenke <martin@meltin.net>
Tue, 16 Jun 2020 09:09:34 +0000 (19:09 +1000)
committerMartin Schwenke <martin@meltin.net>
Thu, 13 Aug 2020 00:55:08 +0000 (10:55 +1000)
Given a source tarball:

* build a binary tarball
* install binary tarball
* setup binary install for AD node
* setup binary install for NAS node

Signed-off-by: Martin Schwenke <martin@meltin.net>
ansible/node/roles/tarball_common/files/ctdb-script.options [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/build_samba.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/build_samba_maybe.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/install_ad.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/install_ctdb.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/install_samba.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/tasks/unpack_binary.yml [new file with mode: 0644]
ansible/node/roles/tarball_common/templates/ctdb-service.j2 [new file with mode: 0644]
ansible/node/roles/tarball_common/templates/etc-profile.j2 [new file with mode: 0644]
ansible/node/roles/tarball_common/vars/main.yml [new file with mode: 0644]

diff --git a/ansible/node/roles/tarball_common/files/ctdb-script.options b/ansible/node/roles/tarball_common/files/ctdb-script.options
new file mode 100644 (file)
index 0000000..ad6e068
--- /dev/null
@@ -0,0 +1 @@
+. /etc/profile.d/autocluster_samba.sh
diff --git a/ansible/node/roles/tarball_common/tasks/build_samba.yml b/ansible/node/roles/tarball_common/tasks/build_samba.yml
new file mode 100644 (file)
index 0000000..01c896a
--- /dev/null
@@ -0,0 +1,123 @@
+---
+- name: unpack source tarball
+  unarchive:
+    src:  "{{ source_tarball }}"
+    dest: /root
+    remote_src: True
+    creates: "{{ source_dir }}"
+
+- name: build directory
+  file:
+    path: "{{ build_dir }}"
+    state: directory
+
+- name: build flags directory
+  file:
+    path: "{{ build_flags_dir }}"
+    state: directory
+
+- name: check for bootstrap script
+  stat:
+    path: "{{ bootstrap_path }}"
+  register: p
+
+- fail: msg="No bootstrap file found for platform '{{ bootstrap_platform }}'"
+  when: p.stat.executable is undefined or not p.stat.executable
+
+- name: install build dependencies
+  shell: >
+    {{ bootstrap_path | quote }} >{{ bootstrap_log }} 2>&1 && \
+    touch {{ bootstrap_ok }}
+  args:
+    chdir: "{{ source_dir }}"
+    creates: "{{ bootstrap_ok }}"
+
+# From this point be careful not to fail if a step fails.  This means
+# that if multiple builds are being done then a single build failure
+# does not stop subsequent builds from being attempted.  Build
+# failures are noticed by other steps because the binary tarball will
+# be missing.
+
+- name: configure Samba build
+  vars:
+    systemd_extra:
+      - Environment=KRB5CCNAME=FILE:{{ run_dir }}/krb5cc_samba
+      - NotifyAccess=all
+  shell: >
+    if ./buildtools/bin/waf configure \
+      --abi-check-disable \
+      --enable-selftest \
+      --with-cluster-support \
+      --enable-pmda \
+      --with-systemd \
+      --systemd-install-services \
+      --with-systemddir={{ systemd_dir }} \
+      --systemd-samba-extra='{{ systemd_extra[0] }}' \
+      --systemd-smb-extra='{{ systemd_extra[0] }}' \
+      --systemd-nmb-extra='{{ systemd_extra[0] }}' \
+      --systemd-winbind-extra='{{ systemd_extra[0] }}' \
+      --systemd-samba-extra='{{ systemd_extra[1] }}' \
+      --systemd-smb-extra='{{ systemd_extra[1] }}' \
+      --systemd-nmb-extra='{{ systemd_extra[1] }}' \
+      --systemd-winbind-extra='{{ systemd_extra[1] }}' \
+      --prefix={{ tarball_install_prefix }} >{{ configure_log }} 2>&1 ; then \
+      touch {{ configure_ok }} ; \
+    fi
+  args:
+    chdir: "{{ source_dir }}"
+    creates: "{{ configure_ok }}"
+
+- name: check for configure_ok
+  stat:
+    path: "{{ configure_ok }}"
+  register: p
+
+- name: build Samba
+  shell: >
+    if make -j >{{ build_log }} 2>&1 ; then \
+      touch {{ build_ok }} ; \
+    fi
+  args:
+    chdir: "{{ source_dir }}"
+    creates: "{{ build_ok }}"
+  when: p.stat.exists
+
+- name: check for build_ok
+  stat:
+    path: "{{ build_ok }}"
+  register: p
+
+- name: install Samba
+  shell: >
+    if make -j install >{{ install_log }} 2>&1 ; then \
+      touch {{ install_ok }} ; \
+    fi
+  args:
+    chdir: "{{ source_dir }}"
+    creates: "{{ install_ok }}"
+  when: p.stat.exists
+
+- name: check for install_ok
+  stat:
+    path: "{{ install_ok }}"
+  register: p
+
+- name: install Samba bootstrap script
+  shell: >
+    cp {{ bootstrap_path | quote }} {{ bootstrap_installed | quote }} && \
+    chmod +x {{ bootstrap_installed | quote }}
+  args:
+    chdir: "{{ source_dir }}"
+    creates: "{{ bootstrap_installed }}"
+  when: p.stat.exists
+
+- name: check for bootstrap_installed
+  stat:
+    path: "{{ bootstrap_installed }}"
+  register: p
+
+- name: create binary tarball
+  archive:
+    dest: "{{ binary_tarball }}"
+    path: "{{ tarball_install_prefix }}"
+  when: p.stat.exists
diff --git a/ansible/node/roles/tarball_common/tasks/build_samba_maybe.yml b/ansible/node/roles/tarball_common/tasks/build_samba_maybe.yml
new file mode 100644 (file)
index 0000000..7389612
--- /dev/null
@@ -0,0 +1,31 @@
+---
+- name: fail if source_tarball variable is not set
+  fail: msg="Variable 'source_tarball' is not set"
+  when: source_tarball is undefined or source_tarball == 'null'
+
+- debug:
+    msg: source tarball is {{ source_tarball }}
+
+- name: check for binary tarball
+  stat:
+    path: "{{ binary_tarball }}"
+  register: p
+
+- name: build Samba tarball
+  include_tasks: build_samba.yml
+  when: not p.stat.exists
+
+#
+# These will not be needed if the tarball exists, so clean them up to
+# avoid this node running out of disk space...
+#
+
+- name: uninstall
+  file:
+    path: "{{ tarball_install_prefix }}"
+    state: absent
+
+- name: clean up source directory
+  file:
+    path: "{{ source_dir }}"
+    state: absent
diff --git a/ansible/node/roles/tarball_common/tasks/install_ad.yml b/ansible/node/roles/tarball_common/tasks/install_ad.yml
new file mode 100644 (file)
index 0000000..9b11c75
--- /dev/null
@@ -0,0 +1,13 @@
+---
+- name: install Samba binary tarball
+  include_tasks: unpack_binary.yml
+
+- name: link to systemd service file
+  file:
+    src: "{{ systemd_dir }}/samba.service"
+    dest: /usr/lib/systemd/system/samba.service
+    state: link
+
+- name: force systemd to reread configs
+  systemd:
+    daemon_reload: yes
diff --git a/ansible/node/roles/tarball_common/tasks/install_ctdb.yml b/ansible/node/roles/tarball_common/tasks/install_ctdb.yml
new file mode 100644 (file)
index 0000000..31a740a
--- /dev/null
@@ -0,0 +1,20 @@
+---
+- name: install Samba binary tarball
+  include_tasks: unpack_binary.yml
+
+# Temporary until CTDB uses --systemd-install-services to install
+# ctdb/config/ctdb.service automatically
+- name: generate CTDB systemd service file
+  template:
+    src: ctdb-service.j2
+    dest: /usr/lib/systemd/system/ctdb.service
+
+# There seems no sane way to tell systemd to add to $PATH  :-(
+- name: generate script.options to hack PATH
+  copy:
+    src: ctdb-script.options
+    dest: "{{ tarball_install_prefix }}/etc/ctdb/script.options"
+
+- name: force systemd to reread configs
+  systemd:
+    daemon_reload: yes
diff --git a/ansible/node/roles/tarball_common/tasks/install_samba.yml b/ansible/node/roles/tarball_common/tasks/install_samba.yml
new file mode 100644 (file)
index 0000000..889bd42
--- /dev/null
@@ -0,0 +1,42 @@
+---
+- name: install Samba binary tarball
+  include_tasks: unpack_binary.yml
+
+- name: link to systemd service files
+  file:
+    src: "{{ systemd_dir }}/{{ service }}.service"
+    dest: /usr/lib/systemd/system/{{ service }}.service
+    state: link
+  loop:
+    - smb
+    - nmb
+    - winbind
+  loop_control:
+    loop_var: service
+
+- name: force systemd to reread configs
+  systemd:
+    daemon_reload: yes
+
+- name: pam_winbind link
+  file:
+    src: "{{ tarball_install_prefix }}/lib/security/pam_winbind.so"
+    dest: /usr/lib64/security/pam_winbind.so
+    state: link
+
+- name: libnss_winbind link
+  file:
+    src: "{{ tarball_install_prefix }}/lib/libnss_winbind.so.2"
+    dest: /usr/lib64/libnss_winbind.so.2
+    state: link
+
+- name: ensure Samba does not autostart
+  service:
+    name: "{{ service }}"
+    enabled: no
+  loop:
+    - smb
+    - nmb
+    - winbind
+  loop_control:
+    loop_var: service
diff --git a/ansible/node/roles/tarball_common/tasks/unpack_binary.yml b/ansible/node/roles/tarball_common/tasks/unpack_binary.yml
new file mode 100644 (file)
index 0000000..37a4e28
--- /dev/null
@@ -0,0 +1,27 @@
+---
+- name: unpack binary tarball
+  unarchive:
+    src:  "{{ binary_tarball }}"
+    dest: "{{ tarball_install_prefix | realpath | dirname }}"
+    remote_src: True
+    creates: "{{ tarball_install_prefix }}"
+
+- name: setup path
+  template:
+    src: etc-profile.j2
+    dest: /etc/profile.d/autocluster_samba.sh
+
+- name: install directory
+  file:
+    path: "{{ install_dir }}"
+    state: directory
+
+# Yes, this is complete overkill because it installs development
+# packages.  However, it is a zero-effort method of ensuring that all
+# run-time dependencies are installed...
+- name: run Samba bootstrap script
+  shell: >
+    {{ bootstrap_installed | quote }} >{{ install_bootstrap_log }} 2>&1 && \
+    touch {{ install_bootstrap_ok }}
+  args:
+    creates: "{{ install_bootstrap_ok }}"
diff --git a/ansible/node/roles/tarball_common/templates/ctdb-service.j2 b/ansible/node/roles/tarball_common/templates/ctdb-service.j2
new file mode 100644 (file)
index 0000000..ede5d31
--- /dev/null
@@ -0,0 +1,19 @@
+[Unit]
+Description=CTDB
+Documentation=man:ctdbd(1) man:ctdb(7)
+After=network-online.target time-sync.target
+ConditionFileNotEmpty={{ tarball_install_prefix }}/etc/ctdb/nodes
+
+[Service]
+Type=forking
+LimitCORE=infinity
+LimitNOFILE=1048576
+TasksMax=4096
+PIDFile={{ tarball_install_prefix }}/var/run/ctdb/ctdbd.pid
+ExecStart={{ tarball_install_prefix }}/sbin/ctdbd_wrapper start
+ExecStop={{ tarball_install_prefix }}/sbin/ctdbd_wrapper stop
+KillMode=control-group
+Restart=no
+
+[Install]
+WantedBy=multi-user.target
diff --git a/ansible/node/roles/tarball_common/templates/etc-profile.j2 b/ansible/node/roles/tarball_common/templates/etc-profile.j2
new file mode 100644 (file)
index 0000000..cace328
--- /dev/null
@@ -0,0 +1,3 @@
+# Autocluster: add Samba binary install sbin/ and bin/ to PATH
+PATH="{{ tarball_install_prefix }}/sbin:${PATH}"
+PATH="{{ tarball_install_prefix }}/bin:${PATH}"
diff --git a/ansible/node/roles/tarball_common/vars/main.yml b/ansible/node/roles/tarball_common/vars/main.yml
new file mode 100644 (file)
index 0000000..9d7553e
--- /dev/null
@@ -0,0 +1,50 @@
+---
+
+source_base: "{{ source_tarball | basename | replace('.tar.gz', '') }}"
+
+source_dir: /root/{{ source_base }}
+
+bootstrap_distro: "{{ ansible_distribution | lower }}"
+
+# FIXME: This won't work for Ubuntu where
+# ansible_distribution_major_version is a meaningless number like 18,
+# rather than the full version string of a particular release.
+bootstrap_version: "{{ ansible_distribution_major_version }}"
+
+bootstrap_platform: "{{ bootstrap_distro }}{{ bootstrap_version }}"
+
+bootstrap_path: >-
+  {{
+    source_dir
+  }}/bootstrap/generated-dists/{{
+    bootstrap_platform
+  }}/bootstrap.sh
+
+bootstrap_installed: "{{ tarball_install_prefix }}/bootstrap.sh"
+
+run_dir: "{{ tarball_install_prefix }}/var/run"
+systemd_dir: "{{ tarball_install_prefix }}/etc/systemd"
+
+tarball_dir: "{{ source_tarball | realpath | dirname }}"
+
+# These are per-build node
+build_flags_dir: "/root/.autocluster/build_flags/{{ source_base }}"
+bootstrap_ok: "{{ build_flags_dir }}/bootstrap.ok"
+configure_ok: "{{ build_flags_dir }}/configure.ok"
+build_ok: "{{ build_flags_dir }}/build.ok"
+install_ok: "{{ build_flags_dir }}/install.ok"
+
+# These are per-build.  Keep the logs for the last (attempted) build.
+build_dir: "{{ tarball_dir }}/{{ source_base }}.build"
+bootstrap_log: "{{ build_dir }}/bootstrap.log"
+configure_log: "{{ build_dir }}/configure.log"
+build_log: "{{ build_dir }}/build.log"
+install_log: "{{ build_dir }}/install.log"
+binary_tarball: "{{ build_dir }}/binary.tar.gz"
+
+# Per node installation
+install_bootstrap_ok: "/root/.autocluster/bootstrap.ok"
+
+# Per node installation.  Keep the logs for the last (attempted) install.
+install_dir: "{{ tarball_dir }}/{{ source_base }}.install.{{ ansible_hostname }}"
+install_bootstrap_log: "{{ install_dir }}/bootstrap.log"