From 353bf8ffd3cc7c17c3656c8c60ade3025dbc1550 Mon Sep 17 00:00:00 2001 From: Russell Bunch Date: Fri, 3 May 2024 10:07:34 -0500 Subject: [PATCH] MTL-2300 Crucible self-update service Add a service for self-updating crucible. When enabled/started, this new daemon will query, download, and install a newer crucible. Also creates `/etc/crucible` for holding system configuration files. --- crucible.spec | 28 ++++++++++++++++- crucible/scripts/install.sh | 9 ++++++ init/crucible-update.service | 39 +++++++++++++++++++++++ init/crucible-update.sh | 61 ++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 init/crucible-update.service create mode 100755 init/crucible-update.sh diff --git a/crucible.spec b/crucible.spec index 4191943..c6261bb 100644 --- a/crucible.spec +++ b/crucible.spec @@ -1,7 +1,7 @@ # # MIT License # -# (C) Copyright 2022-2023 Hewlett Packard Enterprise Development LP +# (C) Copyright 2023-2024 Hewlett Packard Enterprise Development LP # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -34,6 +34,7 @@ AutoReqProv: no BuildRequires: python-rpm-generators BuildRequires: python-rpm-macros +BuildRequires: pkgconfig(systemd) Requires: python%{python_version_nodots}-base Name: %(echo $NAME) BuildArch: %(echo $ARCH) @@ -45,6 +46,12 @@ Source: %{name}-%{version}.tar.bz2 Vendor: Hewlett Packard Enterprise Development LP Obsoletes: %{python_flavor}-%{name} +# helps when installing a program whose unit files makes use of a feature only available in a newer systemd version +# If the program is installed on its own, it will have to make do with the available features +# If a newer systemd package is planned to be installed in the same transaction as the program, +# it can be beneficial to have systemd installed first, so that the features have become available by the time program is installed and restarted +%{?systemd_ordering} + %description A Python application for managing block devices for use by an Operating system. @@ -75,6 +82,10 @@ sed -i 's:^#!.*$:#!%{install_dir}/bin/python:' %{buildroot}%{install_dir}/bin/%{ # Add the PoC mock files cp -pr poc-mocks %{buildroot}%{install_dir} +install -D -m 755 -d %{buildroot}%{_sysconfdir}/%{name} +install -D -m 0644 -t %{buildroot}%{_unitdir} init/%{name}-update.service +install -D -m 0755 -t %{buildroot}%{_sbindir} init/%{name}-update.sh + install -D -m 755 -d %{buildroot}%{_bindir} cp -pr scripts %{buildroot}%{install_dir}/ ln -snf %{install_dir}/scripts/lsnics.sh %{buildroot}%{_bindir}/lsnics @@ -86,14 +97,29 @@ install -m 644 %{name}/network/ifname.yml %{buildroot}%{conf_dir}/ifname.yml find %{buildroot}%{install_dir} | sed 's:'${RPM_BUILD_ROOT}'::' | tee -a INSTALLED_FILES cat INSTALLED_FILES | xargs -i sh -c 'test -f $RPM_BUILD_ROOT{} && echo {} || test -L $RPM_BUILD_ROOT{} && echo {} || echo %dir {}' | sort -u > FILES +%pre +%service_add_pre %{name}-update.service + +%post +%service_add_post %{name}-update.service + +%preun +%service_del_preun %{name}-update.service + +%postun +%service_del_postun %{name}-update.service + %clean %files -f FILES /usr/bin/%{name} /usr/bin/lsnics +%{_unitdir}/%{name}-update.service +%{_sbindir}/%{name}-update.sh %config(noreplace) %{conf_dir}/ifname.yml %doc README.adoc %defattr(755,root,root) +%dir %{_sysconfdir}/%{name} %license LICENSE %changelog diff --git a/crucible/scripts/install.sh b/crucible/scripts/install.sh index 09f9993..7a3e8de 100755 --- a/crucible/scripts/install.sh +++ b/crucible/scripts/install.sh @@ -372,6 +372,15 @@ _update_crucible() { else echo "Successfully updated crucible." fi + + if [ ! -d "${overlay_mount}/etc/crucible" ]; then + echo >&2 "${overlay_mount}/etc/crucible/ did not exist, it should, but it didn't. This script made it anyway because Russell is tired of silly breakages for his proof of concept." + echo >&2 "Maybe this script is being used with an older version of crucible that doesn't create the directory in its spec file yet." + mkdir -p "${overlay_mount}/etc/crucible" + fi + + # Disable auto-updating of crucible, since there's no management-vm to respond and we are already updating crucible in this script. + touch "${overlay_mount}/etc/crucible/auto-update.disabled" } ############################################################################## diff --git a/init/crucible-update.service b/init/crucible-update.service new file mode 100644 index 0000000..4709cf9 --- /dev/null +++ b/init/crucible-update.service @@ -0,0 +1,39 @@ +# +# MIT License +# +# (C) Copyright 2024 Hewlett Packard Enterprise Development LP +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +[Unit] +Description=Crucible automatic updater. +Requires=network-online.target +After=network-online.target + +[Service] +ExecCondition=/bin/bash -c '[ ! -f /etc/crucible/auto-update.disabled ]' +Environment=REPO_URL=http://bootserver/nexus/repository +ExecStart=/usr/lib64/crucible/bin/crucible-update.sh +Restart=on-failure +KillMode=control-group +RemainAfterExit=true +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/init/crucible-update.sh b/init/crucible-update.sh new file mode 100755 index 0000000..7ea600f --- /dev/null +++ b/init/crucible-update.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# MIT License +# +# (C) Copyright 2024 Hewlett Packard Enterprise Development LP +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +set -euo pipefail + +REPO_URL=${REPO_URL:-'http://bootserver/nexus/repository'} + +# Some distros (e.g. centos) use space delimited values in /etc/os-release for ID_LIKE, ensure we just grab +# the first entry. +OS="$(awk -F= '/ID_LIKE/{gsub("\"", ""); print $NF}' /etc/os-release | awk '{print $1}')" +if [ -z "${OS}" ]; then + echo >&2 'Failed to detect OS from /etc/os-release' + exit 1 +else + echo "Detected OS family: ${OS}" +fi + +function update { + echo 'Checking for crucible updates ... ' + case "${OS}" in + suse) + if ! zypper addrepo --gpgcheck-allow-unsigned "${REPO_URL}"'/fawkes-sle-${releasever_major}sp${releasever_minor}' fawkes-sle; then + echo "Repository already added, or unavailable." + fi + + if ! zypper addrepo --gpgcheck-allow-unsigned "${REPO_URL}/fawkes-noos" fawkes-noos; then + echo "Repository already added, or unavailable." + fi + + if ! zypper --no-gpg-checks up --no-confirm --auto-agree-with-licenses crucible; then + echo "No updates found, or no repository was reachable." + fi + ;; + *) + echo >&2 'Unhandled OS; nothing to do' + ;; + esac +} + +update diff --git a/pyproject.toml b/pyproject.toml index 4a8421f..36f8a11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ dependencies = [ 'click~=8.1', 'j2ipaddr~=1.0.6', 'jinja2~=3.1.2', + 'urwid~=2.5.2' ] dynamic = ['entry-points', 'scripts', 'version'] maintainers = [