diff --git a/Makefile b/Makefile index 4571eef..642b283 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,21 @@ # Zabbix agent framework makefile +all: help + +help: + @echo make '{deb|arch|ipk|rpm}' '[PLUGINS="/dir/plg1 [/dir2]...] [IPLUGINS="plg1 [plg2]..."] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."]' + @echo PLUGINS are embedded into package. Has to be local directories accessible during build. + @echo IPLUGINS will be downloaded and installed after package is installed. Can be name or url accessible after package installation. + @echo + +include deb.mk +include arch.mk +include ipk.mk +include rpm.mk + CONTROLFILES=$(foreach p,$(PLUGINS),$(p)/control.zaf) ZAF_EXPORT_OPTS=$(foreach o,$(ZAF_OPTIONS),$(shell echo $(o)|cut -d '=' -f 1)) -DEBIAN_DIR=tmp/deb -DEBIAN_CTRL=$(DEBIAN_DIR)/DEBIAN -DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) -ARCH_DIR=archlinux + ifeq ($(ZAF_DEBUG),) ZAF_DEBUG=0 endif @@ -17,86 +27,15 @@ ifeq ($(IPLUGINS),) IPLUGINS = zaf endif -all: help +deb: $(DEBIAN_PKG) -help: - @echo make '{deb|ipk|rpm}' '[PLUGINS="/dir/plg1 [/dir2]...] [IPLUGINS="plg1 [plg2]..."] [ZAF_OPTIONS="ZAF_cfg=val ..."] [AGENT_OPTIONS="Z_Server=host ..."]' - @echo PLUGINS are embedded into package. Has to be local directories accessible during build. - @echo IPLUGINS will be downloaded and installed after package is installed. Can be name or url accessible after package installation. - @echo +arch: $(ARCH_PKG) -deb: - $(DEBIAN_PKG) +rpm: $(RPM_PKG) -arch: - $(ARCH_PKG) - -$(DEBIAN_PKG): deb-clean deb-init deb-deps deb-control deb-scripts deb-cp deb-package -$(ARCH_PKG): arch-clean arch-build +ipk: $(IPK_PKG) clean: @rm -rf tmp/* out/* -deb-clean: - @rm -rf $(DEBIAN_DIR) $(DEBIAN_PKG) -deb-init: - @mkdir -p tmp out $(DEBIAN_DIR) - -deb-deps: $(CONTROLFILES) - @which dpkg >/dev/null && which dpkg-buildpackage >/dev/null && which dch >/dev/null || { echo "You need essential debian developer tools. Please install them:\nsudo apt-get install build-essential devscripts debhelper"; exit 2; } - -deb-control: - @mkdir -p $(DEBIAN_CTRL) - @. lib/zaf.lib.sh; \ - . lib/ctrl.lib.sh; \ - for p in $(PLUGINS); do \ - DEPENDS="$$DEPENDS,$$(zaf_ctrl_get_global_option $$p/control.zaf Depends-dpkg | tr ' ' ',')"; \ - done; \ - [ "$$ZAF_GITBRANCH" = "master" ] && master=master; \ - zaf_far '{ZAF_VERSION}' "$${ZAF_VERSION}$$master" $(DEBIAN_CTRL)/control - -deb-scripts: - @. lib/zaf.lib.sh; \ - . lib/ctrl.lib.sh; \ - cat files/postinst.template | zaf_far '{PLUGINS}' "$(PLUGINS)" | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | 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 - -deb-cp: - @mkdir -p $(DEBIAN_DIR) - @set -e; INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=$(ZAF_DEBUG) ./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/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 - @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 -endif - -deb-package: - @dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) - @echo "\nCheck configuration:" - @cat $(DEBIAN_DIR)/etc/zaf.conf - @echo PLUGINS embedded: $(PLUGINS) - @echo PLUGINS in postinst: $(IPLUGINS) - @echo - -arch-clean: - @cd $(ARCH_DIR) - git clean -ffdx - -arch-build: - @cd $(ARCH_DIR) && makepkg -f diff --git a/arch.mk b/arch.mk new file mode 100644 index 0000000..d5c2bb6 --- /dev/null +++ b/arch.mk @@ -0,0 +1,22 @@ +# Arch linux specific definitions + +ARCH_DIR=tmp/archlinux + +ifeq ($(ARCH_PKG),) + ARCH_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.arch) +endif + +$(ARCH_PKG): clean arch-init arch-build + +arch-init: + @mkdir -p tmp out $(ARCH_DIR) + @. lib/zaf.lib.sh; \ + . lib/ctrl.lib.sh; \ + cat files/archlinux/PKGBUILD | zaf_far '{PLUGINS}' "$(PLUGINS)" | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | \ + zaf_far "{ZAF_OPTIONS}" "$(ZAF_OPTIONS)" | zaf_far "{AGENT_OPTIONS}" "$(AGENT_OPTIONS)" \ + >$(ARCH_DIR)/PKGBUILD + +arch-build: + @cd $(ARCH_DIR) && makepkg -f + + diff --git a/deb.mk b/deb.mk new file mode 100644 index 0000000..cee1979 --- /dev/null +++ b/deb.mk @@ -0,0 +1,66 @@ +# Debian specific config + +DEBIAN_DIR=tmp/deb +DEBIAN_CTRL=$(DEBIAN_DIR)/DEBIAN + +ifeq ($(DEBIAN_PKG),) + DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) +endif + +$(DEBIAN_PKG): clean deb-init deb-deps deb-control deb-scripts deb-cp deb-package + +deb-init: + @mkdir -p tmp out $(DEBIAN_DIR) + +deb-deps: $(CONTROLFILES) + @which dpkg >/dev/null && which dpkg-buildpackage >/dev/null && which dch >/dev/null || { echo "You need essential debian developer tools. Please install them:\nsudo apt-get install build-essential devscripts debhelper"; exit 2; } + +deb-control: + @mkdir -p $(DEBIAN_CTRL) + @. lib/zaf.lib.sh; \ + . lib/ctrl.lib.sh; \ + for p in $(PLUGINS); do \ + DEPENDS="$$DEPENDS,$$(zaf_ctrl_get_global_option $$p/control.zaf Depends-dpkg | tr ' ' ',')"; \ + done; \ + [ "$$ZAF_GITBRANCH" = "master" ] && master=master; \ + zaf_far '{ZAF_VERSION}' "$${ZAF_VERSION}$$master" $(DEBIAN_CTRL)/control + +deb-scripts: + @. lib/zaf.lib.sh; \ + . lib/ctrl.lib.sh; \ + cat files/debian/postinst.template | zaf_far '{PLUGINS}' "$(PLUGINS)" | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | zaf_far '{ZAF_LIB_DIR}' "/usr/lib/zaf" >$(DEBIAN_CTRL)/postinst + @chmod +x $(DEBIAN_CTRL)/postinst + @cp files/debian/preinst.template $(DEBIAN_CTRL)/preinst + @chmod +x $(DEBIAN_CTRL)/preinst + @cp files/debian/prerm.template $(DEBIAN_CTRL)/prerm + @chmod +x $(DEBIAN_CTRL)/prerm + +deb-cp: + @mkdir -p $(DEBIAN_DIR) + @set -e; INSTALL_PREFIX=$(DEBIAN_DIR) ZAF_DEBUG=$(ZAF_DEBUG) ./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/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 + @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 +endif + +deb-package: + @dpkg-deb -b $(DEBIAN_DIR) $(DEBIAN_PKG) + @echo "\nCheck configuration:" + @cat $(DEBIAN_DIR)/etc/zaf.conf + @echo PLUGINS embedded: $(PLUGINS) + @echo PLUGINS in postinst: $(IPLUGINS) + @echo + + diff --git a/archlinux/PKGBUILD b/files/archlinux/PKGBUILD similarity index 92% rename from archlinux/PKGBUILD rename to files/archlinux/PKGBUILD index 6bb331d..70136d4 100644 --- a/archlinux/PKGBUILD +++ b/files/archlinux/PKGBUILD @@ -34,5 +34,6 @@ package() { cd "$srcdir/$pkgname" INSTALL_PREFIX="$pkgdir" \ - ./install.sh auto + ./install.sh auto {ZAF_OPTIONS} {AGENT_OPTIONS} } + diff --git a/files/changelog.template b/files/debian/changelog.template similarity index 100% rename from files/changelog.template rename to files/debian/changelog.template diff --git a/files/control.template b/files/debian/control.template similarity index 100% rename from files/control.template rename to files/debian/control.template diff --git a/files/postinst.template b/files/debian/postinst.template similarity index 100% rename from files/postinst.template rename to files/debian/postinst.template diff --git a/files/preinst.template b/files/debian/preinst.template similarity index 100% rename from files/preinst.template rename to files/debian/preinst.template diff --git a/files/prerm.template b/files/debian/prerm.template similarity index 100% rename from files/prerm.template rename to files/debian/prerm.template diff --git a/files/zaf.conf-deb.template b/files/debian/zaf.conf-deb.template similarity index 100% rename from files/zaf.conf-deb.template rename to files/debian/zaf.conf-deb.template diff --git a/install.sh b/install.sh index 7f3db1d..2b420c0 100755 --- a/install.sh +++ b/install.sh @@ -109,54 +109,73 @@ zaf_set_option(){ fi } -# Set config option in zabbix agent config file -# $1 option -# $2 value -zaf_set_agent_option() { - local option="$1" - local value="$2" - if grep -q ^$option\= $ZAF_AGENT_CONFIG; then - zaf_dbg "Setting option $option in $ZAF_AGENT_CONFIG." - sed -i "s/$option=\(.*\)/$option=$2/" $ZAF_AGENT_CONFIG +# Set config option in zabbix config file +# $1 config file +# $2 option +# $3 value +zaf_set_zabbix_option() { + local cfgfile="$1" + local option="$2" + local value="$3" + if grep -q ^$option\= $cfgfile; then + zaf_dbg "Setting option $option in $cfgfile." + sed -i "s/$option=\(.*\)/$option=$2/" $cfgfile else - zaf_move_agent_option "$1" "$2" + zaf_move_zabbix_option "$1" "$2" "$3" fi } -# Unset config option in zabbix agent config file -# $1 option -zaf_unset_agent_option() { - local option="$1" - local value="$2" - if grep -q ^$option\= $ZAF_AGENT_CONFIG; then - zaf_dbg "Unsetting option $option in $ZAF_AGENT_CONFIG." - sed -i "s/$option=\(.*\)/#$option=$2/" $ZAF_AGENT_CONFIG +# Get config option from zabbix config file +# $1 config file +# $2 option +zaf_get_zabbix_option() { + local cfgfile="$1" + local option="$2" + grep ^$option\= $cfgfile | cut -d '=' -f 2-; +} + +# Unset config option in zabbix config file +# $1 config file +# $2 option +zaf_unset_zabbix_option() { + local cfgfile="$1" + local option="$2" + local value="$3" + if grep -q ^$option\= $cfgfile; then + zaf_dbg "Unsetting option $option in $cfgfile." + sed -i "s/$option=\(.*\)/#$option=$2/" $cfgfile fi } -# 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 +# Add config option in zabbix config file +# $1 config file +# $2 option +# $3 value +zaf_add_zabbix_option() { + local cfgfile="$1" + local option="$2" + local value="$3" + if ! grep -q "^$option=$value" $cfgfile; then + zaf_dbg "Adding option $option to $cfgfile." + echo "$option=$value" >>$cfgfile 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 -q ^$option\= $ZAF_AGENT_CONFIG; then - zaf_dbg "Moving option $option from $ZAF_AGENT_CONFIG to ." - sed -i "s/$option=(.*)/$option=$2/" $ZAF_AGENT_CONFIG +# Move config option fron zabbix config file to zaf options file and set value +# $1 config file +# $2 options file +# $3 option +# $4 value +zaf_move_zabbix_option() { + local cfgfile="$1" + local optsfile="$2" + local option="$3" + local value="$4" + if grep -q ^$option\= $cfgfile; then + zaf_dbg "Moving option $option from $cfgfile to $optsfile." + sed -i "s/$option=(.*)/$option=$value/" $cfgfile fi - [ -n "$value" ] && echo "$option=$value" >> "$ZAF_AGENT_CONFIGD/zaf_options.conf" + [ -n "$value" ] && echo "$option=$value" >> "$optsfile" } # Automaticaly configure agent if supported @@ -166,6 +185,7 @@ zaf_configure_agent() { local option local value local options + local changes zaf_install_dir "$ZAF_AGENT_CONFIGD" echo -n >"$ZAF_AGENT_CONFIGD/zaf_options.conf" || zaf_err "Cannot access $ZAF_AGENT_CONFIGD/zaf_options.conf" @@ -175,15 +195,45 @@ zaf_configure_agent() { option=$(echo $pair|cut -d '=' -f 1|cut -d '_' -f 2) value=$(echo $pair|cut -d '=' -f 2-) if [ -n "$value" ]; then - zaf_set_agent_option "$option" "$value" + zaf_set_zabbix_option "$ZAF_AGENT_CONFIG" "$option" "$value" else - zaf_unset_agent_option "$option" + zaf_unset_zabbix_option "$ZAF_AGENT_CONFIG" "$option" fi options="$options Z_$option=$value" + changes=1 done zaf_set_option ZAF_AGENT_OPTIONS "${options}" + [ -n "$changes" ] # Return false if no changes } +# Automaticaly configure server if supported +# Parameters are in format S_zabbixconfvar=value +zaf_configure_server() { + local pair + local option + local value + local options + local changes + + zaf_install_dir "$ZAF_SERVER_CONFIGD" + echo -n >"$ZAF_SERVER_CONFIGD/zaf_options.conf" || zaf_err "Cannot access $ZAF_SERVER_CONFIGD/zaf_options.conf" + for pair in "$@"; do + echo $pair | grep -q '^S\_' || continue # Skip non S_ vars + option=$(echo $pair|cut -d '=' -f 1|cut -d '_' -f 2) + value=$(echo $pair|cut -d '=' -f 2-) + if [ -n "$value" ]; then + zaf_set_zabbix_option "$ZAF_SERVER_CONFIG" "$option" "$value" + else + zaf_unset_zabbix_option "$ZAF_SERVER_CONFIG" "$option" + fi + options="$options S_$option=$value" + changes=1 + done + zaf_set_option ZAF_SERVER_OPTIONS "${options}" + [ -n "$changes" ] # Return false if no changes +} + + zaf_preconfigure(){ zaf_detect_system zaf_os_specific zaf_configure_os @@ -222,11 +272,18 @@ zaf_configure(){ [ "${ZAF_GIT}" = 1 ] && zaf_get_option ZAF_REPO_GITURL "Git plugins repository" "https://github.com/limosek/zaf-plugins.git" "$INSTALL_MODE" zaf_get_option ZAF_REPO_URL "Plugins http[s] repository" "https://raw.githubusercontent.com/limosek/zaf-plugins/master/" "$INSTALL_MODE" zaf_get_option ZAF_REPO_DIR "Plugins directory" "${ZAF_LIB_DIR}/repo" "$INSTALL_MODE" + zaf_get_option ZAF_AGENT_CONFIG "Zabbix agent config" "/etc/zabbix/zabbix_agentd.conf" "$INSTALL_MODE" ! [ -d "${ZAF_AGENT_CONFIGD}" ] && [ -d "/etc/zabbix/zabbix_agentd.d" ] && ZAF_AGENT_CONFIGD="/etc/zabbix/zabbix_agentd.d" zaf_get_option ZAF_AGENT_CONFIGD "Zabbix agent config.d" "/etc/zabbix/zabbix_agentd.conf.d/" "$INSTALL_MODE" zaf_get_option ZAF_AGENT_BIN "Zabbix agent binary" "/usr/sbin/zabbix_agentd" "$INSTALL_MODE" zaf_get_option ZAF_AGENT_RESTART "Zabbix agent restart cmd" "service zabbix-agent restart" "$INSTALL_MODE" + + zaf_get_option ZAF_SERVER_CONFIG "Zabbix server config" "/etc/zabbix/zabbix_server.conf" "$INSTALL_MODE" + ! [ -d "${ZAF_SERVER_CONFIGD}" ] && [ -d "/etc/zabbix/zabbix_server.d" ] && ZAF_SERVER_CONFIGD="/etc/zabbix/zabbix_server.d" + zaf_get_option ZAF_SERVER_CONFIGD "Zabbix server config.d" "/etc/zabbix/zabbix_server.conf.d/" "$INSTALL_MODE" + zaf_get_option ZAF_SERVER_BIN "Zabbix server binary" "/usr/sbin/zabbix_server" "$INSTALL_MODE" + zaf_get_option ZAF_SUDOERSD "Sudo sudoers.d directory" "/etc/sudoers.d" "$INSTALL_MODE" zaf_get_option ZAF_CROND "Cron.d directory" "/etc/cron.d" "$INSTALL_MODE" zaf_get_option ZAF_ZBXAPI_URL "Zabbix API url" "http://localhost/zabbix/api_jsonrpc.php" "$INSTALL_MODE" @@ -260,6 +317,12 @@ 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" + if [ -f $ZABBIX_SERVER_BIN ]; then + zaf_set_option ZAF_SERVER_CONFIG "$ZAF_SERVER_CONFIG" + zaf_set_option ZAF_SERVER_CONFIGD "$ZAF_SERVER_CONFIGD" + zaf_set_option ZAF_SERVER_EXTSCRIPTS "$(zaf_get_zabbix_option $ZAF_SERVER_CONFIG ExternalScripts)" + fi + zaf_set_option ZAF_SERVER_BIN "$ZAF_SERVER_BIN" zaf_set_option ZAF_SUDOERSD "$ZAF_SUDOERSD" zaf_set_option ZAF_CROND "$ZAF_CROND" zaf_set_option ZAF_ZBXAPI_URL "$ZAF_ZBXAPI_URL" @@ -270,7 +333,12 @@ zaf_configure(){ if zaf_is_root; then zaf_configure_agent $ZAF_AGENT_OPTIONS "$@" - zaf_add_agent_option "Include" "$ZAF_AGENT_CONFIGD" + zaf_add_zabbix_option "$ZAF_AGENT_CONFIG" "Include" "$ZAF_AGENT_CONFIGD" + if [ -f "$ZAF_SERVER_BIN" ]; then + zaf_configure_server $ZAF_SERVER_OPTIONS "$@" && zaf_add_zabbix_option "$ZAF_SERVER_CONFIG" "Include" "$ZAF_SERVER_CONFIGD" + else + zaf_wrn "Skipping server config. Zabbix server binary '$ZAF_SERVER_BIN' not found." + fi fi } @@ -388,6 +456,7 @@ install) echo "install.sh {auto|interactive|debug-auto|debug-interactive|reconf} [Agent-Options] [Zaf-Options]" echo "scratch means that config file will be created from scratch" echo " Agent-Options: Z_Option=value [...]" + echo " Server-Options: S_Option=value [...]" echo " Zaf-Options: ZAF_OPT=value [...]" echo " To unset Agent-Option use Z_Option=''" echo diff --git a/ipk.mk b/ipk.mk new file mode 100644 index 0000000..20f8ff3 --- /dev/null +++ b/ipk.mk @@ -0,0 +1,10 @@ +# Makefile for generating openwrt ipk packages +# Contrinutions welcome :) + +ifeq ($(IPK_PKG),) + IPK_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.ipk) +endif + +$(IPK_PKG): + @echo "Not supported yet. Contributions welcomed! :) "; exit 2 + diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 8386ba6..8330220 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -5,6 +5,25 @@ zaf_ctrl_get_items() { grep '^Item ' | cut -d ' ' -f 2 | cut -d ':' -f 1 | tr '\r\n' ' ' } +# Get external item list from control on stdin +zaf_ctrl_get_extitems() { + grep '^ExtItem ' | cut -d ' ' -f 2 | cut -d ':' -f 1 | tr '\r\n' ' ' +} + +# Get external item body from stdin +# $1 itemname +zaf_ctrl_get_extitem_block() { + grep -v '^#' | awk '/^ExtItem '$1'/ { i=0; + while (i==0) { + getline; + if (/^\/ExtItem/) exit; + print $0; + }}; + END { + exit i==0; + }' +} + # Get item body from stdin # $1 itemname zaf_ctrl_get_item_block() { @@ -19,13 +38,14 @@ zaf_ctrl_get_item_block() { }' } + # Get global plugin block body from stdin # $1 itemname zaf_ctrl_get_global_block() { grep -v '^#' | awk '{ i=0; print $0; while (i==0) { getline; - if (/^Item /) exit; + if (/^(Item |ExtItem)/) exit; print $0; }}' } @@ -33,7 +53,7 @@ zaf_ctrl_get_global_block() { # Get item multiline option # $1 optionname zaf_block_get_moption() { - awk '/^'$1'::$/ { i=0; print $0; + awk '/^'$1'::$/ { i=0; while (i==0) { getline; if (/^::$/) {i=1; continue;}; @@ -68,6 +88,7 @@ zaf_ctrl_get_global_option() { || zaf_ctrl_get_global_block <$1 | zaf_block_get_option "$2" fi } + # Get item specific option (single or multiline) # $1 - control file # $2 - item name @@ -87,10 +108,30 @@ zaf_ctrl_get_item_option() { fi } +# Get external item specific option (single or multiline) +# $1 - control file +# $2 - item name +# $3 - option name +zaf_ctrl_get_extitem_option() { + local ctrlvar + local ctrlopt + + ctrlopt="ZAF_CTRLI_$(zaf_stripctrl $2)_$(zaf_stripctrl $3)" + eval ctrlvar=\$$ctrlopt + if [ -n "$ctrlvar" ]; then + zaf_dbg "Overriding item control field $2/$3 from env $ctrlopt($ctrlvar)" + echo $ctrlopt + else + zaf_ctrl_get_extitem_block <$1 "$2" | zaf_block_get_moption "$3" \ + || zaf_ctrl_get_extitem_block <$1 "$2" | zaf_block_get_option "$3" + fi +} + # Check dependencies based on control file zaf_ctrl_check_deps() { local deps deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-${ZAF_PKG}" ) + if ! zaf_os_specific zaf_check_deps $deps; then zaf_err "Missing one of dependend system packages: $deps" fi @@ -178,10 +219,10 @@ zaf_ctrl_install() { ) || zaf_err "Error during zaf_ctrl_install" } -# Generates zabbix cfg from control file +# Generates zabbix items cfg from control file # $1 control # $2 pluginname -zaf_ctrl_generate_cfg() { +zaf_ctrl_generate_items_cfg() { local items local cmd local iscript @@ -229,7 +270,60 @@ zaf_ctrl_generate_cfg() { fi zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" done - ) || zaf_err "Error during zaf_ctrl_generate_cfg" + ) || zaf_err "Error during zaf_ctrl_generate_items_cfg" } +# Generates zabbix cfg for external items from control file +# $1 control +# $2 pluginname +zaf_ctrl_generate_extitems_cfg() { + local items + local cmd + local iscript + local ikey + local lock + local cache + + items=$(zaf_ctrl_get_extitems <"$1") + if [ -n "$items" ] && [ -z "${ZAF_SERVER_EXTSCRIPTS}" ] || ! [ -d "${ZAF_SERVER_EXTSCRIPTS}" ]; then + zaf_err "Zabbix server external scripts directory '${ZAF_SERVER_EXTSCRIPTS}' unknown. Cannot add external item." + fi + (set -e + for i in $items; do + iscript=$(zaf_stripctrl $i) + params=$(zaf_ctrl_get_extitem_option $1 $i "Parameters") + ikey="$2.$i" + if [ -n "$params" ]; then + args="" + apos=1; + for p in $params; do + args="$args \$$apos" + apos=$(expr $apos + 1) + done + fi + lock=$(zaf_ctrl_get_extitem_option $1 $i "Lock") + if [ -n "$lock" ]; then + lock="${ZAF_LIB_DIR}/zaflock $lock " + fi + cache=$(zaf_ctrl_get_extitem_option $1 $i "Cache") + if [ -n "$cache" ]; then + cache="_cache '$cache' " + fi + cmd=$(zaf_ctrl_get_extitem_option $1 $i "Cmd") + if [ -n "$cmd" ]; then + $(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock$cmd"; + continue + fi + cmd=$(zaf_ctrl_get_extitem_option $1 $i "Script") + if [ -n "$cmd" ]; then + zaf_ctrl_get_extitem_option $1 $i "Script" >${ZAF_TMP_DIR}/${iscript}.sh; + zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ + $(which echo) -e "#!/bin/sh\n${ZAF_LIB_DIR}/preload.sh $cache $lock${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args" >${ZAF_SERVER_EXTSCRIPTS}/$ikey; + chmod +x ${ZAF_SERVER_EXTSCRIPTS}/$ikey + continue; + fi + zaf_err "External item $i declared in control file but has no Cmd, Function or Script!" + done + ) || zaf_err "Error during zaf_ctrl_generate_items_cfg" +} diff --git a/lib/os.lib.sh b/lib/os.lib.sh index 48ea6a5..4d5fd22 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -130,7 +130,7 @@ zaf_install_agent_opkg() { # $* - packages zaf_check_deps_dpkg() { for i in $*; do - dpkg-query -f '${Status},${Package}\n' -W $* 2>/dev/null | grep -q "^install ok" + dpkg-query -f '${db:Status-Status},${Package}\n' -W $* 2>/dev/null | grep -q "^installed" done } diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 3e7e908..b8ca58b 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -299,8 +299,9 @@ zaf_install_plugin() { zaf_ctrl_install "$url" "${control}" "${plugindir}" zaf_ctrl_sudo "$plugin" "${control}" "${plugindir}" zaf_ctrl_cron "$plugin" "${control}" "${plugindir}" - zaf_ctrl_generate_cfg "${control}" "${plugin}" \ + zaf_ctrl_generate_items_cfg "${control}" "${plugin}" \ | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf + zaf_ctrl_generate_extitems_cfg "${control}" "${plugin}" zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" else zaf_err "Cannot install plugin '$plugin' to $plugindir!" diff --git a/lib/zafext b/lib/zafext new file mode 100644 index 0000000..855be76 --- /dev/null +++ b/lib/zafext @@ -0,0 +1,29 @@ +#!/bin/sh + +. /etc/zaf.conf + +. ${ZAF_LIB_DIR}/zaf.lib.sh +. ${ZAF_LIB_DIR}/plugin.lib.sh +. ${ZAF_LIB_DIR}/ctrl.lib.sh +. ${ZAF_LIB_DIR}/os.lib.sh +. ${ZAF_LIB_DIR}/zbxapi.lib.sh +. ${ZAF_LIB_DIR}/cache.lib.sh + +if ! type zaf_version >/dev/null; then + echo "Problem loading libraries?" + exit 2 +fi +zaf_debug_init +zaf_tmp_init +zaf_cache_init + +export ZAF_LIB_DIR +export ZAF_TMP_DIR +export ZAF_CACHE_DIR +export ZAF_PLUGINS_DIR +export ZAF_DEBUG +unset ZAF_LOG_STDERR +export PATH +export ZAF_ITEM=$(basename $0) + + diff --git a/rpm.mk b/rpm.mk new file mode 100644 index 0000000..23f703c --- /dev/null +++ b/rpm.mk @@ -0,0 +1,10 @@ +# Makefile for generating rpm packages +# Contrinutions welcome :) + +ifeq ($(RPM_PKG),) + RPM_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.rpm) +endif + +$(RPM_PKG): + @echo "Not supported yet. Contributions welcomed! :) "; exit 2 +