diff --git a/cdist/conf/type/__sensible_editor/explorer/editor_path b/cdist/conf/type/__sensible_editor/explorer/editor_path new file mode 100644 index 00000000..dcf63c9b --- /dev/null +++ b/cdist/conf/type/__sensible_editor/explorer/editor_path @@ -0,0 +1,131 @@ +#!/bin/sh -e +# +# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Check if the given editor is present on the target system and determine its +# absolute path. +# + +die() { + echo "$@" >&2 + exit 1 +} + +editor_missing() { die "Editor '$1' is missing on the target system."; } +editor_no_alternative() { + die "Editor '$1' is not in the alternatives list of the target system." \ + "$(test -n "${editors}" && printf '\nPlease choose one of:\n\n%s\n' "${editors}")" +} + +# No need to check for the path if the file is supposed to be removed. +test "$(cat "${__object}/parameter/state")" != 'absent' || exit 0 + + +case $("${__explorer}/os") +in + debian|devuan|ubuntu) + has_alternatives=true + + # NOTE: Old versions do not support `--list`, in this case ignore the errors. + # This will require an absolute path to be provided, though. + editors=$(update-alternatives --list editor 2>/dev/null) + ;; + *) + # NOTE: RedHat has an alternatives system but it doesn't usually track + # editors and it is a pain to extract the list. + has_alternatives=false + ;; +esac + +# Read --editor parameter and check its value since it is "optional" +editor=$(cat "${__object}/parameter/editor" 2>/dev/null) || true +test -n "${editor}" || die 'Please provide an --editor to configure.' + +case $editor +in + /*) + is_abspath=true + ;; + */*) + die 'Relative editor paths are not supported' + ;; + *) + is_abspath=false + ;; +esac + + +if $has_alternatives && test -n "${editors}" +then + IFS=' +' + if ! $is_abspath + then + # First, try to resolve the absolute path using $editors. + while true + do + for e in $editors + do + if test "$(basename "${e}")" = "${editor}" + then + editor="${e}" + break 2 # break out of both loops + fi + done + + # Iterating through alternatives did not yield a result + editor_no_alternative "${editor}" + break + done + fi + + # Check if editor is present + test -f "${editor}" || editor_missing "${editor}" + + for e in $editors + do + if test "${editor}" = "${e}" + then + # Editor is part of the alternatives list -> use it! + echo "${editor}" + exit 0 + fi + done + + editor_no_alternative "${editor}" +else + # NOTE: This branch is mostly for RedHat-based systems which do + # not track editor alternatives. To make this type useful + # on RedHat at all we allow an absoloute path to be provided + # in any case. + + if $is_abspath + then + test -x "${editor}" || editor_missing "${editor}" + + echo "${editor}" + exit 0 + else + die "The target doesn't list any editor alternatives. " \ + "Please specify an absolute path or populate the alternatives list." + fi +fi + +# The script should never reach this statement! +exit 1 diff --git a/cdist/conf/type/__sensible_editor/explorer/group b/cdist/conf/type/__sensible_editor/explorer/group new file mode 100644 index 00000000..5d288189 --- /dev/null +++ b/cdist/conf/type/__sensible_editor/explorer/group @@ -0,0 +1,26 @@ +#!/bin/sh -e +# +# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Determines the primary group of the user. +# + +user=$__object_id + +id -gn "${user}" 2>/dev/null diff --git a/cdist/conf/type/__sensible_editor/explorer/user_home b/cdist/conf/type/__sensible_editor/explorer/user_home new file mode 100644 index 00000000..b88243f7 --- /dev/null +++ b/cdist/conf/type/__sensible_editor/explorer/user_home @@ -0,0 +1,33 @@ +#!/bin/sh -e +# +# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Determines the home folder of the target user. +# + +user=$__object_id +home=$(getent passwd "${user}" | cut -d':' -f6) + +if ! test -d "${home}" +then + echo "Cannot find home directory of user ${user}" >&2 + exit 1 +fi + +echo "${home}" diff --git a/cdist/conf/type/__sensible_editor/man.rst b/cdist/conf/type/__sensible_editor/man.rst new file mode 100644 index 00000000..9b805e06 --- /dev/null +++ b/cdist/conf/type/__sensible_editor/man.rst @@ -0,0 +1,78 @@ +cdist-type__sensible_editor(7) +============================== + +NAME +---- +cdist-type__sensible_editor - Select the sensible-editor + + +DESCRIPTION +----------- +This cdist type allows you to select the :strong:`sensible-editor` for +a given user. + + +REQUIRED PARAMETERS +------------------- +editor + Name or path of the editor to be selected. + On systems other than Debian derivatives an absolute path is required. + + It is permissible to omit this parameter if --state is absent. + + +OPTIONAL PARAMETERS +------------------- +state + 'present', 'absent', or 'exists'. Defaults to 'present', where: + + present + the sensible-editor is exactly what is specified in --editor. + absent + no sensible-editor configuration is present. + exists + the sensible-editor will be set to what is specified in --editor, + unless there already is a configuration on the target system. + + +EXAMPLES +-------- + +.. code-block:: sh + + __sensible_editor root --editor /bin/ed # ed(1) is the standard + __sensible_editor noob --editor nano + + +LIMITATIONS +----------- + +This type depends upon the :strong:`sensible-editor`\ (1) script which +is part of the sensible-utils package. + +Therefore, the following operating systems are supported: + * Debian 8 (jessie) or later + * Devuan + * Ubuntu 8.10 (intrepid) or later + * RHEL/CentOS 7 or later (EPEL repo required) + * Fedora 21 or later + +Note: on old versions of Ubuntu the sensible-* utils are part of the +debianutils package. + +SEE ALSO +-------- +:strong:`select-editor`\ (1), :strong:`sensible-editor`\ (1). + + +AUTHOR +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2019 Dennis Camera. +You can redistribute it and/or modify it under the terms of the GNU General +Public License as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. diff --git a/cdist/conf/type/__sensible_editor/manifest b/cdist/conf/type/__sensible_editor/manifest new file mode 100644 index 00000000..1cdb0c2c --- /dev/null +++ b/cdist/conf/type/__sensible_editor/manifest @@ -0,0 +1,94 @@ +#!/bin/sh -e +# -*- mode: sh; indent-tabs-mode: t -*- +# +# 2019 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +version_ge() { + awk -F '[^0-9.]' -v target="${1:?}" ' + function max(x, y) { return x > y ? x : y; } + BEGIN { + getline; + nx = split($1, x, "."); + ny = split(target, y, "."); + for (i = 1; i <= max(nx, ny); ++i) { + diff = int(x[i]) - int(y[i]); + if (diff < 0) exit 1; + else if (diff > 0) exit 0; + else continue; + } + }' +} + +not_supported() { + echo "OS ${os} does not support __sensible_editor." >&2 + echo 'If it does, please provide a patch.' >&2 + exit 1 +} + +os=$(cat "${__global}/explorer/os") +os_version=$(cat "${__global}/explorer/os_version") + +state=$(cat "${__object}/parameter/state") +user=$__object_id + +if test "${state}" != 'present' && test "${state}" != 'exists' && test "${state}" != 'absent' +then + echo 'Only "present", "exists", and "absent" are allowed for --state' >&2 + exit 1 +fi + +package_name='sensible-utils' + +case $os +in + debian) + pkg_type='apt' + ;; + devuan) + pkg_type='apt' + ;; + ubuntu) + (echo "${os_version}" | version_ge 10.04) || package_name='debianutils' + pkg_type='apt' + ;; + centos|fedora|redhat|scientific) + pkg_type='yum' + ;; + *) + not_supported + ;; +esac + +if test "${state}" != 'absent' +then + __package "${package_name}" --state present \ + --type "${pkg_type}" + export require="__package/${package_name}" +fi + +editor_path=$(cat "${__object}/explorer/editor_path") +user_home=$(cat "${__object}/explorer/user_home") +group=$(cat "${__object}/explorer/group") + +__file "${user_home}/.selected_editor" --state "${state}" \ + --owner "${user}" --group "${group}" --mode 0644 \ + --source - <