diff --git a/Makefile b/Makefile index 10fa93f..072b824 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,10 @@ all: help help: @echo make '{deb|ipk|rpm}' '[PLUGINS="/dir/plg1 /dir/plg2] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."]' -deb: deb-clean deb-init deb-deps deb-control deb-postinst deb-cp deb-changelog deb-package +deb: deb-clean deb-init deb-deps deb-control deb-scripts deb-cp deb-package deb-clean: - rm -rf $(DEBIAN_DIR) $(DEBIAN_PKG) + @rm -rf $(DEBIAN_DIR) $(DEBIAN_PKG) deb-init: @mkdir -p tmp out $(DEBIAN_DIR) @@ -31,38 +31,44 @@ deb-control: done; \ zaf_far '{ZAF_VERSION}' "0.1" $(DEBIAN_CTRL)/control -deb-postinst: +deb-scripts: ifneq ($(PLUGINS),) - @echo -n "#!/bin/sh\nzaf install " >$(DEBIAN_CTRL)/postinst @. lib/zaf.lib.sh; \ . lib/ctrl.lib.sh; \ for p in $(PLUGINS); do \ - echo -n " "$$(zaf_ctrl_get_global_option $$p/control.zaf Plugin) ; \ - done >>$(DEBIAN_CTRL)/postinst - @echo >>$(DEBIAN_CTRL)/postinst + plugins="$$plugins "$$(zaf_ctrl_get_global_option $$p/control.zaf Plugin) ; \ + done; \ + cat files/postinst.template | zaf_far '{PLUGINS}' "$$plugins" | zaf_far '{ZAF_LIB_DIR}' "/usr/lib/zaf" >$(DEBIAN_CTRL)/postinst @chmod +x $(DEBIAN_CTRL)/postinst + @cp files/preinst.template $(DEBIAN_CTRL)/preinst + @chmod +x $(DEBIAN_CTRL)/preinst + @cp files/prerm.template $(DEBIAN_CTRL)/prerm + @chmod +x $(DEBIAN_CTRL)/prerm endif deb-cp: @mkdir -p $(DEBIAN_DIR) - INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=0 ./install.sh auto $(ZAF_OPTIONS) $(AGENT_OPTIONS) + @set -e; INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=0 ./install.sh auto $(ZAF_OPTIONS) $(AGENT_OPTIONS) @. lib/zaf.lib.sh; \ . lib/ctrl.lib.sh; \ for p in $(PLUGINS); do \ plugin=$$(zaf_ctrl_get_global_option $$p/control.zaf Plugin) ; \ - mkdir -p $(DEBIAN_DIR)/usr/lib/zaf/plugins/$$plugin/; \ - cp -R $$p/* $(DEBIAN_DIR)/usr/lib/zaf/plugins/$$plugin/; \ + mkdir -p $(DEBIAN_DIR)/usr/lib/zaf/prepackaged/$$plugin/; \ + cp -R $$p/* $(DEBIAN_DIR)/usr/lib/zaf/prepackaged/$$plugin/; \ done + @cat lib/*lib.sh install.sh >$(DEBIAN_DIR)/usr/lib/zaf/install.sh + @chmod +x $(DEBIAN_DIR)/usr/lib/zaf/install.sh @rm -rf $(DEBIAN_DIR)/tmp @cp $(DEBIAN_DIR)/etc/zaf.conf tmp/zaf.conf - grep -E "$$(echo $(ZAF_EXPORT_OPTS) | tr ' ' '|')=" tmp/zaf.conf >$(DEBIAN_DIR)/etc/zaf.conf + @grep -E "$$(echo $(ZAF_EXPORT_OPTS) | tr ' ' '|')=" tmp/zaf.conf >$(DEBIAN_DIR)/etc/zaf.conf + @echo "ZAF_PREPACKAGED_DIR=\"/usr/lib/zaf/prepackaged\"" >>$(DEBIAN_DIR)/etc/zaf.conf ifneq ($(AGENT_OPTIONS),) - echo "ZAF_AGENT_OPTIONS=\"$(AGENT_OPTIONS)\"" >>$(DEBIAN_DIR)/etc/zaf.conf + @echo "ZAF_AGENT_OPTIONS=\"$(AGENT_OPTIONS)\"" >>$(DEBIAN_DIR)/etc/zaf.conf endif deb-changelog: - @cp files/changelog.template debian/changelog + @cp files/changelog.template $(DEBIAN_CTRL)/changelog deb-package: - dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) + @dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) diff --git a/files/postinst.template b/files/postinst.template new file mode 100644 index 0000000..45e6060 --- /dev/null +++ b/files/postinst.template @@ -0,0 +1,16 @@ +#!/bin/sh + +case $1 in +configure) + if [ -f /usr/lib/zaf/install.sh ] && [ -f /etc/zaf.conf ] && [ -f /usr/lib/zaf/zaf.lib.sh ] && which zaf >/dev/null; then + . /etc/zaf.conf + . /usr/lib/zaf/zaf.lib.sh + . /usr/lib/zaf/os.lib.sh + . /usr/lib/zaf/ctrl.lib.sh + cd /usr/lib/zaf && /usr/lib/zaf/install.sh reconf + zaf reinstall {PLUGINS} + fi +;; +esac + + diff --git a/files/preinst.template b/files/preinst.template new file mode 100644 index 0000000..0a3971d --- /dev/null +++ b/files/preinst.template @@ -0,0 +1,10 @@ +#!/bin/sh + +case $1 in +install) + if [ -d /usr/lib/zaf ]; then + echo "Do zaf self-remove first! Cannot mix packaged and non-packaged version!" + exit 2 + fi + ;; +esac diff --git a/files/prerm.template b/files/prerm.template new file mode 100644 index 0000000..ea97185 --- /dev/null +++ b/files/prerm.template @@ -0,0 +1,7 @@ +#!/bin/sh + +case $1 in +remove) + rm -rf /usr/lib/zaf/plugins /usr/lib/zaf/repo + ;; +esac diff --git a/install.sh b/install.sh index fea45a5..c02c64c 100755 --- a/install.sh +++ b/install.sh @@ -1,21 +1,44 @@ #!/bin/sh -if ! [ "$(basename $0)" = "install.sh" ]; then - # We are runing from stdin - url="https://raw.githubusercontent.com/limosek/zaf/master/" +if [ -z "$ZAF_URL" ]; then + # Runing as standalone install.sh. We have to download rest of files first. + [ -z "$ZAF_VERSION" ] && ZAF_VERSION=master + ZAF_URL="https://github.com/limosek/zaf/" +fi + +# Lite version of zaf_fetch_url, full version will be loaded later +zaf_fetch_url(){ + if [ -z "$ZAF_OFFLINE" ]; then + echo curl -f -k -s -L -o - "$1" >&2; curl -f -k -s -L -o - "$1" + else + echo "Offline mode wants to download $1. Exiting." >&2 + exit 2 + fi +} + +# Download tgz and extract to /tmp/zaf-installer +zaf_download_files() { + rm -rf /tmp/zaf-installer + zaf_fetch_url $ZAF_URL/archive/$ZAF_VERSION.tar.gz | tar -C /tmp -zx && mv /tmp/zaf-$ZAF_VERSION /tmp/zaf-installer +} + +if ! [ -f README.md ]; then + # We are runing from stdin if ! which curl >/dev/null; then zaf_err "Curl not found. Cannot continue. Please install it." fi echo "Installing from url $url..." [ -z "$*" ] && auto=auto - set -e - mkdir -p /tmp/zaf-installer \ - && cd /tmp/zaf-installer \ - && (for i in lib/zaf.lib.sh lib/os.lib.sh lib/ctrl.lib.sh install.sh ; do echo curl -f -k -s -L -o - "$url/$i" >&2; curl -f -k -s -L -o - "$url/$i"; done) >install.sh \ - && chmod +x install.sh \ - && exec ./install.sh $auto "$@" - exit + zaf_download_files && cd /tmp/zaf-installer && exec ./install.sh $auto "$@" + echo "Error downloading and runing installer!" >&2 + exit 2 +fi + +if ! type zaf_version >/dev/null; then +. lib/zaf.lib.sh +. lib/os.lib.sh +. lib/ctrl.lib.sh fi # Read options as config for ZAF @@ -24,18 +47,13 @@ for pair in "$@"; do option=$(echo $pair|cut -d '=' -f 1) value=$(echo $pair|cut -d '=' -f 2-) eval "C_${option}='$value'" + zaf_wrn "Overriding $option from cmdline." done [ -z "$ZAF_CFG_FILE" ] && ZAF_CFG_FILE=$INSTALL_PREFIX/etc/zaf.conf [ -n "$C_ZAF_DEBUG" ] && ZAF_DEBUG=$C_ZAF_DEBUG [ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 -if [ -f $(dirname $0)/lib/zaf.lib.sh ]; then - . $(dirname $0)/lib/zaf.lib.sh - . $(dirname $0)/lib/os.lib.sh - . $(dirname $0)/lib/ctrl.lib.sh -fi - # Read option. If it is already set in zaf.conf, it is skipped. If env variable is set, it is used instead of default # It sets global variable name on result. # $1 - option name @@ -87,34 +105,41 @@ zaf_set_option(){ fi } -zaf_getrest(){ - if [ -f "$(dirname $0)/$1" ]; then - echo "$(dirname $0)/$1" - else - curl -f -k -s -L -o - https://raw.githubusercontent.com/limosek/zaf/master/$1 >${ZAF_TMP_DIR}/$(basename $1) - echo ${ZAF_TMP_DIR}/$(basename $1) - fi -} - -# Set config option in zabbix agent +# Set config option in zabbix agent config file # $1 option # $2 value -# $3 if nonempty, do not remove opion from config, just add to the end zaf_set_agent_option() { local option="$1" local value="$2" - if [ -n "$3" ]; then - if ! grep -q "^$1=$2" $ZAF_AGENT_CONFIG; then - zaf_dbg "Adding option $option to $ZAF_AGENT_CONFIG." - echo "$option=$value" >>$ZAF_AGENT_CONFIG - fi - return - fi if grep ^$option\= $ZAF_AGENT_CONFIG; then - zaf_wrn "Moving option $option to zaf config part." - sed -i "s/$option=/#$option=/" $ZAF_AGENT_CONFIG + zaf_dbg "Setting option $option in $ZAF_AGENT_CONFIG." + sed -i "s/$option=(.*)/$option=$2/" $ZAF_AGENT_CONFIG fi - [ -n "$2" ] && echo "$option=$value" >> "$ZAF_AGENT_CONFIGD/zaf_options.conf" +} + +# Add config option in zabbix agent config file +# $1 option +# $2 value +zaf_add_agent_option() { + local option="$1" + local value="$2" + if ! grep -q "^$1=$2" $ZAF_AGENT_CONFIG; then + zaf_dbg "Adding option $option to $ZAF_AGENT_CONFIG." + echo "$option=$value" >>$ZAF_AGENT_CONFIG + fi +} + +# Move config option fron zabbix agent config file to zaf options file and set value +# $1 option +# $2 value +zaf_move_agent_option() { + local option="$1" + local value="$2" + if grep ^$option\= $ZAF_AGENT_CONFIG; then + zaf_dbg "Moving option $option from $ZAF_AGENT_CONFIG to ." + sed -i "s/$option=(.*)/$option=$2/" $ZAF_AGENT_CONFIG + fi + [ -n "$value" ] && echo "$option=$value" >> "$ZAF_AGENT_CONFIGD/zaf_options.conf" } # Automaticaly configure agent if supported @@ -160,8 +185,9 @@ zaf_configure(){ if which git >/dev/null; then ZAF_GIT=1 else - ZAF_GIT="" + ZAF_GIT=0 fi + zaf_get_option ZAF_GIT "Git is installed" "$ZAF_GIT" "$1" zaf_get_option ZAF_CURL_INSECURE "Insecure curl (accept all certificates)" "1" "$1" zaf_get_option ZAF_TMP_BASE "Tmp directory prefix (\$USER will be added)" "/tmp/zaf" "$1" zaf_get_option ZAF_LIB_DIR "Libraries directory" "/usr/lib/zaf" "$1" @@ -202,61 +228,33 @@ zaf_configure(){ zaf_set_option ZAF_AGENT_CONFIGD "$ZAF_AGENT_CONFIGD" zaf_set_option ZAF_AGENT_BIN "$ZAF_AGENT_BIN" zaf_set_option ZAF_AGENT_RESTART "$ZAF_AGENT_RESTART" + [ -n "$ZAF_PREPACKAGED_DIR" ] && zaf_set_option ZAF_PREPACKAGED_DIR "$ZAF_PREPACKAGED_DIR" ZAF_TMP_DIR="${ZAF_TMP_BASE}-${USER}-$$" -} -if [ -f "${ZAF_CFG_FILE}" ]; then - . "${ZAF_CFG_FILE}" -fi -ZAF_TMP_DIR="${ZAF_TMP_BASE-/tmp/zaf}-${USER}-$$" - -case $1 in -interactive) - shift - zaf_configure interactive - $0 install "$@" - ;; -auto) - shift - zaf_configure auto - $0 install "$@" - ;; -debug-auto) - shift; - ZAF_DEBUG=3 $0 auto "$@" - ;; -debug-interactive) - shift; - ZAF_DEBUG=3 $0 interactive "$@" - ;; -debug) - shift; - ZAF_DEBUG=3 $0 install "$@" - ;; -reconf) - shift; - rm -f $ZAF_CFG_FILE - $0 install "$@" - ;; -install) - zaf_configure auto - rm -rif ${ZAF_TMP_DIR} - mkdir -p ${ZAF_TMP_DIR} if zaf_is_root; then zaf_configure_agent $ZAF_AGENT_OPTIONS "$@" - zaf_set_agent_option "Include" "$ZAF_AGENT_CONFIGD" append + zaf_add_agent_option "Include" "$ZAF_AGENT_CONFIGD" fi +} + +zaf_install_all() { + rm -rif ${ZAF_TMP_DIR} + mkdir -p ${ZAF_TMP_DIR} zaf_install_dir ${ZAF_LIB_DIR} + for i in lib/zaf.lib.sh lib/os.lib.sh lib/ctrl.lib.sh README.md; do + zaf_install $i ${ZAF_LIB_DIR}/ + done + for i in lib/zaflock lib/preload.sh; do + zaf_install_bin $i ${ZAF_LIB_DIR}/ + done + zaf_install_dir ${ZAF_BIN_DIR} + for i in zaf; do + zaf_install_bin $i ${ZAF_BIN_DIR}/ + done zaf_install_dir ${ZAF_PLUGINS_DIR} - zaf_install $(zaf_getrest lib/zaf.lib.sh) ${ZAF_LIB_DIR} - zaf_install $(zaf_getrest lib/os.lib.sh) ${ZAF_LIB_DIR} - zaf_install $(zaf_getrest lib/ctrl.lib.sh) ${ZAF_LIB_DIR} - zaf_install_bin $(zaf_getrest lib/zaflock) ${ZAF_LIB_DIR} - zaf_install_bin $(zaf_getrest lib/preload.sh) ${ZAF_LIB_DIR} zaf_install_dir ${ZAF_TMP_DIR}/p/zaf zaf_install_dir ${ZAF_PLUGINS_DIR} zaf_install_dir ${ZAF_BIN_DIR} - zaf_install_bin $(zaf_getrest zaf) ${ZAF_BIN_DIR} export INSTALL_PREFIX ZAF_CFG_FILE ZAF_DEBUG if zaf_is_root; then [ "${ZAF_GIT}" = 1 ] && ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf update @@ -268,9 +266,55 @@ install) echo "Does ${ZAF_AGENT_RESTART} work?" exit 1 fi + else + [ "${ZAF_GIT}" = 1 ] && [ -n "${INSTALL_PREFIX}" ] && git clone "${ZAF_PLUGINS_GITURL}" "${INSTALL_PREFIX}/${ZAF_REPO_DIR}" fi rm -rif ${ZAF_TMP_DIR} echo "Install OK. Use 'zaf' without parameters to continue." +} + +if [ -f "${ZAF_CFG_FILE}" ]; then + . "${ZAF_CFG_FILE}" +fi +ZAF_TMP_DIR="${ZAF_TMP_BASE-/tmp/zaf}-${USER}-$$" + +case $1 in +interactive) + shift + zaf_configure interactive + zaf_install_all + ;; +auto) + shift + zaf_configure auto + zaf_install_all + ;; +debug-auto) + shift; + ZAF_DEBUG=4 + zaf_configure auto + zaf_install_all + ;; +debug-interactive) + shift; + ZAF_DEBUG=4 + zaf_configure interactive + zaf_install_all + ;; +debug) + shift; + ZAF_DEBUG=4 + zaf_configure auto + zaf_install_all + ;; +reconf) + shift; + rm -f $ZAF_CFG_FILE + zaf_configure auto + ;; +install) + zaf_configure auto + zaf_install_all ;; *) echo diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 3c4300c..e08a539 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -1,7 +1,7 @@ # Hardcoded variables -ZAF_VERSION="trunk" -ZAF_URL="https://raw.githubusercontent.com/limosek/zaf/master/" +ZAF_VERSION="master" +ZAF_URL="https://github.com/limosek/zaf" ############################################ Common routines @@ -39,6 +39,7 @@ zaf_fetch_url() { fi case $scheme in http|https|ftp|file) + [ "$scheme" != "file" ] && [ -n "$ZAF_OFFLINE" ] && zaf_err "Cannot download $1 in offline mode!" [ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="-k" zaf_dbg curl $insecure -f -s -L -o - $1 curl $insecure -f -s -L -o - "$1" @@ -131,7 +132,7 @@ zaf_discovery(){ # Restart zabbix agent zaf_restart_agent() { zaf_wrn "Restarting agent (${ZAF_AGENT_RESTART})" - ${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART})!" + ${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART}). Try $ZAF_AGENT_BIN -f !"; } # Check if zaf.version item is populated @@ -157,6 +158,7 @@ zaf_update_repo() { # name (to try from repo) zaf_get_plugin_url() { local url + if echo "$1" | grep -q '/'; then url="$1" # plugin with path - from directory else @@ -166,7 +168,11 @@ zaf_get_plugin_url() { if [ -d "${ZAF_REPO_DIR}/$1" ]; then url="${ZAF_REPO_DIR}/$1" else - url="${ZAF_PLUGINS_URL}/$1"; + if [ -n "${ZAF_PREPACKAGED_DIR}" ] && [ -d "${ZAF_PREPACKAGED_DIR}/$1" ]; then + url="${ZAF_PREPACKAGED_DIR}/$1" + else + zaf_err "Plugin $1 not found." + fi fi fi fi diff --git a/zaf b/zaf index aebb793..1e2fd88 100755 --- a/zaf +++ b/zaf @@ -8,6 +8,14 @@ else exit 2 fi +# Read options as config for ZAF +for pair in "$@"; do + echo $pair | grep -q '^ZAF\_' || continue + option=$(echo $pair|cut -d '=' -f 1) + value=$(echo $pair|cut -d '=' -f 2-) + eval "${option}='$value'" +done + [ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf ZAF_TMP_DIR="${ZAF_TMP_BASE}-${USER}" trap "rm -rif ${ZAF_TMP_DIR}" EXIT @@ -127,6 +135,7 @@ remove) ;; self-upgrade) + zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-upgrade." rm -rf /tmp/zaf-installer && mkdir /tmp/zaf-installer if ! which curl >/dev/null; then @@ -143,6 +152,7 @@ self-upgrade) ;; self-remove) + zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-remove." . /etc/zaf.conf if [ "$2" = "force" ]; then rm -rf /etc/zaf.conf ${ZAF_PLUGINS_DIR} ${ZAF_REPO_DIR} ${ZAF_LIB_DIR} \