Evilham
d5b552ddb4
With these changes the type is good for general consumption (modulo the limitations mentioned in the manpage under TODO).
193 lines
5.7 KiB
Bash
Executable file
193 lines
5.7 KiB
Bash
Executable file
#!/bin/sh -e
|
|
|
|
BIN_DIR="/usr/local/bin"
|
|
ETC_DIR="/etc"
|
|
|
|
# Ensure the target bin dir exists
|
|
# Care, we never want to remove it :-D
|
|
__directory "${BIN_DIR}" \
|
|
--state "exists" \
|
|
--mode 0755
|
|
export require="${require} __directory${BIN_DIR}"
|
|
|
|
STATE="$(cat "${__object}/parameter/state")"
|
|
USER="$(cat "${__object}/parameter/user")"
|
|
GROUP="$(cat "${__object}/parameter/group" 2>/dev/null || true)"
|
|
if [ -z "${GROUP}" ]; then
|
|
GROUP="${USER}"
|
|
fi
|
|
|
|
SERVICE_NAME="${__object_id}"
|
|
|
|
BINARY="$(cat "${__object}/parameter/binary" 2>/dev/null || true)"
|
|
if [ -z "${BINARY}" ]; then
|
|
BINARY="${SERVICE_NAME}"
|
|
fi
|
|
EXTRA_BINARIES="$(cat "${__object}/parameter/extra-binary" 2>/dev/null || true)"
|
|
# This only makes sense for file archives
|
|
if [ -n "${EXTRA_BINARIES}" ] && [ -f "${__object}/parameter/unpack" ]; then
|
|
cat >> /dev/stderr <<-EOF
|
|
You cannot specify extra binaries without the --unpack argument.
|
|
Make sure that the --url argument points to a file archive.
|
|
EOF
|
|
fi
|
|
|
|
SERVICE_EXEC="$(cat "${__object}/parameter/service-exec" 2>/dev/null || true)"
|
|
if [ -z "${SERVICE_EXEC}" ]; then
|
|
SERVICE_EXEC="${BIN_DIR}/${BINARY}"
|
|
fi
|
|
SERVICE_EXEC="${SERVICE_EXEC} $(cat "${__object}/parameter/service-args")"
|
|
|
|
SERVICE_DESCRIPTION="$(cat "${__object}/parameter/service-description" \
|
|
2>/dev/null || true)"
|
|
if [ -z "${SERVICE_DESCRIPTION}" ]; then
|
|
SERVICE_DESCRIPTION="cdist-managed '${SERVICE_NAME}' service"
|
|
fi
|
|
|
|
DOWNLOAD_URL="$(cat "${__object}/parameter/url")"
|
|
CHECKSUM="$(cat "${__object}/parameter/checksum")"
|
|
SHOULD_VERSION="$(cat "${__object}/parameter/version")"
|
|
|
|
# Create a user for the service if it is not root
|
|
if [ "${USER}" != "root" ] && \
|
|
[ ! -f "${__object}/parameter/do-not-manage-user" ]; then
|
|
if [ "${STATE}" = "absent" ]; then
|
|
# When removing, ensure user is not being used
|
|
user_require="__systemd_unit/${SERVICE_NAME}.service"
|
|
fi
|
|
require="${require} ${user_require}" __user "${USER}" \
|
|
--system \
|
|
--state "${STATE}" \
|
|
--home /nonexistent \
|
|
--comment "cdist-managed ${SERVICE_NAME} user"
|
|
# Track dependencies
|
|
service_require="${service_require} __user/${USER}"
|
|
fi
|
|
|
|
# Place config file if necessary
|
|
CONFIG_FILE_DEST="${ETC_DIR}/${SERVICE_NAME}.conf"
|
|
CONFIG_FILE_SOURCE="$(cat "${__object}/parameter/config-file-source" 2>/dev/null || true)"
|
|
if [ "${CONFIG_FILE_SOURCE}" = "-" ]; then
|
|
CONFIG_FILE_SOURCE="${__object}/stdin"
|
|
fi
|
|
if [ -n "${CONFIG_FILE_SOURCE}" ] && [ "${STATE}" = "present" ]; then
|
|
require="${require} __user/${USER}" __file \
|
|
"${CONFIG_FILE_DEST}" \
|
|
--owner "${USER}" \
|
|
--group "${GROUP}" \
|
|
--mode "0440" \
|
|
--source "${CONFIG_FILE_SOURCE}"
|
|
service_required="${service_required} __file${CONFIG_FILE_DEST}"
|
|
fi
|
|
|
|
|
|
|
|
# TODO: Support non-systemd
|
|
__systemd_unit "${SERVICE_NAME}.service" \
|
|
--source "-" \
|
|
--state "${STATE}" \
|
|
--restart \
|
|
--enablement-state "enabled" <<EOF
|
|
[Unit]
|
|
Description=${SERVICE_DESCRIPTION}
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
|
|
User=${USER}
|
|
Group=${GROUP}
|
|
ExecStart=${SERVICE_EXEC}
|
|
Restart=always
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
service_require="${service_require} __systemd_unit/${SERVICE_NAME}.service"
|
|
|
|
# Proceed after user and service description have been prepared
|
|
export require="${require} ${service_require}"
|
|
|
|
# Perform a service restart if config has changed
|
|
if [ "${STATE}" = "present" ]; then
|
|
__check_messages "${SERVICE_NAME}_config" \
|
|
--pattern "^__file${CONFIG_FILE_DEST}" \
|
|
--execute "service ${SERVICE_NAME} restart"
|
|
fi
|
|
|
|
VERSION_FILE="${BIN_DIR}/.${SERVICE_NAME}.cdist.version"
|
|
IS_VERSION="$(cat "${__object}/explorer/explorer-version")"
|
|
|
|
if [ "${SHOULD_VERSION}" != "${IS_VERSION}" ] && \
|
|
[ "${STATE}" = "present" ]; then
|
|
# We are installing the service and there has been a version change
|
|
# (or it is first-time install)
|
|
TMP_PATH="/tmp/${SERVICE_NAME}-${SHOULD_VERSION}"
|
|
|
|
# This is what will stop the service, replace the binaries and
|
|
# start the service again
|
|
perform_service_upgrade="$(cat <<EOF
|
|
service ${SERVICE_NAME} stop || true
|
|
for bin_file in ${BINARY} ${EXTRA_BINARIES}; do
|
|
bin_path="${TMP_PATH}/\${bin_file}"
|
|
# TODO: on the BSDs, the super user group is wheel
|
|
chown root:root "\${bin_path}"
|
|
chmod 0555 "\${bin_path}"
|
|
cp -af "\${bin_path}" "${BIN_DIR}/\${bin_file}"
|
|
done
|
|
service ${SERVICE_NAME} start || true
|
|
EOF
|
|
)"
|
|
|
|
if [ -f "${__object}/parameter/unpack" ]; then
|
|
# TODO: Support files other than .tar.gz
|
|
UNPACK_ARGS="$(cat "${__object}/parameter/unpack-args" \
|
|
2>/dev/null || true)"
|
|
# Download packed file
|
|
__download "${TMP_PATH}.tar.gz" \
|
|
--url "${DOWNLOAD_URL}" \
|
|
--download remote \
|
|
--sum "${CHECKSUM}"
|
|
|
|
# Unpack file and also perform service upgrade
|
|
# shellcheck disable=SC2086
|
|
require="__download${TMP_PATH}.tar.gz" \
|
|
__unpack "${TMP_PATH}.tar.gz" \
|
|
${UNPACK_ARGS} \
|
|
--destination "${TMP_PATH}" \
|
|
--onchange "$(cat <<EOF
|
|
${perform_service_upgrade}
|
|
EOF
|
|
)"
|
|
version_bump_require="__unpack${TMP_PATH}.tar.gz"
|
|
else
|
|
# Create temp directory
|
|
__directory "${TMP_PATH}"
|
|
# Download binary directoy to the temp directory with the
|
|
# specified binary name
|
|
# And also perform service upgrade
|
|
require="__directory${TMP_PATH}" __download \
|
|
"${TMP_PATH}/${BINARY}" \
|
|
--url "${DOWNLOAD_URL}" \
|
|
--download remote \
|
|
--sum "${CHECKSUM}" \
|
|
--onchange "${perform_service_upgrade}"
|
|
version_bump_require="__download${TMP_PATH}/${BINARY}"
|
|
fi
|
|
|
|
# Perform update of cdist-managed version file
|
|
# only after binaries have been upgraded
|
|
printf "%s" "${SHOULD_VERSION}" | \
|
|
require="${version_bump_require}" __file \
|
|
"${VERSION_FILE}" \
|
|
--source "-"
|
|
fi
|
|
|
|
if [ "${STATE}" = "absent" ]; then
|
|
# Perform cleanup of generated files
|
|
for bin_file in ${BINARY} ${EXTRA_BINARIES}; do
|
|
__file "${BINARY_PREFIX}/${bin_file}" --state "absent"
|
|
done
|
|
__file "${VERSION_FILE}" --state "absent"
|
|
__file "${CONFIG_FILE_DEST}" --state "absent"
|
|
fi
|