Index: net-mgmt/zabbix5-agent/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-agent/Makefile @@ -0,0 +1,14 @@ +# Created by: Juraj Lutter +# $FreeBSD$ + +PORTNAME= zabbix5 +CATEGORIES= net-mgmt +PKGNAMESUFFIX= -agent + +MASTERDIR= ${.CURDIR}/../zabbix5-server +PLIST= ${PKGDIR}/pkg-plist.agent + +OPTIONS_DEFINE= CURL IPV6 +OPTIONS_DEFAULT= CURL OPENSSL + +.include "${MASTERDIR}/Makefile" Index: net-mgmt/zabbix5-agent2/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-agent2/Makefile @@ -0,0 +1,20 @@ +# Created by: Juraj Lutter +# $FreeBSD$ + +PORTNAME= zabbix5 +CATEGORIES= net-mgmt +PKGNAMESUFFIX= -agent2 +DISTFILES= ${DISTNAME}${EXTRACT_SUFX} + +MASTERDIR= ${.CURDIR}/../zabbix5-server +PLIST= ${PKGDIR}/pkg-plist.agent2 + +DISTINFO_FILE= ${.CURDIR}/distinfo + +OPTIONS_DEFINE= LDAP IPV6 OPENSSL +OPTIONS_DEFAULT= LDAP OPENSSL + +LDAP_CONFIGURE_WITH= ldap +LDAP_USE= OPENLDAP=yes + +.include "${MASTERDIR}/Makefile" Index: net-mgmt/zabbix5-agent2/distinfo =================================================================== --- /dev/null +++ net-mgmt/zabbix5-agent2/distinfo @@ -0,0 +1,25 @@ +TIMESTAMP = 1590062351 +SHA256 (zabbix-5.0.0.tar.gz) = 5a1762fd2bb7275d9a28c6dfa9a6d46d84be749f9bf50a36eb8fcd20fb8bb6eb +SIZE (zabbix-5.0.0.tar.gz) = 18519888 +SHA256 (alimy-mc-v2.0.3_GH0.tar.gz) = 0ac06190a767bc0fcf74fbb7e565fa0742a6f5425440c337a15246a41aca309e +SIZE (alimy-mc-v2.0.3_GH0.tar.gz) = 21035 +SHA256 (dustin-gomemcached-a2284a01c143_GH0.tar.gz) = d6b4c2af8993f45199aa2cfa05e0f630d897a73ddbbc7ddbebc47821d4b1115f +SIZE (dustin-gomemcached-a2284a01c143_GH0.tar.gz) = 21981 +SHA256 (fsnotify-fsnotify-v1.4.7_GH0.tar.gz) = b7530d973d0ab0e58ad8ce1b9a4b963d6f57b3d72f2f9e13d49846976361b1cd +SIZE (fsnotify-fsnotify-v1.4.7_GH0.tar.gz) = 31139 +SHA256 (go-ole-go-ole-v1.2.4_GH0.tar.gz) = 1f30df494ffc50c133c5f276f64c94820046b1a3a660c0cca49a5c3a8106db11 +SIZE (go-ole-go-ole-v1.2.4_GH0.tar.gz) = 51655 +SHA256 (go-sql-driver-mysql-v1.5.0_GH0.tar.gz) = 9d98b46623037447a26a51a203540bf605b6e6220d31f2efc7396242fcb660b5 +SIZE (go-sql-driver-mysql-v1.5.0_GH0.tar.gz) = 90474 +SHA256 (godbus-dbus-v4.1.0_GH0.tar.gz) = e35dd6031febb2b550b765da602a6e8eaa6a45c501af7370f66d7710a23c501d +SIZE (godbus-dbus-v4.1.0_GH0.tar.gz) = 53466 +SHA256 (golang-sys-f43be2a4598c_GH0.tar.gz) = 120cfab17111e93b3513a42bf0db20634552c85ae48d1fd3c5d7859fc5603356 +SIZE (golang-sys-f43be2a4598c_GH0.tar.gz) = 1513901 +SHA256 (golang-xerrors-1b5146add898_GH0.tar.gz) = 57ba6cacc0a84a2ecbfda1169b5e9c184581dd009136f95d2fca9a5289e49ab1 +SIZE (golang-xerrors-1b5146add898_GH0.tar.gz) = 12200 +SHA256 (mattn-go-sqlite3-v2.0.3_GH0.tar.gz) = ed015860c9b3e701d8cce7dcb0bcb2e2f53071718334465b10abb696f7de0e58 +SIZE (mattn-go-sqlite3-v2.0.3_GH0.tar.gz) = 2335418 +SHA256 (mediocregopher-radix-v3.4.2_GH0.tar.gz) = 3b26042bed210daca2354b43e476e462b12e94edba6e242c14f2cf6095c9dce5 +SIZE (mediocregopher-radix-v3.4.2_GH0.tar.gz) = 93999 +SHA256 (natefinch-npipe-c1b8fa8bdcce_GH0.tar.gz) = 6e3de30412671aba8f89008b2411126378a4dd2bddff095312d7a88a1670d3ab +SIZE (natefinch-npipe-c1b8fa8bdcce_GH0.tar.gz) = 12421 Index: net-mgmt/zabbix5-frontend/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-frontend/Makefile @@ -0,0 +1,34 @@ +# Created by: Juraj Lutter +# $FreeBSD$ + +PORTNAME= zabbix5 +CATEGORIES= net-mgmt +PKGNAMESUFFIX= -frontend + +MASTERDIR= ${.CURDIR}/../zabbix5-server + +NO_BUILD= yes +NO_ARCH= yes +PATCHDIR= +PLIST= ${PKGDIR}/pkg-plist.frontend + +USE_PHP= bcmath ctype dom fileinfo filter gd gettext json ldap mbstring pcre \ + session simplexml snmp sockets xml xmlreader xmlwriter +USES+= php:web + +OPTIONS_DEFINE= MYSQLI PGSQL ORACLE +OPTIONS_DEFAULT= MYSQLI +MYSQLI_DESC= MySQLI backend + +MYSQLI_USE= PHP=mysqli + +PGSQL_USE= PHP=pgsql + +ORACLE_CONFIGURE_WITH= oracle + +do-install: + @${MKDIR} ${STAGEDIR}${WWWDIR} + (cd ${WRKSRC}/ui && \ + ${COPYTREE_SHARE} . ${STAGEDIR}${WWWDIR}) + +.include "${MASTERDIR}/Makefile" Index: net-mgmt/zabbix5-java/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-java/Makefile @@ -0,0 +1,14 @@ +# $FreeBSD$ + +PORTNAME= zabbix5 +CATEGORIES= net-mgmt +PKGNAMESUFFIX= -java + +MASTERDIR= ${.CURDIR}/../zabbix5-server +PLIST= ${PKGDIR}/pkg-plist.java + +OPTIONS_DEFINE= IPV6 + +USE_JAVA= yes + +.include "${MASTERDIR}/Makefile" Index: net-mgmt/zabbix5-proxy/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-proxy/Makefile @@ -0,0 +1,12 @@ +# Created by: Juraj Lutter +# $FreeBSD$ + +PORTNAME= zabbix5 +CATEGORIES= net-mgmt +PKGNAMESUFFIX= -proxy + +MASTERDIR= ${.CURDIR}/../zabbix5-server + +OPTIONS_SINGLE_DB= MYSQL PGSQL SQLITE ORACLE + +.include "${MASTERDIR}/Makefile" Index: net-mgmt/zabbix5-server/Makefile =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/Makefile @@ -0,0 +1,260 @@ +# Created by: Juraj Lutter +# $FreeBSD$ + +PORTNAME= zabbix5 +PORTVERSION= 5.0.0 +PORTREVISION?= 0 +CATEGORIES= net-mgmt +MASTER_SITES= https://cdn.zabbix.com/zabbix/sources/stable/${PORTVERSION:R}/ +PKGNAMESUFFIX?= -server +DISTNAME= zabbix-${PORTVERSION} + +MAINTAINER= juraj@lutter.sk +COMMENT= Enterprise-class open source distributed monitoring (${PKGNAMESUFFIX:S/^-//}) + +LICENSE= GPLv2+ +LICENSE_FILE= ${WRKSRC}/COPYING + +LIB_DEPENDS= libpcre.so:devel/pcre + +CONFLICTS= zabbix[0-46-9][0-9]${PKGNAMESUFFIX} \ + zabbix4[0-46-9]${PKGNAMESUFFIX} \ + zabbix[0-9]${PKGNAMESUFFIX} + +ZABBIX_BUILD= ${PKGNAMESUFFIX:S/^-//} + +USES= autoreconf localbase pkgconfig iconv +.if ${ZABBIX_BUILD} == "agent2" +USES+= go:modules +USE_GITHUB= nodefault +GH_ACCOUNT= zabbix +GH_PROJECT= zabbix +GH_TUPLE= \ + alimy:mc:v2.0.3:alimy_mc_v2/src/go/vendor/github.com/alimy/mc/v2 \ + dustin:gomemcached:a2284a01c143:dustin_gomemcached/src/go/vendor/github.com/dustin/gomemcached \ + fsnotify:fsnotify:v1.4.7:fsnotify_fsnotify/src/go/vendor/github.com/fsnotify/fsnotify \ + go-ole:go-ole:v1.2.4:go_ole_go_ole/src/go/vendor/github.com/go-ole/go-ole \ + go-sql-driver:mysql:v1.5.0:go_sql_driver_mysql/src/go/vendor/github.com/go-sql-driver/mysql \ + godbus:dbus:v4.1.0:godbus_dbus/src/go/vendor/github.com/godbus/dbus \ + golang:sys:f43be2a4598c:golang_sys/src/go/vendor/golang.org/x/sys \ + golang:xerrors:1b5146add898:golang_xerrors/src/go/vendor/golang.org/x/xerrors \ + mattn:go-sqlite3:v2.0.3:mattn_go_sqlite3/src/go/vendor/github.com/mattn/go-sqlite3 \ + mediocregopher:radix:v3.4.2:mediocregopher_radix_v3/src/go/vendor/github.com/mediocregopher/radix/v3 \ + natefinch:npipe:c1b8fa8bdcce:natefinch_npipe/src/go/vendor/github.com/natefinch/npipe +.endif + +.if ${ZABBIX_BUILD} != "frontend" # frontend only needs the version/distribution settings +.if ${ZABBIX_BUILD:Nagent*} +CONFIGURE_ARGS+= --with-libevent=${LOCALBASE} --cache-file=${WRKSRC}/config.cache +LIB_DEPENDS+= libevent.so:devel/libevent +USE_RC_SUBR= zabbix_${ZABBIX_BUILD} +.elif ${ZABBIX_BUILD} == "agent" +USE_RC_SUBR= zabbix_${ZABBIX_BUILD}d +.else +USE_RC_SUBR= zabbix_${ZABBIX_BUILD} +USE_RC_SUBR+= mock_server +.endif + +USERS= zabbix +GROUPS= zabbix + +.if ${ZABBIX_BUILD} != "proxy" +PLIST_SUB= PROXY="@comment " +.else +PLIST_SUB= PROXY="" +.endif + +.if ${ZABBIX_BUILD} == "server" +PLIST_SUB+= SERVER="" +.else +PLIST_SUB+= SERVER="@comment " +.endif + +PLIST_SUB+= ZABBIX_BUILD=${ZABBIX_BUILD} PORTVERSION=${PORTVERSION} +SUB_LIST= ZABBIX_BUILD=${ZABBIX_BUILD} + +MAKE_ARGS+= ARCH=freebsd + +GNU_CONFIGURE= yes +CONFIGURE_ARGS+= --enable-${ZABBIX_BUILD} \ + --sysconfdir=${ETCDIR} \ + --datadir=${ETCDIR} \ + --with-iconv=${ICONV_PREFIX} + +.if ${ZABBIX_BUILD:Nagent*} && ${ZABBIX_BUILD} != "java" +LIB_DEPENDS+= libnetsnmp.so:net-mgmt/net-snmp + +CPPFLAGS+= -I${LOCALBASE}/include + +SUB_FILES= pkg-message + +CONFIGURE_ARGS+= --with-net-snmp + +OPTIONS_DEFINE= IPV6 FPING CURL LDAP IPMI SSH NMAP LIBXML2 UNIXODBC + +OPTIONS_DEFAULT= FPING CURL UNIXODBC MYSQL OPENSSL +OPTIONS_SUB= yes + +FPING_DESC= Build/install fping for ping checks +IPMI_DESC= Support for IPMI checks +LDAP_DESC= Support for LDAP server checks +NMAP_DESC= Build/install nmap for o/s detection +SSH_DESC= Support for SSH-based checks +UNIXODBC_DESC= Support for database checks via ODBC +LIBXML2_DESC= Support for libxml2 (required by monitoring VMware) + +OPTIONS_SINGLE= DB SSL +OPTIONS_SINGLE_DB?= MYSQL PGSQL ORACLE +OPTIONS_SINGLE_SSL= OPENSSL GNUTLS + +MYSQL_CONFIGURE_WITH= mysql +MYSQL_USES+= compiler:c11 mysql + +PGSQL_CONFIGURE_WITH= postgresql +PGSQL_USES+= pgsql + +SQLITE_CONFIGURE_WITH= sqlite3 +SQLITE_USES+= sqlite:3 + +ORACLE_CONFIGURE_WITH= oracle + +LDAP_CONFIGURE_WITH= ldap +LDAP_USE= OPENLDAP=yes + +IPMI_CONFIGURE_WITH= openipmi +IPMI_LIB_DEPENDS= libOpenIPMI.so:sysutils/openipmi + +FPING_RUN_DEPENDS= fping:net/fping + +SSH_CONFIGURE_WITH= ssh2 +SSH_LIB_DEPENDS= libssh2.so:security/libssh2 + +UNIXODBC_CONFIGURE_WITH=unixodbc +UNIXODBC_LIB_DEPENDS= libodbc.so:databases/unixODBC +.elif ${ZABBIX_BUILD} == "agent" +OPTIONS_SINGLE= SSL +OPTIONS_SINGLE_SSL= OPENSSL GNUTLS +.endif # if ${ZABBIX_BUILD} != "agent" && ${ZABBIX_BUILD} != "java" + +CURL_DESC= Support for web monitoring +CURL_CONFIGURE_WITH= libcurl +CURL_LIB_DEPENDS= libcurl.so:ftp/curl + +IPV6_CONFIGURE_ENABLE= ipv6 + +NMAP_RUN_DEPENDS= nmap:security/nmap \ + sudo:security/sudo + +LIBXML2_CONFIGURE_WITH= libxml2=${LOCALBASE} +LIBXML2_LIB_DEPENDS= libxml2.so:textproc/libxml2 + +OPENSSL_CONFIGURE_WITH= openssl +OPENSSL_USES= ssl +OPENSSL_VARS= BROKEN_SSL="libressl libressl-devel" \ + BROKEN_SSL_REASON="PSK is not provided by LibreSSL" + +GNUTLS_CONFIGURE_WITH= gnutls +GNUTLS_LIB_DEPENDS= libgnutls.so:security/gnutls + +.include + +.if ${ZABBIX_BUILD} == "agent2" +EXTRA_PATCHES= ${PATCHDIR}/agent2-patches +MAKE_ARGS+= CGO_CFLAGS="-I${LOCALBASE}/include" +.endif + +post-patch: + @${GREP} -rl "/etc/zabbix" ${WRKSRC} \ + | ${XARGS} ${REINPLACE_CMD} -e 's#/usr/local/etc#${ETCDIR}#g' + + @${REINPLACE_CMD} -e 's#/usr/sbin/fping#${LOCALBASE}/sbin/fping#g' \ + ${WRKSRC}/conf/zabbix_*.conf \ + ${WRKSRC}/src/zabbix_proxy/proxy.c \ + ${WRKSRC}/src/zabbix_server/server.c + +.if ${ZABBIX_BUILD} == "server" + @${REINPLACE_CMD} -e 's#/tmp/zabbix_server.pid#/var/run/zabbix/zabbix_server.pid#g' \ + ${WRKSRC}/conf/zabbix_server.conf \ + ${WRKSRC}/src/zabbix_server/server.c +.endif + +.if ${ZABBIX_BUILD} == "proxy" + @${REINPLACE_CMD} -e 's#/tmp/zabbix_proxy.pid#/var/run/zabbix/zabbix_proxy.pid#g' \ + ${WRKSRC}/conf/zabbix_proxy.conf \ + ${WRKSRC}/src/zabbix_proxy/proxy.c +.endif + +.if ${ZABBIX_BUILD} == "agent" + @${REINPLACE_CMD} -e 's#/tmp/zabbix_agentd.pid#/var/run/zabbix/zabbix_agentd.pid#g' \ + ${WRKSRC}/conf/zabbix_agentd.conf \ + ${WRKSRC}/src/zabbix_agent/zabbix_agentd.c +.endif + +.if ${ZABBIX_BUILD} == "agent2" + @${REINPLACE_CMD} -e 's#/tmp/zabbix_agent2.pid#/var/run/zabbix/zabbix_agent2.pid#g' \ + ${WRKSRC}/src/go/conf/zabbix_agent2.conf \ + ${WRKSRC}/src/go/pkg/pidfile/pidfile_nix.go +.endif + +.if ${ZABBIX_BUILD} == "java" + @${REINPLACE_CMD} -e 's#/tmp/zabbix_java.pid#/var/run/zabbix/zabbix_java.pid#g' \ + ${WRKSRC}/src/zabbix_java/settings.sh +.endif + +.if ${ZABBIX_BUILD:Nagent*} +. for d in mysql oracle postgresql sqlite3 + @${REINPLACE_CMD} \ + -e 's|/usr/bin/traceroute|/usr/sbin/traceroute|g' \ + -e 's|sudo /usr/bin/nmap|sudo ${LOCALBASE}/bin/nmap|g' \ + ${WRKSRC}/database/${d}/data.sql +. endfor +.endif + @${FIND} ${WRKSRC} -type f \( -name '*.bak' -or -name '*.orig' \) \ + -exec ${RM} {} + + +pre-configure: + @echo "ac_cv_env_PKG_CONFIG_set=${LOCALBASE}/bin/pkgconf" > ${WRKSRC}/config.cache + +.if ${ZABBIX_BUILD} == "agent2" +do-build: + cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} + +do-install: + ${MKDIR} ${STAGEDIR}${ETCDIR} + ${INSTALL_PROGRAM} ${WRKSRC}/src/go/bin/mock_server ${STAGEDIR}${LOCALBASE}/bin + ${INSTALL_PROGRAM} ${WRKSRC}/src/go/bin/zabbix_agent2 ${STAGEDIR}${LOCALBASE}/bin + ${CP} ${WRKSRC}/src/go/conf/zabbix_agent2.conf ${STAGEDIR}${ETCDIR}/zabbix_agent2.conf.sample + ${CP} ${WRKSRC}/src/go/conf/mock_server.conf ${STAGEDIR}${ETCDIR}/mock_server.conf.sample + ${CP} ${WRKSRC}/src/go/cmd/mock_server/active_checks.json ${STAGEDIR}${ETCDIR}/active_checks.json.sample + @${REINPLACE_CMD} -e 's#./go/src/zabbix/cmd/mock_server/active_checks.json#${ETCDIR}/active_checks.json#g' \ + ${STAGEDIR}${ETCDIR}/mock_server.conf.sample +.endif + +post-install: +.if ${ZABBIX_BUILD} == "java" + ${MV} ${STAGEDIR}${PREFIX}/sbin/zabbix_java/settings.sh \ + ${STAGEDIR}${PREFIX}/sbin/zabbix_java/settings.sh.sample + @${MKDIR} ${STAGEDIR}/var/run/zabbix +.endif + +.if ${ZABBIX_BUILD:Nagent*} && ${ZABBIX_BUILD} != "java" + ${MKDIR} ${STAGEDIR}${DATADIR}/${ZABBIX_BUILD:Q}/database + @${RM} ${WRKSRC}/database/*/Makefile* + (cd ${WRKSRC}/database/ && \ + ${COPYTREE_SHARE} "mysql oracle postgresql sqlite3" \ + ${STAGEDIR}${DATADIR}/${ZABBIX_BUILD:Q}/database/) + + ${MV} ${STAGEDIR}${ETCDIR}/zabbix_${ZABBIX_BUILD}.conf \ + ${STAGEDIR}${ETCDIR}/zabbix_${ZABBIX_BUILD}.conf.sample +.endif + +.if ${ZABBIX_BUILD} == "agent" + ${MV} ${STAGEDIR}${ETCDIR}/zabbix_${ZABBIX_BUILD}d.conf \ + ${STAGEDIR}${ETCDIR}/zabbix_${ZABBIX_BUILD}d.conf.sample +.endif + +.else # frontend +.include +.endif + +.include Index: net-mgmt/zabbix5-server/distinfo =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1589832899 +SHA256 (zabbix-5.0.0.tar.gz) = 5a1762fd2bb7275d9a28c6dfa9a6d46d84be749f9bf50a36eb8fcd20fb8bb6eb +SIZE (zabbix-5.0.0.tar.gz) = 18519888 Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_cmd_zabbix__agent2_testrun__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_cmd_zabbix__agent2_testrun__freebsd.go @@ -0,0 +1,105 @@ +--- src/go/cmd/zabbix_agent2/testrun_freebsd.go.orig 2020-05-19 19:29:14 UTC ++++ src/go/cmd/zabbix_agent2/testrun_freebsd.go +@@ -0,0 +1,102 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package main ++ ++import "zabbix.com/internal/agent/scheduler" ++ ++func checkMetrics(s scheduler.Scheduler) { ++ metrics := []string{ ++ `agent.hostname`, ++ `agent.ping`, ++ `agent.version`, ++ `system.localtime[utc]`, ++ `system.run[echo test]`, ++ `web.page.get[localhost,,80]`, ++ `web.page.perf[localhost,,80]`, ++ `web.page.regexp[localhost,,80,OK]`, ++ `vfs.file.size[/etc/passwd]`, ++ `vfs.file.time[/etc/passwd,modify]`, ++ `vfs.file.exists[/etc/passwd]`, ++ `vfs.file.contents[/etc/passwd]`, ++ `vfs.file.regexp[/etc/passwd,root]`, ++ `vfs.file.regmatch[/etc/passwd,root]`, ++ `vfs.file.md5sum[/etc/passwd]`, ++ `vfs.file.cksum[/etc/passwd]`, ++ `vfs.dir.size[/var/log]`, ++ `vfs.dir.count[/var/log]`, ++ `net.dns[,zabbix.com]`, ++ `net.dns.record[,zabbix.com]`, ++ `net.tcp.dns[,zabbix.com]`, ++ `net.tcp.dns.query[,zabbix.com]`, ++ `net.tcp.port[,80]`, ++ `system.users.num`, ++ `log[logfile]`, ++ `log.count[logfile]`, ++ `logrt[logfile]`, ++ `logrt.count[logfile]`, ++ `zabbix.stats[127.0.0.1,10051]`, ++ `kernel.maxfiles`, ++ `kernel.maxproc`, ++ `vfs.fs.size[/,free]`, ++ `vfs.fs.inode[/,free]`, ++ `vfs.fs.discovery`, ++ `vfs.dev.write[sda,operations]`, ++ `net.tcp.listen[80]`, ++ `net.udp.listen[68]`, ++ `net.if.in[lo,bytes]`, ++ `net.if.out[lo,bytes]`, ++ `net.if.total[lo,bytes]`, ++ `net.if.collisions[lo]`, ++ `net.if.discovery`, ++ `vm.memory.size[total]`, ++ `proc.cpu.util[inetd]`, ++ `proc.num[inetd]`, ++ `proc.mem[inetd]`, ++ `system.cpu.switches`, ++ `system.cpu.intr`, ++ `system.cpu.util[all,user,avg1]`, ++ `system.cpu.load[all,avg1]`, ++ `system.cpu.num[online]`, ++ `system.cpu.discovery`, ++ `system.uname`, ++ `system.hw.chassis`, ++ `system.hw.cpu`, ++ `system.hw.devices`, ++ `system.hw.macaddr`, ++ `system.sw.arch`, ++ `system.sw.os`, ++ `system.sw.packages`, ++ `system.swap.size[all,free]`, ++ `system.swap.in[all]`, ++ `system.swap.out[all]`, ++ `system.uptime`, ++ `system.boottime`, ++ `sensor[w83781d-i2c-0-2d,temp1]`, ++ `net.tcp.service[ssh,127.0.0.1,22]`, ++ `net.tcp.service.perf[ssh,127.0.0.1,22]`, ++ `net.udp.service[ntp,127.0.0.1,123]`, ++ `net.udp.service.perf[ntp,127.0.0.1,123]`, ++ `system.hostname`, ++ } ++ ++ for _, metric := range metrics { ++ checkMetric(s, metric) ++ } ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_pkg_zbxlib_checks__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_pkg_zbxlib_checks__freebsd.go @@ -0,0 +1,103 @@ +--- src/go/pkg/zbxlib/checks_freebsd.go.orig 2020-05-19 19:28:35 UTC ++++ src/go/pkg/zbxlib/checks_freebsd.go +@@ -0,0 +1,100 @@ ++// +build freebsd ++ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package zbxlib ++ ++/* cspell:disable */ ++ ++/* ++#cgo CFLAGS: -I${SRCDIR}/../../../../../include ++ ++#include "common.h" ++#include "sysinfo.h" ++ ++int SYSTEM_LOCALTIME(AGENT_REQUEST *request, AGENT_RESULT *result); ++int NET_DNS(AGENT_REQUEST *request, AGENT_RESULT *result); ++int NET_DNS_RECORD(AGENT_REQUEST *request, AGENT_RESULT *result); ++int SYSTEM_BOOTTIME(AGENT_REQUEST *request, AGENT_RESULT *result); ++int NET_TCP_LISTEN(AGENT_REQUEST *request, AGENT_RESULT *result); ++int NET_TCP_PORT(AGENT_REQUEST *request, AGENT_RESULT *result); ++int CHECK_SERVICE(AGENT_REQUEST *request, AGENT_RESULT *result); ++int CHECK_SERVICE_PERF(AGENT_REQUEST *request, AGENT_RESULT *result); ++int NET_UDP_LISTEN(AGENT_REQUEST *request, AGENT_RESULT *result); ++int SYSTEM_CPU_LOAD(AGENT_REQUEST *request, AGENT_RESULT *result); ++int SYSTEM_USERS_NUM(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_DIR_COUNT(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_DIR_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_FS_INODE(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VFS_FS_GET(AGENT_REQUEST *request, AGENT_RESULT *result); ++int VM_MEMORY_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result); ++ ++*/ ++import "C" ++ ++import ( ++ "unsafe" ++) ++ ++func resolveMetric(key string) (cfunc unsafe.Pointer) { ++ switch key { ++ case "system.localtime": ++ return unsafe.Pointer(C.SYSTEM_LOCALTIME) ++ case "net.dns": ++ return unsafe.Pointer(C.NET_DNS) ++ case "net.dns.record": ++ return unsafe.Pointer(C.NET_DNS_RECORD) ++ case "system.boottime": ++ return unsafe.Pointer(C.SYSTEM_BOOTTIME) ++ case "net.tcp.listen": ++ return unsafe.Pointer(C.NET_TCP_LISTEN) ++ case "net.tcp.port": ++ return unsafe.Pointer(C.NET_TCP_PORT) ++ case "net.tcp.service", "net.udp.service": ++ return unsafe.Pointer(C.CHECK_SERVICE) ++ case "net.tcp.service.perf", "net.udp.service.perf": ++ return unsafe.Pointer(C.CHECK_SERVICE_PERF) ++ case "net.udp.listen": ++ return unsafe.Pointer(C.NET_UDP_LISTEN) ++ case "system.cpu.load": ++ return unsafe.Pointer(C.SYSTEM_CPU_LOAD) ++ case "system.users.num": ++ return unsafe.Pointer(C.SYSTEM_USERS_NUM) ++ case "vfs.dir.count": ++ return unsafe.Pointer(C.VFS_DIR_COUNT) ++ case "vfs.dir.size": ++ return unsafe.Pointer(C.VFS_DIR_SIZE) ++ case "vfs.fs.discovery": ++ return unsafe.Pointer(C.VFS_FS_DISCOVERY) ++ case "vfs.fs.inode": ++ return unsafe.Pointer(C.VFS_FS_INODE) ++ case "vfs.fs.size": ++ return unsafe.Pointer(C.VFS_FS_SIZE) ++ case "vfs.fs.get": ++ return unsafe.Pointer(C.VFS_FS_GET) ++ case "vm.memory.size": ++ return unsafe.Pointer(C.VM_MEMORY_SIZE) ++ ++ default: ++ return ++ } ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_pkg_zbxlib_globals__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_pkg_zbxlib_globals__freebsd.go @@ -0,0 +1,125 @@ +--- src/go/pkg/zbxlib/globals_freebsd.go.orig 2020-05-19 19:28:39 UTC ++++ src/go/pkg/zbxlib/globals_freebsd.go +@@ -0,0 +1,122 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package zbxlib ++ ++/* ++#cgo LDFLAGS: ${SRCDIR}/../../../zabbix_agent/logfiles/libzbxlogfiles.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxcomms/libzbxcomms.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxcommon/libzbxcommon.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxcrypto/libzbxcrypto.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsys/libzbxsys.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxnix/libzbxnix.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxconf/libzbxconf.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxhttp/libzbxhttp.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxcompress/libzbxcompress.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxregexp/libzbxregexp.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsysinfo/libzbxagentsysinfo.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsysinfo/common/libcommonsysinfo.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsysinfo/simple/libsimplesysinfo.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxexec/libzbxexec.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxalgo/libzbxalgo.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxjson/libzbxjson.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsysinfo/freebsd/libspechostnamesysinfo.a ++#cgo LDFLAGS: ${SRCDIR}/../../../libs/zbxsysinfo/freebsd/libspecsysinfo.a ++#cgo LDFLAGS: -lz -lpcre ++ ++#include "common.h" ++#include "sysinfo.h" ++#include "comms.h" ++#include "log.h" ++#include "../src/zabbix_agent/metrics.h" ++#include "../src/zabbix_agent/logfiles/logfiles.h" ++ ++typedef ZBX_ACTIVE_METRIC* ZBX_ACTIVE_METRIC_LP; ++typedef zbx_vector_ptr_t * zbx_vector_ptr_lp_t; ++ ++int CONFIG_MAX_LINES_PER_SECOND = 20; ++char *CONFIG_HOSTNAME = NULL; ++int CONFIG_UNSAFE_USER_PARAMETERS= 0; ++int CONFIG_ENABLE_REMOTE_COMMANDS= 0; ++int CONFIG_LOG_REMOTE_COMMANDS= 0; ++char *CONFIG_SOURCE_IP= NULL; ++ ++unsigned int configured_tls_connect_mode = ZBX_TCP_SEC_UNENCRYPTED; ++unsigned int configured_tls_accept_modes = ZBX_TCP_SEC_UNENCRYPTED; ++ ++char *CONFIG_TLS_CONNECT= NULL; ++char *CONFIG_TLS_ACCEPT = NULL; ++char *CONFIG_TLS_CA_FILE = NULL; ++char *CONFIG_TLS_CRL_FILE = NULL; ++char *CONFIG_TLS_SERVER_CERT_ISSUER = NULL; ++char *CONFIG_TLS_SERVER_CERT_SUBJECT = NULL; ++char *CONFIG_TLS_CERT_FILE = NULL; ++char *CONFIG_TLS_KEY_FILE = NULL; ++char *CONFIG_TLS_PSK_IDENTITY = NULL; ++char *CONFIG_TLS_PSK_FILE = NULL; ++ ++char *CONFIG_TLS_CIPHER_CERT13 = NULL; ++char *CONFIG_TLS_CIPHER_CERT = NULL; ++char *CONFIG_TLS_CIPHER_PSK13 = NULL; ++char *CONFIG_TLS_CIPHER_PSK = NULL; ++char *CONFIG_TLS_CIPHER_ALL13 = NULL; ++char *CONFIG_TLS_CIPHER_ALL = NULL; ++char *CONFIG_TLS_CIPHER_CMD13 = NULL; ++char *CONFIG_TLS_CIPHER_CMD = NULL; ++ ++int CONFIG_PASSIVE_FORKS = 0; ++int CONFIG_ACTIVE_FORKS = 0; ++ ++const char *progname = NULL; ++const char title_message[] = "agent"; ++const char syslog_app_name[] = "agent"; ++const char *usage_message[] = {}; ++unsigned char program_type = 0x80; ++const char *help_message[] = {}; ++ ++ZBX_METRIC parameters_agent[] = {NULL}; ++ZBX_METRIC parameters_specific[] = {NULL}; ++ ++void zbx_on_exit(int ret) ++{ ++} ++ ++int zbx_procstat_collector_started(void) ++{ ++ return FAIL; ++} ++ ++int zbx_procstat_get_util(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags, ++ int period, int type, double *value, char **errmsg) ++{ ++ return FAIL; ++} ++ ++int get_cpustat(AGENT_RESULT *result, int cpu_num, int state, int mode) ++{ ++ return SYSINFO_RET_FAIL; ++} ++ ++char *strerror_from_system(unsigned long error) ++{ ++ return zbx_strerror(errno); ++} ++ ++*/ ++import "C" Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_netif_netif__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_netif_netif__freebsd.go @@ -0,0 +1,207 @@ +--- src/go/plugins/net/netif/netif_freebsd.go.orig 2020-05-20 09:43:23 UTC ++++ src/go/plugins/net/netif/netif_freebsd.go +@@ -0,0 +1,204 @@ ++// +build: freebsd ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package netif ++ ++import ( ++ "bufio" ++ "encoding/json" ++ "errors" ++ "fmt" ++ "strconv" ++ "strings" ++ ++ "zabbix.com/pkg/plugin" ++ "zabbix.com/pkg/std" ++) ++ ++const ( ++ errorCannotFindIf = "Cannot find information for this network interface in /compat/linux/proc/net/dev." ++ errorCannotOpenNetDev = "Cannot open /compat/linux/proc/net/dev: %s" ++) ++ ++var stdOs std.Os ++ ++var mapNetStatIn = map[string]uint{ ++ "bytes": 0, ++ "packets": 1, ++ "errors": 2, ++ "dropped": 3, ++ "overruns": 4, ++ "frame": 5, ++ "compressed": 6, ++ "multicast": 7, ++} ++ ++var mapNetStatOut = map[string]uint{ ++ "bytes": 8, ++ "packets": 9, ++ "errors": 10, ++ "dropped": 11, ++ "overruns": 12, ++ "collisions": 13, ++ "carrier": 14, ++ "compressed": 15, ++} ++ ++func (p *Plugin) addStatNum(statName string, mapNetStat map[string]uint, statNums *[]uint) error { ++ if statNum, ok := mapNetStat[statName]; ok { ++ *statNums = append(*statNums, statNum) ++ } else { ++ return errors.New(errorInvalidSecondParam) ++ } ++ return nil ++} ++ ++func (p *Plugin) getNetStats(networkIf string, statName string, dir dirFlag) (result uint64, err error) { ++ var statNums []uint ++ ++ if dir&dirIn != 0 { ++ if err = p.addStatNum(statName, mapNetStatIn, &statNums); err != nil { ++ return ++ } ++ } ++ ++ if dir&dirOut != 0 { ++ if err = p.addStatNum(statName, mapNetStatOut, &statNums); err != nil { ++ return ++ } ++ } ++ ++ file, err := stdOs.Open("/compat/linux/proc/net/dev") ++ if err != nil { ++ return 0, fmt.Errorf(errorCannotOpenNetDev, err) ++ } ++ defer file.Close() ++ ++ var total uint64 ++loop: ++ for sLines := bufio.NewScanner(file); sLines.Scan(); { ++ dev := strings.Split(sLines.Text(), ":") ++ ++ if len(dev) > 1 && networkIf == strings.TrimSpace(dev[0]) { ++ stats := strings.Fields(dev[1]) ++ ++ if len(stats) >= 16 { ++ for _, statNum := range statNums { ++ var res uint64 ++ ++ if res, err = strconv.ParseUint(stats[statNum], 10, 64); err != nil { ++ break loop ++ } ++ total += res ++ } ++ return total, nil ++ } ++ break ++ } ++ } ++ err = errors.New(errorCannotFindIf) ++ return ++} ++ ++func (p *Plugin) getDevDiscovery() (netInterfaces []msgIfDiscovery, err error) { ++ var f std.File ++ if f, err = stdOs.Open("/compat/linux/proc/net/dev"); err != nil { ++ return nil, fmt.Errorf(errorCannotOpenNetDev, err) ++ } ++ defer f.Close() ++ ++ netInterfaces = make([]msgIfDiscovery, 0) ++ for sLines := bufio.NewScanner(f); sLines.Scan(); { ++ dev := strings.Split(sLines.Text(), ":") ++ if len(dev) > 1 { ++ netInterfaces = append(netInterfaces, msgIfDiscovery{strings.TrimSpace(dev[0])}) ++ } ++ } ++ ++ return netInterfaces, nil ++} ++ ++// Export - ++func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error) { ++ var direction dirFlag ++ var mode string ++ ++ switch key { ++ case "net.if.discovery": ++ if len(params) > 0 { ++ return nil, errors.New(errorParametersNotAllowed) ++ } ++ var devices []msgIfDiscovery ++ if devices, err = p.getDevDiscovery(); err != nil { ++ return ++ } ++ var b []byte ++ if b, err = json.Marshal(devices); err != nil { ++ return ++ } ++ return string(b), nil ++ case "net.if.collisions": ++ if len(params) > 1 { ++ return nil, errors.New(errorTooManyParams) ++ } ++ ++ if len(params) < 1 || params[0] == "" { ++ return nil, errors.New(errorEmptyIfName) ++ } ++ return p.getNetStats(params[0], "collisions", dirOut) ++ case "net.if.in": ++ direction = dirIn ++ case "net.if.out": ++ direction = dirOut ++ case "net.if.total": ++ direction = dirIn | dirOut ++ default: ++ /* SHOULD_NEVER_HAPPEN */ ++ return nil, errors.New(errorUnsupportedMetric) ++ } ++ ++ if len(params) < 1 || params[0] == "" { ++ return nil, errors.New(errorEmptyIfName) ++ } ++ ++ if len(params) > 2 { ++ return nil, errors.New(errorTooManyParams) ++ } ++ ++ if len(params) == 2 && params[1] != "" { ++ mode = params[1] ++ } else { ++ mode = "bytes" ++ } ++ ++ return p.getNetStats(params[0], mode, direction) ++} ++ ++func init() { ++ stdOs = std.NewOs() ++ ++ plugin.RegisterMetrics(&impl, "NetIf", ++ "net.if.collisions", "Returns number of out-of-window collisions.", ++ "net.if.in", "Returns incoming traffic statistics on network interface.", ++ "net.if.out", "Returns outgoing traffic statistics on network interface.", ++ "net.if.total", "Returns sum of incoming and outgoing traffic statistics on network interface.", ++ "net.if.discovery", "Returns list of network interfaces. Used for low-level discovery.") ++ ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_netif_netif__unsupported.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_netif_netif__unsupported.go @@ -0,0 +1,8 @@ +--- src/go/plugins/net/netif/netif_unsupported.go.orig 2020-05-20 09:53:44 UTC ++++ src/go/plugins/net/netif/netif_unsupported.go +@@ -1,4 +1,4 @@ +-// +build !linux,!windows ++// +build !linux,!windows,!freebsd + + /* + ** Zabbix Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_tcp_tcp__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_net_tcp_tcp__freebsd.go @@ -0,0 +1,38 @@ +--- src/go/plugins/net/tcp/tcp_freebsd.go.orig 2020-05-20 10:52:02 UTC ++++ src/go/plugins/net/tcp/tcp_freebsd.go +@@ -0,0 +1,35 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package tcpudp ++ ++import ( ++ "errors" ++ ++ "zabbix.com/pkg/plugin" ++) ++ ++func exportSystemTcpListen(port uint16) (result interface{}, err error) { ++ return nil, errors.New("Not supported.") ++} ++ ++func init() { ++ plugin.RegisterMetrics(&impl, "TCP", ++ "net.tcp.port", "Checks if it is possible to make TCP connection to specified port.") ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_plugins__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_plugins__freebsd.go @@ -0,0 +1,42 @@ +--- src/go/plugins/plugins_freebsd.go.orig 2020-05-20 11:05:00 UTC ++++ src/go/plugins/plugins_freebsd.go +@@ -0,0 +1,39 @@ ++// build: freebsd ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package plugins ++ ++import ( ++ _ "zabbix.com/plugins/log" ++ _ "zabbix.com/plugins/memcached" ++ _ "zabbix.com/plugins/mysql" ++ _ "zabbix.com/plugins/net/netif" ++ _ "zabbix.com/plugins/net/tcp" ++ _ "zabbix.com/plugins/net/udp" ++ _ "zabbix.com/plugins/proc" ++ _ "zabbix.com/plugins/redis" ++ _ "zabbix.com/plugins/systemrun" ++ _ "zabbix.com/plugins/system/cpu" ++ _ "zabbix.com/plugins/system/uptime" ++ _ "zabbix.com/plugins/web" ++ _ "zabbix.com/plugins/zabbix/async" ++ _ "zabbix.com/plugins/zabbix/stats" ++ _ "zabbix.com/plugins/zabbix/sync" ++) Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_proc_proc__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_proc_proc__freebsd.go @@ -0,0 +1,413 @@ +--- src/go/plugins/proc/proc_freebsd.go.orig 2020-05-20 10:37:47 UTC ++++ src/go/plugins/proc/proc_freebsd.go +@@ -0,0 +1,410 @@ ++// +build freebsd ++ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package proc ++ ++/* ++#include ++*/ ++import "C" ++ ++import ( ++ "errors" ++ "math" ++ "os/user" ++ "regexp" ++ "strconv" ++ "sync" ++ "time" ++ ++ "zabbix.com/pkg/log" ++ "zabbix.com/pkg/plugin" ++) ++ ++const ( ++ maxInactivityPeriod = time.Hour * 25 ++ maxHistory = 60*15 + 1 ++) ++ ++// Plugin - ++type Plugin struct { ++ plugin.Base ++ queries map[procQuery]*cpuUtilStats ++ mutex sync.Mutex ++ scanid uint64 ++ stats map[int64]*cpuUtil ++} ++ ++var impl Plugin = Plugin{ ++ stats: make(map[int64]*cpuUtil), ++ queries: make(map[procQuery]*cpuUtilStats), ++} ++ ++type historyIndex int ++ ++func (h historyIndex) inc() historyIndex { ++ h++ ++ if h == maxHistory { ++ h = 0 ++ } ++ return h ++} ++ ++func (h historyIndex) dec() historyIndex { ++ h-- ++ if h < 0 { ++ h = maxHistory - 1 ++ } ++ return h ++} ++ ++func (h historyIndex) sub(value historyIndex) historyIndex { ++ h -= value ++ for h < 0 { ++ h += maxHistory ++ } ++ return h ++} ++ ++type cpuUtilData struct { ++ utime uint64 ++ stime uint64 ++ timestamp time.Time ++} ++ ++type cpuUtilStats struct { ++ scanid uint64 ++ accessed time.Time ++ err error ++ cmdlinePattern *regexp.Regexp ++ history []cpuUtilData ++ tail historyIndex ++ head historyIndex ++} ++ ++type cpuUtilQuery struct { ++ procQuery ++ userid int64 ++ pids []int64 ++ cmdlinePattern *regexp.Regexp ++ utime uint64 ++ stime uint64 ++} ++ ++type procQuery struct { ++ name string ++ user string ++ cmdline string ++} ++ ++const ( ++ procInfoPid = 1 << iota ++ procInfoName ++ procInfoUser ++ procInfoCmdline ++) ++ ++type procInfo struct { ++ pid int64 ++ name string ++ userid int64 ++ cmdline string ++ arg0 string ++} ++ ++type cpuUtil struct { ++ utime uint64 ++ stime uint64 ++ started uint64 ++ err error ++} ++ ++ ++func (q *cpuUtilQuery) match(p *procInfo) bool { ++ if q.name != "" && q.name != p.name && q.name != p.arg0 { ++ return false ++ } ++ if q.user != "" && q.userid != p.userid { ++ return false ++ } ++ if q.cmdline != "" && !q.cmdlinePattern.Match([]byte(p.cmdline)) { ++ return false ++ } ++ return true ++} ++ ++func newCpuUtilQuery(q *procQuery, pattern *regexp.Regexp) (query *cpuUtilQuery, err error) { ++ query = &cpuUtilQuery{procQuery: *q} ++ if q.user != "" { ++ var u *user.User ++ if u, err = user.Lookup(q.user); err != nil { ++ return ++ } ++ if query.userid, err = strconv.ParseInt(u.Uid, 10, 64); err != nil { ++ return ++ } ++ } ++ query.cmdlinePattern = pattern ++ return ++} ++ ++func (p *Plugin) prepareQueries() (queries []*cpuUtilQuery, flags int) { ++ now := time.Now() ++ flags = procInfoPid ++ ++ queries = make([]*cpuUtilQuery, 0, len(p.queries)) ++ p.mutex.Lock() ++ for q, stats := range p.queries { ++ if now.Sub(stats.accessed) > maxInactivityPeriod { ++ p.Debugf("removed unused CPU utilisation query %+v", q) ++ delete(p.queries, q) ++ continue ++ } ++ var query *cpuUtilQuery ++ if query, stats.err = newCpuUtilQuery(&q, stats.cmdlinePattern); stats.err != nil { ++ p.Debugf("cannot create CPU utilisation query %+v: %s", q, stats.err) ++ continue ++ } ++ queries = append(queries, query) ++ stats.scanid = p.scanid ++ if q.name != "" { ++ flags |= procInfoName | procInfoCmdline ++ } ++ if q.user != "" { ++ flags |= procInfoUser ++ } ++ if q.cmdline != "" { ++ flags |= procInfoCmdline ++ } ++ } ++ p.mutex.Unlock() ++ return ++} ++ ++func (p *Plugin) Collect() (err error) { ++ if log.CheckLogLevel(log.Trace) { ++ p.Tracef("In %s() queries:%d", log.Caller(), len(p.queries)) ++ defer p.Tracef("End of %s()", log.Caller()) ++ } ++ p.scanid++ ++ queries, flags := p.prepareQueries() ++ var processes []*procInfo ++ if processes, err = p.getProcesses(flags); err != nil { ++ return ++ } ++ p.Tracef("%s() queries:%d", log.Caller(), len(p.queries)) ++ ++ stats := make(map[int64]*cpuUtil) ++ // find processes matching prepared queries ++ for _, p := range processes { ++ var monitored bool ++ for _, q := range queries { ++ if q.match(p) { ++ q.pids = append(q.pids, p.pid) ++ monitored = true ++ } ++ } ++ if monitored { ++ stats[p.pid] = &cpuUtil{} ++ } ++ } ++ ++ if log.CheckLogLevel(log.Trace) { ++ for _, q := range queries { ++ p.Tracef("%s() name:%s user:%s cmdline:%s pids:%v", log.Caller(), q.name, q.user, q.cmdline, q.pids) ++ } ++ } ++ ++ now := time.Now() ++ for pid, stat := range stats { ++ p.getProcCpuUtil(pid, stat) ++ if stat.err != nil { ++ p.Debugf("cannot get process %d CPU utilisation statistics: %s", pid, stat.err) ++ } ++ } ++ ++ // gather process utilization for queries ++ for _, q := range queries { ++ for _, pid := range q.pids { ++ var stat, last *cpuUtil ++ var ok bool ++ if stat, ok = stats[pid]; !ok || stat.err != nil { ++ continue ++ } ++ if last, ok = p.stats[pid]; !ok || stat.err != nil { ++ continue ++ } ++ if stat.started == last.started { ++ q.utime += stat.utime - last.utime ++ q.stime += stat.stime - last.stime ++ } ++ } ++ } ++ ++ p.stats = stats ++ ++ // update statistics ++ p.Tracef("%s() update statistics", log.Caller()) ++ p.mutex.Lock() ++ for _, q := range queries { ++ if stat, ok := p.queries[q.procQuery]; ok { ++ if stat.scanid != p.scanid { ++ continue ++ } ++ var last *cpuUtilData ++ if stat.tail != stat.head { ++ last = &stat.history[stat.tail.dec()] ++ } ++ slot := &stat.history[stat.tail] ++ slot.utime = q.utime ++ slot.stime = q.stime ++ slot.timestamp = now ++ if last != nil { ++ slot.utime += last.utime ++ slot.stime += last.stime ++ } ++ stat.tail = stat.tail.inc() ++ if stat.tail == stat.head { ++ stat.head = stat.head.inc() ++ } ++ } ++ } ++ p.mutex.Unlock() ++ ++ return nil ++} ++ ++func (p *Plugin) Period() int { ++ return 1 ++} ++ ++const ( ++ timeUser = 1 << iota ++ timeSystem ++ timeTotal = timeUser | timeSystem ++) ++ ++// Export - ++func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error) { ++ if ctx == nil { ++ return nil, errors.New("This item is available only in daemon mode.") ++ } ++ ++ var name, user, cmdline, mode, utiltype string ++ switch len(params) { ++ case 5: ++ mode = params[4] ++ fallthrough ++ case 4: ++ cmdline = params[3] ++ fallthrough ++ case 3: ++ utiltype = params[2] ++ fallthrough ++ case 2: ++ user = params[1] ++ fallthrough ++ case 1: ++ name = params[0] ++ case 0: ++ default: ++ return nil, errors.New("Too many parameters.") ++ } ++ ++ var utilrange historyIndex ++ switch mode { ++ case "avg1", "": ++ utilrange = 60 ++ case "avg5": ++ utilrange = 300 ++ case "avg15": ++ utilrange = 900 ++ default: ++ return nil, errors.New("Invalid fifth parameter.") ++ } ++ ++ var typeflags uint ++ switch utiltype { ++ case "total", "": ++ typeflags |= timeTotal ++ case "user": ++ typeflags |= timeUser ++ case "system": ++ typeflags |= timeSystem ++ default: ++ return nil, errors.New("Invalid third parameter.") ++ } ++ ++ now := time.Now() ++ query := procQuery{name: name, user: user, cmdline: cmdline} ++ p.mutex.Lock() ++ defer p.mutex.Unlock() ++ if stats, ok := p.queries[query]; ok { ++ stats.accessed = now ++ if stats.err != nil { ++ p.Debugf("CPU utilisation gathering error %s", err) ++ return nil, stats.err ++ } ++ if stats.tail == stats.head { ++ return ++ } ++ totalnum := stats.tail - stats.head ++ if totalnum < 0 { ++ totalnum += maxHistory ++ } ++ if totalnum < 2 { ++ return ++ } ++ if totalnum < utilrange { ++ utilrange = totalnum ++ } ++ tail := &stats.history[stats.tail.dec()] ++ head := &stats.history[stats.tail.sub(utilrange)] ++ ++ var ticks uint64 ++ if typeflags&timeUser != 0 { ++ ticks += tail.utime - head.utime ++ } ++ if typeflags&timeSystem != 0 { ++ ticks += tail.stime - head.stime ++ } ++ /* 1e9 (nanoseconds) * 1e2 (percent) * 1e1 (one digit decimal place) */ ++ ticks *= 1e12 ++ ticks /= uint64(tail.timestamp.Sub(head.timestamp)) ++ ++ return math.Round(float64(ticks)/float64(C.sysconf(C._SC_CLK_TCK))) / 10, nil ++ } ++ stats := &cpuUtilStats{accessed: now, history: make([]cpuUtilData, maxHistory)} ++ if cmdline != "" { ++ stats.cmdlinePattern, err = regexp.Compile(cmdline) ++ } ++ if err == nil { ++ p.queries[query] = stats ++ p.Debugf("registered new CPU utilisation query: %s, %s, %s", name, user, cmdline) ++ } else { ++ p.Debugf("cannot register CPU utilisation query: %s", err) ++ } ++ return ++} ++ ++func init() { ++ plugin.RegisterMetrics(&impl, "Proc", "proc.cpu.util", "Process CPU utilisation percentage.") ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_proc_procfs__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_proc_procfs__freebsd.go @@ -0,0 +1,196 @@ +--- src/go/plugins/proc/procfs_freebsd.go.orig 2020-05-20 10:37:05 UTC ++++ src/go/plugins/proc/procfs_freebsd.go +@@ -0,0 +1,193 @@ ++// +build freebsd ++ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package proc ++ ++import ( ++ "bytes" ++ "fmt" ++ "io" ++ "os" ++ "strconv" ++ "syscall" ++) ++ ++func read2k(filename string) (data []byte, err error) { ++ fd, err := syscall.Open(filename, syscall.O_RDONLY, 0) ++ if err != nil { ++ return ++ } ++ var n int ++ b := make([]byte, 2048) ++ if n, err = syscall.Read(fd, b); err == nil { ++ data = b[:n] ++ } ++ syscall.Close(fd) ++ return ++} ++ ++func readAll(filename string) (data []byte, err error) { ++ fd, err := syscall.Open(filename, syscall.O_RDONLY, 0) ++ if err != nil { ++ return ++ } ++ defer syscall.Close(fd) ++ var buf bytes.Buffer ++ b := make([]byte, 2048) ++ for { ++ var n int ++ if n, err = syscall.Read(fd, b); err != nil { ++ return ++ } ++ if n == 0 { ++ return buf.Bytes(), nil ++ } ++ if _, err = buf.Write(b[:n]); err != nil { ++ return ++ } ++ } ++} ++ ++func (p *Plugin) getProcessName(pid string) (name string, err error) { ++ var data []byte ++ if data, err = read2k("/compat/linux/proc/" + pid + "/stat"); err != nil { ++ return ++ } ++ var left, right int ++ if right = bytes.LastIndexByte(data, ')'); right == -1 { ++ return "", fmt.Errorf("cannot find process name ending position in /compat/linux/proc/%s/stat", pid) ++ } ++ if left = bytes.IndexByte(data[:right], '('); left == -1 { ++ return "", fmt.Errorf("cannot find process name starting position in /compat/linux/proc/%s/stat", pid) ++ } ++ return string(data[left+1 : right]), nil ++} ++ ++func (p *Plugin) getProcessUserID(pid string) (userid int64, err error) { ++ var fi os.FileInfo ++ if fi, err = os.Stat("/compat/linux/proc/" + pid); err != nil { ++ return ++ } ++ return int64(fi.Sys().(*syscall.Stat_t).Uid), nil ++} ++ ++func (p *Plugin) getProcessCmdline(pid string, flags int) (arg0 string, cmdline string, err error) { ++ var data []byte ++ if data, err = readAll("/compat/linux/proc/" + pid + "/cmdline"); err != nil { ++ return ++ } ++ ++ if flags&procInfoName != 0 { ++ if end := bytes.IndexByte(data, 0); end != -1 { ++ if pos := bytes.LastIndexByte(data[:end], '/'); pos != -1 { ++ arg0 = string(data[pos+1 : end]) ++ } else { ++ arg0 = string(data[:end]) ++ } ++ } else { ++ arg0 = string(data) ++ } ++ } ++ ++ for i := 0; i < len(data); i++ { ++ if data[i] == 0 { ++ data[i] = ' ' ++ } ++ } ++ ++ if len(data) != 0 && data[len(data)-1] == ' ' { ++ data = data[:len(data)-1] ++ } ++ ++ return arg0, string(data), nil ++} ++ ++func (p *Plugin) getProcCpuUtil(pid int64, stat *cpuUtil) { ++ var data []byte ++ if data, stat.err = read2k(fmt.Sprintf("/compat/linux/proc/%d/stat", pid)); stat.err != nil { ++ return ++ } ++ var pos int ++ if pos = bytes.LastIndexByte(data, ')'); pos == -1 || len(data[pos:]) < 2 { ++ stat.err = fmt.Errorf("cannot find CPU statistic starting position in /compat/linux/proc/%d/stat", pid) ++ return ++ } ++ stats := bytes.Split(data[pos+2:], []byte{' '}) ++ if len(stats) < 20 { ++ stat.err = fmt.Errorf("cannot parse CPU statistics in /compat/linux/proc/%d/stat", pid) ++ return ++ } ++ if stat.utime, stat.err = strconv.ParseUint(string(stats[11]), 10, 64); stat.err != nil { ++ return ++ } ++ if stat.stime, stat.err = strconv.ParseUint(string(stats[12]), 10, 64); stat.err != nil { ++ return ++ } ++ if stat.started, stat.err = strconv.ParseUint(string(stats[19]), 10, 64); stat.err != nil { ++ return ++ } ++} ++ ++func (p *Plugin) getProcesses(flags int) (processes []*procInfo, err error) { ++ var entries []os.FileInfo ++ f, err := os.Open("/compat/linux/proc") ++ if err != nil { ++ return nil, err ++ } ++ defer f.Close() ++ ++ for entries, err = f.Readdir(1); err != io.EOF; entries, err = f.Readdir(1) { ++ if err != nil { ++ return nil, err ++ } ++ ++ if !entries[0].IsDir() { ++ continue ++ } ++ var pid int64 ++ var tmperr error ++ if pid, tmperr = strconv.ParseInt(entries[0].Name(), 10, 64); tmperr != nil { ++ continue ++ } ++ info := &procInfo{pid: pid} ++ if flags&procInfoName != 0 { ++ if info.name, tmperr = p.getProcessName(entries[0].Name()); tmperr != nil { ++ p.Debugf("cannot get process %s name: %s", entries[0].Name(), tmperr) ++ continue ++ } ++ } ++ if flags&procInfoUser != 0 { ++ if info.userid, tmperr = p.getProcessUserID(entries[0].Name()); tmperr != nil { ++ p.Debugf("cannot get process %s user id: %s", entries[0].Name(), tmperr) ++ continue ++ } ++ } ++ if flags&procInfoCmdline != 0 { ++ if info.arg0, info.cmdline, tmperr = p.getProcessCmdline(entries[0].Name(), flags); tmperr != nil { ++ p.Debugf("cannot get process %s command line: %s", entries[0].Name(), tmperr) ++ continue ++ } ++ } ++ processes = append(processes, info) ++ } ++ ++ return processes, nil ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_cpu_cpu__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_cpu_cpu__freebsd.go @@ -0,0 +1,152 @@ +--- src/go/plugins/system/cpu/cpu_freebsd.go.orig 2020-05-20 10:00:53 UTC ++++ src/go/plugins/system/cpu/cpu_freebsd.go +@@ -0,0 +1,149 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package cpu ++ ++/* ++#include ++*/ ++import "C" ++ ++import ( ++ "bufio" ++ "bytes" ++ "os" ++ "strconv" ++ "strings" ++ ++ "zabbix.com/pkg/plugin" ++) ++ ++// Plugin - ++type Plugin struct { ++ plugin.Base ++ cpus []*cpuUnit ++} ++ ++const ( ++ procStatLocation = "/compat/linux/proc/stat" ++) ++ ++func (p *Plugin) getCpuLoad(params []string) (result interface{}, err error) { ++ return nil, plugin.UnsupportedMetricError ++} ++ ++func (p *Plugin) Collect() (err error) { ++ var file *os.File ++ if file, err = os.Open(procStatLocation); err != nil { ++ return err ++ } ++ defer file.Close() ++ ++ var buf bytes.Buffer ++ if _, err = buf.ReadFrom(file); err != nil { ++ return ++ } ++ ++ for _, cpu := range p.cpus { ++ cpu.status = cpuStatusOffline ++ } ++ ++ scanner := bufio.NewScanner(&buf) ++ for scanner.Scan() { ++ line := scanner.Text() ++ if !strings.HasPrefix(line, "cpu") { ++ continue ++ } ++ fields := strings.Fields(line) ++ var index, status int ++ if len(fields[0]) > 3 { ++ var i int64 ++ if i, err = strconv.ParseInt(fields[0][3:], 10, 32); err != nil { ++ return ++ } ++ if index = int(i); index < 0 || index+1 >= len(p.cpus) { ++ p.Debugf("invalid CPU index %d", index) ++ continue ++ } ++ ++ status = cpuStatusOnline ++ } else { ++ index = -1 ++ } ++ ++ cpu := p.cpus[index+1] ++ cpu.status = status ++ ++ slot := &cpu.history[cpu.tail] ++ num := len(slot.counters) ++ if num > len(fields)-1 { ++ num = len(fields) - 1 ++ } ++ for i := 0; i < num; i++ { ++ slot.counters[i], _ = strconv.ParseUint(fields[i+1], 10, 64) ++ } ++ for i := num; i < len(slot.counters); i++ { ++ slot.counters[i] = 0 ++ } ++ // Linux includes guest times in user and nice times ++ slot.counters[counterUser] -= slot.counters[counterGcpu] ++ slot.counters[counterNice] -= slot.counters[counterGnice] ++ ++ if cpu.tail = cpu.tail.inc(); cpu.tail == cpu.head { ++ cpu.head = cpu.head.inc() ++ } ++ } ++ return nil ++} ++ ++func numCPU() int { ++ return int(C.sysconf(C._SC_NPROCESSORS_CONF)) ++} ++ ++func (p *Plugin) Start() { ++ p.cpus = p.newCpus(numCPU()) ++} ++ ++func (p *Plugin) Stop() { ++ p.cpus = nil ++} ++ ++func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error) { ++ if p.cpus == nil || p.cpus[0].head == p.cpus[0].tail { ++ // no data gathered yet ++ return ++ } ++ switch key { ++ case "system.cpu.discovery": ++ return p.getCpuDiscovery(params) ++ case "system.cpu.num": ++ return p.getCpuNum(params) ++ case "system.cpu.util": ++ return p.getCpuUtil(params) ++ default: ++ return nil, plugin.UnsupportedMetricError ++ } ++} ++ ++func init() { ++ plugin.RegisterMetrics(&impl, pluginName, ++ "system.cpu.discovery", "List of detected CPUs/CPU cores, used for low-level discovery.", ++ "system.cpu.num", "Number of CPUs.", ++ "system.cpu.util", "CPU utilisation percentage.") ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_cpu_cpucounters__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_cpu_cpucounters__freebsd.go @@ -0,0 +1,104 @@ +--- src/go/plugins/system/cpu/cpucounters_freebsd.go.orig 2020-05-20 10:07:01 UTC ++++ src/go/plugins/system/cpu/cpucounters_freebsd.go +@@ -0,0 +1,101 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2019 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package cpu ++ ++const ( ++ counterUnknown cpuCounter = iota - 1 ++ counterUser ++ counterNice ++ counterSystem ++ counterIdle ++ counterIowait ++ counterIrq ++ counterSoftirq ++ counterSteal ++ counterGcpu ++ counterGnice ++ counterNum // number of cpu counters ++) ++ ++type cpuCounters struct { ++ counters [counterNum]uint64 ++} ++ ++func counterByType(name string) (counter cpuCounter) { ++ switch name { ++ case "", "user": ++ return counterUser ++ case "idle": ++ return counterIdle ++ case "nice": ++ return counterNice ++ case "system": ++ return counterSystem ++ case "iowait": ++ return counterIowait ++ case "interrupt": ++ return counterIrq ++ case "softirq": ++ return counterSoftirq ++ case "steal": ++ return counterSteal ++ case "guest": ++ return counterGcpu ++ case "guest_nice": ++ return counterGnice ++ default: ++ return counterUnknown ++ } ++} ++ ++func (c *cpuUnit) counterAverage(counter cpuCounter, period historyIndex) (result interface{}) { ++ if c.head == c.tail { ++ return ++ } ++ var tail, head *cpuCounters ++ totalnum := c.tail - c.head ++ if totalnum < 0 { ++ totalnum += maxHistory ++ } ++ if totalnum < 2 { ++ // need at least two samples to calculate utilization ++ return ++ } ++ if totalnum-1 < period { ++ period = totalnum - 1 ++ } ++ tail = &c.history[c.tail.dec()] ++ head = &c.history[c.tail.sub(period+1)] ++ ++ var value, total uint64 ++ for i := 0; i < len(tail.counters); i++ { ++ if tail.counters[i] > head.counters[i] { ++ total += tail.counters[i] - head.counters[i] ++ } ++ } ++ if total == 0 { ++ return ++ } ++ ++ if tail.counters[counter] > head.counters[counter] { ++ value = tail.counters[counter] - head.counters[counter] ++ } ++ return float64(value) * 100 / float64(total) ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_uname_uname__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_uname_uname__freebsd.go @@ -0,0 +1,73 @@ +--- src/go/plugins/system/uname/uname_freebsd.go.orig 2020-05-20 10:26:11 UTC ++++ src/go/plugins/system/uname/uname_freebsd.go +@@ -0,0 +1,70 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package uname ++ ++import ( ++ "errors" ++ "fmt" ++ "syscall" ++) ++ ++func getUname(params []string) (uname string, err error) { ++ if len(params) > 0 { ++ return "", errors.New("Too many parameters.") ++ } ++ ++ var utsname syscall.Utsname ++ if err = syscall.Uname(&utsname); err != nil { ++ err = fmt.Errorf("Cannot obtain system information: %s", err.Error()) ++ return ++ } ++ uname = fmt.Sprintf("%s %s %s %s %s", arrayToString(&utsname.Sysname), arrayToString(&utsname.Nodename), ++ arrayToString(&utsname.Release), arrayToString(&utsname.Version), arrayToString(&utsname.Machine)) ++ ++ return uname, nil ++} ++ ++func getHostname(params []string) (hostname string, err error) { ++ if len(params) > 0 { ++ return "", errors.New("Too many parameters.") ++ } ++ ++ var utsname syscall.Utsname ++ if err = syscall.Uname(&utsname); err != nil { ++ err = fmt.Errorf("Cannot obtain system information: %s", err.Error()) ++ return ++ } ++ ++ return arrayToString(&utsname.Nodename), nil ++} ++ ++func getSwArch(params []string) (uname string, err error) { ++ if len(params) > 0 { ++ return "", errors.New("Too many parameters.") ++ } ++ ++ var utsname syscall.Utsname ++ if err = syscall.Uname(&utsname); err != nil { ++ err = fmt.Errorf("Cannot obtain system information: %s", err.Error()) ++ return ++ } ++ ++ return arrayToString(&utsname.Machine), nil ++} Index: net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_uptime_uptime__freebsd.go =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/agent2-patches/patch-src_go_plugins_system_uptime_uptime__freebsd.go @@ -0,0 +1,56 @@ +--- src/go/plugins/system/uptime/uptime_freebsd.go.orig 2020-05-20 10:20:21 UTC ++++ src/go/plugins/system/uptime/uptime_freebsd.go +@@ -0,0 +1,53 @@ ++/* ++** Zabbix ++** Copyright (C) 2001-2020 Zabbix SIA ++** ++** This program 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 2 of the License, or ++** (at your option) any later version. ++** ++** This program 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 this program; if not, write to the Free Software ++** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++**/ ++ ++package uptime ++ ++import ( ++ "bufio" ++ "errors" ++ "fmt" ++ "strconv" ++ "strings" ++ "time" ++ ++ "zabbix.com/pkg/std" ++) ++ ++func getUptime() (uptime int, err error) { ++ var file std.File ++ if file, err = stdOs.Open("/compat/linux/proc/stat"); err != nil { ++ err = fmt.Errorf("Cannot read boot time: %s", err.Error()) ++ return ++ } ++ defer file.Close() ++ ++ scanner := bufio.NewScanner(file) ++ for scanner.Scan() { ++ if strings.HasPrefix(scanner.Text(), "btime") { ++ var boot int ++ if boot, err = strconv.Atoi(scanner.Text()[6:]); err != nil { ++ return ++ } ++ return int(time.Now().Unix()) - boot, nil ++ } ++ } ++ ++ return 0, errors.New("Cannot locate boot time") ++} Index: net-mgmt/zabbix5-server/files/mock_server.in =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/mock_server.in @@ -0,0 +1,65 @@ +#!/bin/sh + +# PROVIDE: mock_server +# REQUIRE: DAEMON +# KEYWORD: shutdown +# +# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to +# enable mock_server: +# +# mock_server_enable (bool): Set to NO by default. Set it to YES to +# enable mock_server. +# mock_server_config (string): Set to the standard config file path by +# default. +# mock_server_pidfile (string): Location of the zabbix_agent pid file +# Default is /var/run/zabbix/mock_server.pid +# mock_server_paths (string): Set to standard path by default. Set a search +# if you have custom userparams that need binaries elsewhere. +# + +. /etc/rc.subr + +name="mock_server" +rcvar=mock_server_enable + +load_rc_config $name + +: ${mock_server_enable:=NO} +: ${mock_server_config:=%%ETCDIR%%/${name}.conf} +: ${mock_server_pidfile:=/var/run/zabbix/mock_server.pid} +: ${mock_server_paths:=$PATH} + +command="%%PREFIX%%/bin/${name}" +required_files="${mock_server_config}" + +start_cmd=mock_server_cmd +start_precmd=mock_server_precmd +status_precmd=mock_server_precmd +stop_precmd=mock_server_precmd + +mock_server_precmd() +{ + if get_pidfile_from_conf PidFile ${mock_server_config}; then + pidfile="$_pidfile_from_conf" + else + pidfile=${mock_server_pidfile} + local rundir=${mock_server_pidfile%/*} + if [ ! -d $rundir ] ; then + install -d -m 0755 -o zabbix -g zabbix $rundir + fi + fi + + # This shouldn't be necessary with pidfile, but empirically it was the + # only way to reap the parent PID instead of all PIDs from + # check_process, which may leak SysV IPC objects and prevent restart + # and/or race condition on restart. + rc_pid=$(check_pidfile ${pidfile} ${command}) +} + +mock_server_cmd() +{ + PATH=$mock_server_paths /usr/sbin/daemon -c -f -S -t "${name}" \ + $command -c $mock_server_config +} + +run_rc_command "$1" Index: net-mgmt/zabbix5-server/files/pkg-message.in =================================================================== --- /dev/null +++ net-mgmt/zabbix5-server/files/pkg-message.in @@ -0,0 +1,45 @@ +[ +{ type: install + message: <