Просмотр исходного кода

Integrate Go plugin with build system. (#17005)

* Integrate Go plugin with build system.

* Fix Debian packaging rules.

* Add FreeBSD support to Go toolchain handling.

* Add Go ldflags handling.

* Fix version detection when GCCGO is used.

* Fix Go ldflags handling.

* Correctly fix Go toolchain version detection.

* Properly mark Go as a required dependency in CMake.

* Disable VCS stamping as it does not work correctly on some platforms.

* Autodetect minimum required Go version from go.mod files.

This allows us to avoid needing to update the CMakeLists.txt file when
the required version changes in a Go component’s go.mod file.

* Prefix GoTools module name with Netdata to ensure we get our local module.

* Update integrations code to use new Go plugin location.

* Remove old go packaging files.

* keep old logic for initial cleanup that is working

* Re-sync Go plugin sources.

* Fix search order for finding Go toolchain.

* update module name

* fix /usr/local/go overwrite condition

---------

Co-authored-by: Fotis Voutsas <fotis@netdata.cloud>
Co-authored-by: ilyam8 <ilya@netdata.cloud>
Austin S. Hemmelgarn 1 год назад
Родитель
Сommit
4b7d920b44

+ 1 - 12
.github/workflows/generate-integrations.yml

@@ -7,6 +7,7 @@ on:
       - master
       - master
     paths: # If any of these files change, we need to regenerate integrations.js.
     paths: # If any of these files change, we need to regenerate integrations.js.
       - 'src/collectors/**/metadata.yaml'
       - 'src/collectors/**/metadata.yaml'
+      - 'src/go/collectors/**/metadata.yaml'
       - 'src/exporting/**/metadata.yaml'
       - 'src/exporting/**/metadata.yaml'
       - 'src/health/notifications/**/metadata.yaml'
       - 'src/health/notifications/**/metadata.yaml'
       - 'integrations/templates/**'
       - 'integrations/templates/**'
@@ -14,7 +15,6 @@ on:
       - 'integrations/deploy.yaml'
       - 'integrations/deploy.yaml'
       - 'integrations/cloud-notifications/metadata.yaml'
       - 'integrations/cloud-notifications/metadata.yaml'
       - 'integrations/gen_integrations.py'
       - 'integrations/gen_integrations.py'
-      - 'packaging/go.d.version'
   workflow_dispatch: null
   workflow_dispatch: null
 concurrency: # This keeps multiple instances of the job from running concurrently for the same ref.
 concurrency: # This keeps multiple instances of the job from running concurrently for the same ref.
   group: integrations-${{ github.ref }}
   group: integrations-${{ github.ref }}
@@ -31,17 +31,6 @@ jobs:
         with:
         with:
           fetch-depth: 1
           fetch-depth: 1
           submodules: recursive
           submodules: recursive
-      - name: Get Go Ref
-        id: get-go-ref
-        run: echo "go_ref=$(cat packaging/go.d.version)" >> "${GITHUB_ENV}"
-      - name: Checkout Go
-        id: checkout-go
-        uses: actions/checkout@v4
-        with:
-          fetch-depth: 1
-          path: go.d.plugin
-          repository: netdata/go.d.plugin
-          ref: ${{ env.go_ref }}
       - name: Prepare Dependencies
       - name: Prepare Dependencies
         id: prep-deps
         id: prep-deps
         run: |
         run: |

+ 49 - 9
CMakeLists.txt

@@ -47,12 +47,14 @@ else()
         message(FATAL_ERROR "Wrong version regex match count ${CMAKE_MATCH_COUNT} (should be in 3, 4 or 5)")
         message(FATAL_ERROR "Wrong version regex match count ${CMAKE_MATCH_COUNT} (should be in 3, 4 or 5)")
 endif()
 endif()
 
 
+set(NETDATA_VERSION ${FIELD_MAJOR}.${FIELD_MINOR}.${FIELD_PATCH}.${FIELD_TWEAK})
+
 #
 #
 # project
 # project
 #
 #
 
 
 project(netdata
 project(netdata
-        VERSION ${FIELD_MAJOR}.${FIELD_MINOR}.${FIELD_PATCH}.${FIELD_TWEAK}
+        VERSION ${NETDATA_VERSION}
         DESCRIPTION "Netdata real-time monitoring"
         DESCRIPTION "Netdata real-time monitoring"
         HOMEPAGE_URL "https://www.netdata.cloud"
         HOMEPAGE_URL "https://www.netdata.cloud"
         LANGUAGES C CXX)
         LANGUAGES C CXX)
@@ -98,20 +100,21 @@ option(ENABLE_ML "enable machine learning" True)
 option(ENABLE_H2O "enable h2o" True)
 option(ENABLE_H2O "enable h2o" True)
 option(ENABLE_DBENGINE "enable dbengine" True)
 option(ENABLE_DBENGINE "enable dbengine" True)
 
 
-option(ENABLE_PLUGIN_DEBUGFS "enable debugfs.plugin" True)
 option(ENABLE_PLUGIN_APPS "enable apps.plugin" True)
 option(ENABLE_PLUGIN_APPS "enable apps.plugin" True)
-option(ENABLE_PLUGIN_FREEIPMI "enable freeipmi.plugin" True)
-option(ENABLE_PLUGIN_NFACCT "enable nfacct.plugin" True)
-option(ENABLE_PLUGIN_XENSTAT "enable xenstat.plugin" True)
-option(ENABLE_PLUGIN_PERF "enable perf.plugin" True)
-option(ENABLE_PLUGIN_SLABINFO "enable slabinfo.plugin" True)
-option(ENABLE_PLUGIN_CUPS "enable cups.plugin" True)
 option(ENABLE_PLUGIN_CGROUP_NETWORK "enable cgroup-network plugin" True)
 option(ENABLE_PLUGIN_CGROUP_NETWORK "enable cgroup-network plugin" True)
+option(ENABLE_PLUGIN_CUPS "enable cups.plugin" True)
+option(ENABLE_PLUGIN_DEBUGFS "enable debugfs.plugin" True)
 option(ENABLE_PLUGIN_EBPF "enable ebpf.plugin" True)
 option(ENABLE_PLUGIN_EBPF "enable ebpf.plugin" True)
+option(ENABLE_PLUGIN_FREEIPMI "enable freeipmi.plugin" True)
+option(ENABLE_PLUGIN_GO "enable go.d.plugin" True)
 option(ENABLE_PLUGIN_LOCAL_LISTENERS "enable local-listeners" True)
 option(ENABLE_PLUGIN_LOCAL_LISTENERS "enable local-listeners" True)
+option(ENABLE_PLUGIN_LOGS_MANAGEMENT "enable logs-management.plugin" True)
 option(ENABLE_PLUGIN_NETWORK_VIEWER "enable network-viewer" True)
 option(ENABLE_PLUGIN_NETWORK_VIEWER "enable network-viewer" True)
+option(ENABLE_PLUGIN_NFACCT "enable nfacct.plugin" True)
+option(ENABLE_PLUGIN_PERF "enable perf.plugin" True)
+option(ENABLE_PLUGIN_SLABINFO "enable slabinfo.plugin" True)
 option(ENABLE_PLUGIN_SYSTEMD_JOURNAL "enable systemd-journal.plugin" True)
 option(ENABLE_PLUGIN_SYSTEMD_JOURNAL "enable systemd-journal.plugin" True)
-option(ENABLE_PLUGIN_LOGS_MANAGEMENT "enable logs-management.plugin" True)
+option(ENABLE_PLUGIN_XENSTAT "enable xenstat.plugin" True)
 
 
 option(ENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE "enable prometheus remote write exporter" True)
 option(ENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE "enable prometheus remote write exporter" True)
 option(ENABLE_EXPORTER_MONGODB "enable mongodb exporter" True)
 option(ENABLE_EXPORTER_MONGODB "enable mongodb exporter" True)
@@ -125,6 +128,14 @@ option(ENABLE_LOGS_MANAGEMENT_TESTS "enable logs management tests" True)
 option(ENABLE_SENTRY "enable sentry" False)
 option(ENABLE_SENTRY "enable sentry" False)
 option(ENABLE_WEBRTC "enable webrtc" False)
 option(ENABLE_WEBRTC "enable webrtc" False)
 
 
+if(ENABLE_PLUGIN_GO)
+    include(NetdataGoTools)
+
+    find_min_go_version("${CMAKE_SOURCE_DIR}/src/go")
+
+    find_package(Go "${MIN_GO_VERSION}" REQUIRED)
+endif()
+
 if(ENABLE_SENTRY)
 if(ENABLE_SENTRY)
         include(FetchContent)
         include(FetchContent)
 
 
@@ -2134,6 +2145,18 @@ install(TARGETS netdatacli
         COMPONENT netdatacli
         COMPONENT netdatacli
         DESTINATION usr/sbin)
         DESTINATION usr/sbin)
 
 
+#
+# Build go.d.plugin
+#
+
+if(ENABLE_PLUGIN_GO)
+    add_go_target(go-plugin go.d.plugin src/go/collectors/go.d.plugin cmd/godplugin)
+
+    install(PROGRAMS ${CMAKE_BINARY_DIR}/go.d.plugin
+            COMPONENT go.d.plugin
+            DESTINATION usr/libexec/netdata/plugins.d)
+endif()
+
 #
 #
 # Generate config file
 # Generate config file
 #
 #
@@ -2641,6 +2664,23 @@ if (ENABLE_PLUGIN_LOGS_MANAGEMENT)
                 DESTINATION usr/lib/netdata/conf.d)
                 DESTINATION usr/lib/netdata/conf.d)
 endif()
 endif()
 
 
+#
+# go.d.plugin
+#
+if(ENABLE_PLUGIN_GO)
+    install(FILES src/go/collectors/go.d.plugin/config/go.d.conf
+            COMPONENT go.d.plugin
+            DESTINATION usr/lib/netdata/conf.d)
+    install(DIRECTORY
+            COMPONENT go.d.plugin
+            DESTINATION usr/lib/netdata/conf.d/go.d)
+
+    file(GLOB GO_CONF_FILES src/go/collectors/go.d.plugin/config/go.d/*.conf)
+    install(FILES ${GO_CONF_FILES}
+            COMPONENT go.d.plugin
+            DESTINATION usr/lib/netdata/conf.d/go.d)
+endif()
+
 #
 #
 # dashboard
 # dashboard
 #
 #

+ 1 - 0
contrib/debian/control

@@ -5,6 +5,7 @@ Build-Depends: debhelper (>= 10),
                cmake,
                cmake,
                curl,
                curl,
                flex,
                flex,
+               golang (>= 1.21),
                libcups2-dev,
                libcups2-dev,
                libcurl4-openssl-dev,
                libcurl4-openssl-dev,
                libelf-dev,
                libelf-dev,

+ 13 - 8
contrib/debian/rules

@@ -83,12 +83,13 @@ override_dh_auto_configure:
 		-DENABLE_PLUGIN_DEBUGFS=On \
 		-DENABLE_PLUGIN_DEBUGFS=On \
 		$(EBPF_CONFIG) \
 		$(EBPF_CONFIG) \
 		-DENABLE_PLUGIN_FREEIPMI=On \
 		-DENABLE_PLUGIN_FREEIPMI=On \
+		-DENABLE_PLUGIN_GO=On \
 		-DENABLE_PLUGIN_LOCAL_LISTENERS=On \
 		-DENABLE_PLUGIN_LOCAL_LISTENERS=On \
+		-DENABLE_PLUGIN_LOGS_MANAGEMENT=On \
 		-DENABLE_PLUGIN_NFACCT=On \
 		-DENABLE_PLUGIN_NFACCT=On \
 		-DENABLE_PLUGIN_PERF=On \
 		-DENABLE_PLUGIN_PERF=On \
 		-DENABLE_PLUGIN_SLABINFO=On \
 		-DENABLE_PLUGIN_SLABINFO=On \
 		-DENABLE_PLUGIN_SYSTEMD_JOURNAL=On \
 		-DENABLE_PLUGIN_SYSTEMD_JOURNAL=On \
-		-DENABLE_PLUGIN_LOGS_MANAGEMENT=On \
 		$(XENSTAT_CONFIG) \
 		$(XENSTAT_CONFIG) \
 		-DENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE=On \
 		-DENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE=On \
 		-DENABLE_EXPORTER_MONGODB=On \
 		-DENABLE_EXPORTER_MONGODB=On \
@@ -210,6 +211,17 @@ override_dh_install:
 		$(TOP)-plugin-xenstat/usr/libexec/netdata/plugins.d/xenstat.plugin; \
 		$(TOP)-plugin-xenstat/usr/libexec/netdata/plugins.d/xenstat.plugin; \
 	fi
 	fi
 
 
+	# Install go to it's own package directory
+	#
+	mkdir -p $(TOP)-plugin-go/usr/libexec/netdata/plugins.d
+	mv -f $(TEMPTOP)/usr/libexec/netdata/plugins.d/go.d.plugin \
+	$(TOP)-plugin-go/usr/libexec/netdata/plugins.d/go.d.plugin
+	mkdir -p $(TOP)-plugin-go/usr/lib/netdata/conf.d
+	mv -f $(TEMPTOP)/usr/lib/netdata/conf.d/go.d.conf \
+	$(TOP)-plugin-go/usr/lib/netdata/conf.d/go.d.conf
+	mv -f $(TEMPTOP)/usr/lib/netdata/conf.d/go.d \
+	$(TOP)-plugin-go/usr/lib/netdata/conf.d/go.d
+
 	# Set the rest of the software in the main package
 	# Set the rest of the software in the main package
 	#
 	#
 	cp -rp $(TEMPTOP)/usr $(TOP)
 	cp -rp $(TEMPTOP)/usr $(TOP)
@@ -230,13 +242,6 @@ override_dh_install:
 		packaging/bundle-ebpf.sh . ${TOP}-ebpf-code-legacy/usr/libexec/netdata/plugins.d/ force; \
 		packaging/bundle-ebpf.sh . ${TOP}-ebpf-code-legacy/usr/libexec/netdata/plugins.d/ force; \
 	fi
 	fi
 
 
-	# Install go to it's own package directory
-	#
-	mkdir -p $(TOP)-plugin-go/usr/lib/netdata/conf.d
-	mkdir -p $(TOP)-plugin-go/usr/libexec/netdata/plugins.d
-	debian/install_go.sh $$(cat ${CURDIR}/packaging/go.d.version) \
-	$(TOP)-plugin-go/usr/lib/netdata \
-	$(TOP)-plugin-go/usr/libexec/netdata
 
 
 override_dh_installdocs:
 override_dh_installdocs:
 	dh_installdocs
 	dh_installdocs

+ 15 - 19
integrations/gen_docs_integrations.py

@@ -5,30 +5,26 @@ import re
 
 
 # Dictionary responsible for making the symbolic links at the end of the script's run.
 # Dictionary responsible for making the symbolic links at the end of the script's run.
 symlink_dict = {}
 symlink_dict = {}
-am_i_inside_go = "go.d.plugin" in str(Path.cwd())
 
 
 
 
 def cleanup():
 def cleanup():
     """
     """
     clean directories that are either data collection or exporting integrations
     clean directories that are either data collection or exporting integrations
     """
     """
-    if am_i_inside_go:
-        for element in Path("modules").glob('**/*/'):
-            if "integrations" in str(element):
-                shutil.rmtree(element)
-    else:
-        for element in Path("src/collectors").glob('**/*/'):
-            # print(element)
-            if "integrations" in str(element):
-                shutil.rmtree(element)
-
-        for element in Path("src/exporting").glob('**/*/'):
-            if "integrations" in str(element):
-                shutil.rmtree(element)
-        for element in Path("integrations/cloud-notifications").glob('**/*/'):
-            if "integrations" in str(element) and not "metadata.yaml" in str(element):
-                shutil.rmtree(element)
-
+    for element in Path("src/go/collectors/go.d.plugin/modules").glob('**/*/'):
+        if "integrations" in str(element):
+            shutil.rmtree(element)
+    for element in Path("src/collectors").glob('**/*/'):
+        # print(element)
+        if "integrations" in str(element):
+            shutil.rmtree(element)
+
+    for element in Path("src/exporting").glob('**/*/'):
+        if "integrations" in str(element):
+            shutil.rmtree(element)
+    for element in Path("integrations/cloud-notifications").glob('**/*/'):
+        if "integrations" in str(element) and not "metadata.yaml" in str(element):
+            shutil.rmtree(element)
 
 
 def generate_category_from_name(category_fragment, category_array):
 def generate_category_from_name(category_fragment, category_array):
     """
     """
@@ -368,7 +364,7 @@ for integration in integrations:
         path = build_path(meta_yaml)
         path = build_path(meta_yaml)
         write_to_file(path, md, meta_yaml, sidebar_label, community)
         write_to_file(path, md, meta_yaml, sidebar_label, community)
 
 
-    elif not am_i_inside_go:
+    else:
         # kind of specific if clause, so we can avoid running excessive code in the go repo
         # kind of specific if clause, so we can avoid running excessive code in the go repo
         if integration['integration_type'] == "exporter":
         if integration['integration_type'] == "exporter":
 
 

+ 2 - 7
integrations/gen_integrations.py

@@ -14,7 +14,6 @@ from referencing.jsonschema import DRAFT7
 from ruamel.yaml import YAML, YAMLError
 from ruamel.yaml import YAML, YAMLError
 
 
 AGENT_REPO = 'netdata/netdata'
 AGENT_REPO = 'netdata/netdata'
-GO_REPO = 'netdata/go.d.plugin'
 
 
 INTEGRATIONS_PATH = Path(__file__).parent
 INTEGRATIONS_PATH = Path(__file__).parent
 TEMPLATE_PATH = INTEGRATIONS_PATH / 'templates'
 TEMPLATE_PATH = INTEGRATIONS_PATH / 'templates'
@@ -23,7 +22,6 @@ JSON_PATH = INTEGRATIONS_PATH / 'integrations.json'
 CATEGORIES_FILE = INTEGRATIONS_PATH / 'categories.yaml'
 CATEGORIES_FILE = INTEGRATIONS_PATH / 'categories.yaml'
 REPO_PATH = INTEGRATIONS_PATH.parent
 REPO_PATH = INTEGRATIONS_PATH.parent
 SCHEMA_PATH = INTEGRATIONS_PATH / 'schemas'
 SCHEMA_PATH = INTEGRATIONS_PATH / 'schemas'
-GO_REPO_PATH = REPO_PATH / 'go.d.plugin'
 DISTROS_FILE = REPO_PATH / '.github' / 'data' / 'distros.yml'
 DISTROS_FILE = REPO_PATH / '.github' / 'data' / 'distros.yml'
 METADATA_PATTERN = '*/metadata.yaml'
 METADATA_PATTERN = '*/metadata.yaml'
 
 
@@ -31,7 +29,7 @@ COLLECTOR_SOURCES = [
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors', True),
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors', True),
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors' / 'charts.d.plugin', True),
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors' / 'charts.d.plugin', True),
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors' / 'python.d.plugin', True),
     (AGENT_REPO, REPO_PATH / 'src' / 'collectors' / 'python.d.plugin', True),
-    (GO_REPO, GO_REPO_PATH / 'modules', True),
+    (AGENT_REPO, REPO_PATH / 'src' / 'go' / 'collectors' / 'go.d.plugin' / 'modules', True),
 ]
 ]
 
 
 DEPLOY_SOURCES = [
 DEPLOY_SOURCES = [
@@ -399,10 +397,7 @@ def make_id(meta):
 
 
 
 
 def make_edit_link(item):
 def make_edit_link(item):
-    if item['_repo'] == 'netdata/go.d.plugin':
-        item_path = item['_src_path'].relative_to(GO_REPO_PATH)
-    else:
-        item_path = item['_src_path'].relative_to(REPO_PATH)
+    item_path = item['_src_path'].relative_to(REPO_PATH)
 
 
     return f'https://github.com/{ item["_repo"] }/blob/master/{ item_path }'
     return f'https://github.com/{ item["_repo"] }/blob/master/{ item_path }'
 
 

+ 35 - 167
netdata-installer.sh

@@ -102,10 +102,6 @@ print_deferred_errors() {
   fi
   fi
 }
 }
 
 
-download_go() {
-  download_file "${1}" "${2}" "go.d plugin" "go"
-}
-
 # make sure we save all commands we run
 # make sure we save all commands we run
 # Variable is used by code in the packaging/installer/functions.sh
 # Variable is used by code in the packaging/installer/functions.sh
 # shellcheck disable=SC2034
 # shellcheck disable=SC2034
@@ -205,7 +201,6 @@ USAGE: ${PROGRAM} [options]
                              This results in less frequent updates.
                              This results in less frequent updates.
   --nightly-channel          Use most recent nightly updates instead of GitHub releases.
   --nightly-channel          Use most recent nightly updates instead of GitHub releases.
                              This results in more frequent updates.
                              This results in more frequent updates.
-  --disable-go               Disable installation of go.d.plugin.
   --disable-ebpf             Disable eBPF Kernel plugin. Default: enabled.
   --disable-ebpf             Disable eBPF Kernel plugin. Default: enabled.
   --disable-cloud            Disable all Netdata Cloud functionality.
   --disable-cloud            Disable all Netdata Cloud functionality.
   --require-cloud            Fail the install if it can't build Netdata Cloud support.
   --require-cloud            Fail the install if it can't build Netdata Cloud support.
@@ -214,6 +209,9 @@ USAGE: ${PROGRAM} [options]
   --disable-plugin-freeipmi  Explicitly disable the FreeIPMI plugin.
   --disable-plugin-freeipmi  Explicitly disable the FreeIPMI plugin.
   --disable-https            Explicitly disable TLS support.
   --disable-https            Explicitly disable TLS support.
   --disable-dbengine         Explicitly disable DB engine support.
   --disable-dbengine         Explicitly disable DB engine support.
+  --enable-plugin-go         Enable the Go plugin. Default: Enabled when possible.
+  --disable-plugin-go        Disable the Go plugin.
+  --disable-go               Equivalent to --disable-go-plugin
   --enable-plugin-nfacct     Enable nfacct plugin. Default: enable it when libmnl and libnetfilter_acct are available.
   --enable-plugin-nfacct     Enable nfacct plugin. Default: enable it when libmnl and libnetfilter_acct are available.
   --disable-plugin-nfacct    Explicitly disable the nfacct plugin.
   --disable-plugin-nfacct    Explicitly disable the nfacct plugin.
   --enable-plugin-xenstat    Enable the xenstat plugin. Default: enable it when libxenstat and libyajl are available.
   --enable-plugin-xenstat    Enable the xenstat plugin. Default: enable it when libxenstat and libyajl are available.
@@ -254,6 +252,7 @@ LIBS_ARE_HERE=0
 NETDATA_ENABLE_ML=""
 NETDATA_ENABLE_ML=""
 ENABLE_DBENGINE=1
 ENABLE_DBENGINE=1
 ENABLE_EBPF=1
 ENABLE_EBPF=1
+ENABLE_GO=1
 ENABLE_H2O=1
 ENABLE_H2O=1
 ENABLE_CLOUD=1
 ENABLE_CLOUD=1
 ENABLE_LOGS_MANAGEMENT=1
 ENABLE_LOGS_MANAGEMENT=1
@@ -284,6 +283,9 @@ while [ -n "${1}" ]; do
       ENABLE_CLOUD=0
       ENABLE_CLOUD=0
       ;;
       ;;
     "--disable-dbengine") ENABLE_DBENGINE=0 ;;
     "--disable-dbengine") ENABLE_DBENGINE=0 ;;
+    "--enable-plugin-go") ENABLE_GO=1 ;;
+    "--disable-plugin-go") ENABLE_GO=0 ;;
+    "--disable-go") ENABLE_GO=0 ;;
     "--enable-plugin-nfacct") ENABLE_NFACCT=1 ;;
     "--enable-plugin-nfacct") ENABLE_NFACCT=1 ;;
     "--disable-plugin-nfacct") ENABLE_NFACCT=0 ;;
     "--disable-plugin-nfacct") ENABLE_NFACCT=0 ;;
     "--enable-plugin-xenstat") ENABLE_XENSTAT=1 ;;
     "--enable-plugin-xenstat") ENABLE_XENSTAT=1 ;;
@@ -321,7 +323,6 @@ while [ -n "${1}" ]; do
       # XXX: No longer supported.
       # XXX: No longer supported.
       ;;
       ;;
     "--disable-telemetry") NETDATA_DISABLE_TELEMETRY=1 ;;
     "--disable-telemetry") NETDATA_DISABLE_TELEMETRY=1 ;;
-    "--disable-go") NETDATA_DISABLE_GO=1 ;;
     "--enable-ebpf")
     "--enable-ebpf")
       ENABLE_EBPF=1
       ENABLE_EBPF=1
       NETDATA_DISABLE_EBPF=0
       NETDATA_DISABLE_EBPF=0
@@ -1039,6 +1040,18 @@ bundle_fluentbit() {
 
 
 bundle_fluentbit
 bundle_fluentbit
 
 
+# -----------------------------------------------------------------------------
+# If we’re installing the Go plugin, ensure a working Go toolchain is installed.
+if [ "${ENABLE_GO}" -eq 1 ]; then
+  progress "Checking for a usable Go toolchain and attempting to install one to /usr/local/go if needed."
+  . "${NETDATA_SOURCE_DIR}/packaging/check-for-go-toolchain.sh"
+
+  if ! ensure_go_toolchain; then
+    warning "Go ${GOLANG_MIN_VERSION} needed to build Go plugin, but could not find or install a usable toolchain: ${GOLANG_FAILURE_REASON}"
+    ENABLE_GO=0
+  fi
+fi
+
 # -----------------------------------------------------------------------------
 # -----------------------------------------------------------------------------
 # If we have the dashboard switching logic, make sure we're on the classic
 # If we have the dashboard switching logic, make sure we're on the classic
 # dashboard during the install (updates don't work correctly otherwise).
 # dashboard during the install (updates don't work correctly otherwise).
@@ -1429,6 +1442,22 @@ if [ "$(id -u)" -eq 0 ]; then
     run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ndsudo"
     run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ndsudo"
   fi
   fi
 
 
+  if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" ]; then
+    run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
+    capabilities=1
+    if ! iscontainer && command -v setcap 1> /dev/null 2>&1; then
+      run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
+      if ! run setcap "cap_dac_read_search+epi cap_net_admin+epi cap_net_raw=eip" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"; then
+        capabilities=0
+      fi
+    fi
+
+    if [ $capabilities -eq 0 ]; then
+      # fix go.d.plugin to be setuid to root
+      run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
+    fi
+  fi
+
 else
 else
   # non-privileged user installation
   # non-privileged user installation
   run chown "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_LOG_DIR}"
   run chown "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_LOG_DIR}"
@@ -1439,167 +1468,6 @@ fi
 
 
 [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
 [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
 
 
-# -----------------------------------------------------------------------------
-
-# govercomp compares go.d.plugin versions. Exit codes:
-# 0 - version1 == version2
-# 1 - version1 > version2
-# 2 - version2 > version1
-# 3 - error
-
-# shellcheck disable=SC2086
-govercomp() {
-  # version in file:
-  # - v0.14.0
-  #
-  # 'go.d.plugin -v' output variants:
-  # - go.d.plugin, version: unknown
-  # - go.d.plugin, version: v0.14.1
-  # - go.d.plugin, version: v0.14.1-dirty
-  # - go.d.plugin, version: v0.14.1-1-g4c5f98c
-  # - go.d.plugin, version: v0.14.1-1-g4c5f98c-dirty
-
-  # we need to compare only MAJOR.MINOR.PATCH part
-  ver1=$(echo "$1" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+")
-  ver2=$(echo "$2" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+")
-
-  if [ ${#ver1} -eq 0 ] || [ ${#ver2} -eq 0 ]; then
-    return 3
-  fi
-
-  num1=$(echo $ver1 | grep -o -E '\.' | wc -l)
-  num2=$(echo $ver2 | grep -o -E '\.' | wc -l)
-
-  if [ ${num1} -ne ${num2} ]; then
-          return 3
-  fi
-
-  for i in $(seq 1 $((num1+1))); do
-          x=$(echo $ver1 | cut -d'.' -f$i)
-          y=$(echo $ver2 | cut -d'.' -f$i)
-    if [ "${x}" -gt "${y}" ]; then
-      return 1
-    elif [ "${y}" -gt "${x}" ]; then
-      return 2
-    fi
-  done
-
-  return 0
-}
-
-should_install_go() {
-  if [ -n "${NETDATA_DISABLE_GO+x}" ]; then
-    return 1
-  fi
-
-  version_in_file="$(cat packaging/go.d.version 2> /dev/null)"
-  binary_version=$("${NETDATA_PREFIX}"/usr/libexec/netdata/plugins.d/go.d.plugin -v 2> /dev/null)
-
-  govercomp "$version_in_file" "$binary_version"
-  case $? in
-    0) return 1 ;; # =
-    2) return 1 ;; # <
-    *) return 0 ;; # >, error
-  esac
-}
-
-install_go() {
-  if ! should_install_go; then
-    return 0
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Installing go.d.plugin."
-
-  # When updating this value, ensure correct checksums in packaging/go.d.checksums
-  GO_PACKAGE_VERSION="$(cat packaging/go.d.version)"
-  ARCH_MAP='
-    i386::386
-    i686::386
-    x86_64::amd64
-    aarch64::arm64
-    armv64::arm64
-    armv6l::arm
-    armv7l::arm
-    armv5tel::arm
-  '
-
-  progress "Install go.d.plugin"
-  ARCH=$(uname -m)
-  OS=$(uname -s | tr '[:upper:]' '[:lower:]')
-
-  for index in ${ARCH_MAP}; do
-    KEY="${index%%::*}"
-    VALUE="${index##*::}"
-    if [ "$KEY" = "$ARCH" ]; then
-      ARCH="${VALUE}"
-      break
-    fi
-  done
-  tmp="$(mktemp -d -t netdata-go-XXXXXX)"
-  GO_PACKAGE_BASENAME="go.d.plugin-${GO_PACKAGE_VERSION}.${OS}-${ARCH}.tar.gz"
-
-  if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" ]; then
-    download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/${GO_PACKAGE_BASENAME}" "${tmp}/${GO_PACKAGE_BASENAME}"
-  else
-    progress "Using provided go.d tarball ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}"
-    run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" "${tmp}/${GO_PACKAGE_BASENAME}"
-  fi
-
-  if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" ]; then
-    download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/config.tar.gz" "${tmp}/config.tar.gz"
-  else
-    progress "Using provided config file for go.d ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}"
-    run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" "${tmp}/config.tar.gz"
-  fi
-
-  if [ ! -f "${tmp}/${GO_PACKAGE_BASENAME}" ] || [ ! -f "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/${GO_PACKAGE_BASENAME}" ]; then
-    run_failed "go.d plugin download failed, go.d plugin will not be available"
-    echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer"
-    echo >&2
-    [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-    return 0
-  fi
-
-  grep "${GO_PACKAGE_BASENAME}\$" "${INSTALLER_DIR}/packaging/go.d.checksums" > "${tmp}/sha256sums.txt" 2> /dev/null
-  grep "config.tar.gz" "${INSTALLER_DIR}/packaging/go.d.checksums" >> "${tmp}/sha256sums.txt" 2> /dev/null
-
-  # Checksum validation
-  if ! (cd "${tmp}" && safe_sha256sum -c "sha256sums.txt"); then
-
-    echo >&2 "go.d plugin checksum validation failure."
-    echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer"
-    echo >&2
-
-    run_failed "go.d.plugin package files checksum validation failed. go.d.plugin will not be available."
-    [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-    return 0
-  fi
-
-  # Install new files
-  run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d"
-  run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d.conf"
-  run tar --no-same-owner -xf "${tmp}/config.tar.gz" -C "${NETDATA_STOCK_CONFIG_DIR}/"
-  run chown -R "${ROOT_USER}:${ROOT_GROUP}" "${NETDATA_STOCK_CONFIG_DIR}"
-
-  run tar --no-same-owner -xf "${tmp}/${GO_PACKAGE_BASENAME}"
-  run mv "${GO_PACKAGE_BASENAME%.tar.gz}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
-  if [ "$(id -u)" -eq 0 ]; then
-    run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
-  fi
-  run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
-  rm -rf "${tmp}"
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-}
-
-install_go
-
-if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" ]; then
-  if command -v setcap 1>/dev/null 2>&1; then
-    run setcap "cap_dac_read_search+epi cap_net_admin+epi cap_net_raw=eip" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin"
-  fi
-fi
-
 should_install_ebpf() {
 should_install_ebpf() {
   if [ "${NETDATA_DISABLE_EBPF:=0}" -eq 1 ]; then
   if [ "${NETDATA_DISABLE_EBPF:=0}" -eq 1 ]; then
     run_failed "eBPF has been explicitly disabled, it will not be available in this install."
     run_failed "eBPF has been explicitly disabled, it will not be available in this install."

+ 17 - 142
netdata.spec.in

@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 # SPDX-License-Identifier: GPL-3.0-or-later
 %global contentdir %{_datadir}/netdata
 %global contentdir %{_datadir}/netdata
 %global version @PACKAGE_VERSION@
 %global version @PACKAGE_VERSION@
-%global go_version @GO_PACKAGE_VERSION@
-%global go_name go.d.plugin
 
 
 # XXX: We are using automatic `Requires:` generation for libraries
 # XXX: We are using automatic `Requires:` generation for libraries
 # whenever possible, DO NOT LIST LIBRARY DEPENDENCIES UNLESS THE RESULTANT
 # whenever possible, DO NOT LIST LIBRARY DEPENDENCIES UNLESS THE RESULTANT
@@ -14,6 +12,11 @@ AutoReqProv: yes
 # error.
 # error.
 %global __os_install_post %{nil}
 %global __os_install_post %{nil}
 
 
+# This is needed to support proper handling of Go code without requiring
+# external linking or GCCGO, because even recent versions of rpmbuild do
+# not properly support the build IDs generated by the upstream Go toolchain.
+%global _missing_build_ids_terminate_build 0
+
 # Use our custom CMake version from our package builders if we can’t find cmake.
 # Use our custom CMake version from our package builders if we can’t find cmake.
 %if 0%{?centos_ver} == 7
 %if 0%{?centos_ver} == 7
 %global __cmake /cmake/bin/cmake
 %global __cmake /cmake/bin/cmake
@@ -39,18 +42,6 @@ AutoReqProv: yes
 %global __cmake_builddir %{__builddir}
 %global __cmake_builddir %{__builddir}
 %endif
 %endif
 
 
-# Disable go.d.plugin build on outdated golang distros
-%if 0
-%if 0%{?centos_ver:1}
-%if 0%{?centos_ver} >= 10 && 0%{?almalinux_ver:1} && 0%{?rocky_ver:1}
-%global _golang_build 1
-%else
-%global _golang_build 0
-%global _missing_build_ids_terminate_build 0
-%endif
-%endif
-%endif
-
 # Disable eBPF for architectures other than x86
 # Disable eBPF for architectures other than x86
 %ifarch x86_64 i386
 %ifarch x86_64 i386
 %global _have_ebpf 1
 %global _have_ebpf 1
@@ -125,8 +116,6 @@ Release:	1%{?dist}
 License:	GPLv3+
 License:	GPLv3+
 Group:		Applications/System
 Group:		Applications/System
 Source0:	https://github.com/%{name}/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz
 Source0:	https://github.com/%{name}/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz
-Source1:	https://github.com/%{name}/%{go_name}/releases/download/v%{go_version}/config.tar.gz
-Source2:	https://github.com/%{name}/%{go_name}/archive/refs/tags/v%{go_version}.tar.gz
 URL:		http://my-%{name}.io
 URL:		http://my-%{name}.io
 
 
 # Remove conflicting EPEL packages
 # Remove conflicting EPEL packages
@@ -260,11 +249,17 @@ BuildRequires: cups-devel
 # end - cups plugin dependencies
 # end - cups plugin dependencies
 
 
 # go.d.plugin dependencies
 # go.d.plugin dependencies
-%if 0%{?_golang_build}
+#
+# The conditional here is checking for a macro we define in our package
+# builders. If it’s defined, then we’ve injected an upstream copy of
+# the Go toolchain, so we don’t need the package installed (which
+# is needed because Go’s development model is at odds with enterprise
+# distro handling of versioning).
+%if %{?_upstream_go_toolchain:0}%{!?_upstream_go_toolchain:1}
 %if 0%{?suse_version}
 %if 0%{?suse_version}
-BuildRequires: go
+BuildRequires: go >= 1.21
 %else
 %else
-BuildRequires: golang
+BuildRequires: golang >= 1.21
 %endif
 %endif
 %endif
 %endif
 # end - go.d.plugin plugin dependencies
 # end - go.d.plugin plugin dependencies
@@ -339,15 +334,6 @@ export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging
 %endif
 %endif
 %endif
 %endif
 
 
-# go.d.plugin
-%if 0%{?_golang_build}
-mkdir -p "%{_builddir}/%{go_name}"
-tar -xzf "%{SOURCE1}" -C "%{_builddir}/%{go_name}"
-tar -xzf "%{SOURCE2}" -C "%{_builddir}/%{go_name}"
-cd "%{_builddir}/%{go_name}/%{go_name}-%{go_version}"
-make download
-%endif
-
 %build
 %build
 # Conf step
 # Conf step
 %cmake -G Ninja \
 %cmake -G Ninja \
@@ -408,6 +394,7 @@ make download
 	-DENABLE_PLUGIN_APPS=On \
 	-DENABLE_PLUGIN_APPS=On \
 	-DENABLE_PLUGIN_CGROUP_NETWORK=On \
 	-DENABLE_PLUGIN_CGROUP_NETWORK=On \
 	-DENABLE_PLUGIN_DEBUGFS=On \
 	-DENABLE_PLUGIN_DEBUGFS=On \
+	-DENABLE_PLUGIN_GO=On \
 	-DENABLE_PLUGIN_LOCAL_LISTENERS=On \
 	-DENABLE_PLUGIN_LOCAL_LISTENERS=On \
 	-DENABLE_PLUGIN_PERF=On \
 	-DENABLE_PLUGIN_PERF=On \
 	-DENABLE_PLUGIN_SLABINFO=On \
 	-DENABLE_PLUGIN_SLABINFO=On \
@@ -420,13 +407,6 @@ make download
 # Build step
 # Build step
 %{cmake_build}
 %{cmake_build}
 
 
-# Build go.d.plugin
-%if 0%{?_golang_build}
-cd "%{_builddir}/%{go_name}/%{go_name}-%{go_version}"
-sed -i 's|CGO_ENABLED=0 ||' "hack/go-build.sh"
-TRAVIS_TAG="%{go_version}" %{__make} build
-%endif
-
 %install
 %install
 
 
 # ###########################################################
 # ###########################################################
@@ -471,111 +451,6 @@ install -m 644 -p "%{__cmake_builddir}/system/systemd/%{name}.service.v235" "${R
 install -m 755 -d "${RPM_BUILD_ROOT}%{_presetdir}"
 install -m 755 -d "${RPM_BUILD_ROOT}%{_presetdir}"
 install -m 644 -p "system/systemd/50-%{name}.preset" "${RPM_BUILD_ROOT}%{_presetdir}/50-%{name}.preset"
 install -m 644 -p "system/systemd/50-%{name}.preset" "${RPM_BUILD_ROOT}%{_presetdir}/50-%{name}.preset"
 
 
-# ############################################################
-# Package Go within netdata
-
-# Install builded go.d.plugin
-%if 0%{?_golang_build}
-install -m 0640 "%{_builddir}/%{go_name}/%{go_name}-%{go_version}/bin/godplugin" \
-"${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d/%{go_name}"
-cp -r "%{_builddir}/%{go_name}/go.d.conf" "%{_builddir}/%{go_name}/go.d" \
-"${RPM_BUILD_ROOT}%{_libdir}/%{name}/conf.d/"
-%else
-# Install binary go.d.plugin
-safe_sha256sum() {
-	# Within the context of the installer, we only use -c option that is common between the two commands
-	# We will have to reconsider if we start non-common options
-	if command -v sha256sum >/dev/null 2>&1; then
-		sha256sum $@
-	elif command -v shasum >/dev/null 2>&1; then
-		shasum -a 256 $@
-	else
-		fatal "I could not find a suitable checksum binary to use"
-	fi
-}
-
-download_go() {
-	url="${1}"
-	dest="${2}"
-
-	if command -v curl >/dev/null 2>&1; then
-		curl -sSL --connect-timeout 10 --retry 3 "${url}" > "${dest}"
-	elif command -v wget >/dev/null 2>&1; then
-		wget -T 15 -O - "${url}" > "${dest}"
-	else
-		echo >&2
-		echo >&2 "Downloading go.d plugin from '${url}' failed because of missing mandatory packages."
-		echo >&2 "Either add packages or disable it by issuing '--disable-go' in the installer"
-		echo >&2
-		exit 1
-	fi
-}
-
-install_go() {
-	# When updating this value, ensure correct checksums in packaging/go.d.checksums
-	GO_PACKAGE_VERSION="$(cat packaging/go.d.version)"
-	ARCH_MAP=(
-		'i386::386'
-		'i686::386'
-		'x86_64::amd64'
-		'aarch64::arm64'
-		'armv64::arm64'
-		'armv6l::arm'
-		'armv7l::arm'
-		'armv5tel::arm'
-	)
-
-	if [ -z "${NETDATA_DISABLE_GO+x}" ]; then
-		ARCH="%{_arch}"
-		OS=$(uname -s | tr '[:upper:]' '[:lower:]')
-
-		echo >&2 "Install go.d.plugin (ARCH=${ARCH}, OS=${OS})"
-
-		for index in "${ARCH_MAP[@]}" ; do
-			KEY="${index%%::*}"
-			VALUE="${index##*::}"
-			if [ "$KEY" = "$ARCH" ]; then
-				ARCH="${VALUE}"
-				break
-			fi
-		done
-		tmp=$(mktemp -d /tmp/netdata-go-XXXXXX)
-		GO_PACKAGE_BASENAME="go.d.plugin-${GO_PACKAGE_VERSION}.${OS}-${ARCH}.tar.gz"
-		download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/${GO_PACKAGE_BASENAME}" "${tmp}/${GO_PACKAGE_BASENAME}"
-		download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/config.tar.gz" "${tmp}/config.tar.gz"
-
-		if [ ! -f "${tmp}/${GO_PACKAGE_BASENAME}" ] || [ ! -f "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/${GO_PACKAGE_BASENAME}" ]; then
-			echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer"
-			echo >&2
-			return 1
-		fi
-
-		grep "${GO_PACKAGE_BASENAME}\$" "packaging/go.d.checksums" > "${tmp}/sha256sums.txt" 2>/dev/null
-		grep "config.tar.gz" "packaging/go.d.checksums" >> "${tmp}/sha256sums.txt" 2>/dev/null
-
-		# Checksum validation
-		if ! (cd "${tmp}" && safe_sha256sum -c "sha256sums.txt"); then
-
-			echo >&2 "go.d plugin checksum validation failure."
-			echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer"
-			echo >&2
-
-			echo "go.d.plugin package files checksum validation failed."
-			exit 1
-		fi
-
-		# Install files
-		tar -xf "${tmp}/config.tar.gz" -C "${RPM_BUILD_ROOT}%{_libdir}/%{name}/conf.d/"
-		tar xf "${tmp}/${GO_PACKAGE_BASENAME}"
-		mv "${GO_PACKAGE_BASENAME/\.tar\.gz/}" "go.d.plugin"
-		rm -rf "${tmp}"
-	fi
-	return 0
-}
-install_go
-install -m 0640 -p "%{go_name}" "${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d/%{go_name}"
-%endif
-
 %if 0%{?_have_ebpf}
 %if 0%{?_have_ebpf}
 ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} \
 ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} \
 ${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d
 ${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/plugins.d
@@ -729,7 +604,7 @@ rm -rf "${RPM_BUILD_ROOT}"
 %exclude %{_libdir}/%{name}/conf.d/python.d
 %exclude %{_libdir}/%{name}/conf.d/python.d
 
 
 # Go.d belongs to a different sub-package
 # Go.d belongs to a different sub-package
-%exclude %{_libexecdir}/%{name}/plugins.d/%{go_name}
+%exclude %{_libexecdir}/%{name}/plugins.d/go.d.plugin
 %exclude %{_libdir}/%{name}/conf.d/go.d.conf
 %exclude %{_libdir}/%{name}/conf.d/go.d.conf
 %exclude %{_libdir}/%{name}/conf.d/go.d
 %exclude %{_libdir}/%{name}/conf.d/go.d
 
 
@@ -958,7 +833,7 @@ fi
 %defattr(0750,root,netdata,0750)
 %defattr(0750,root,netdata,0750)
 # CAP_NET_ADMIN needed for WireGuard collector
 # CAP_NET_ADMIN needed for WireGuard collector
 # CAP_NET_RAW needed for ping collector
 # CAP_NET_RAW needed for ping collector
-%caps(cap_dac_read_search,cap_net_admin,cap_net_raw=eip) %{_libexecdir}/%{name}/plugins.d/%{go_name}
+%caps(cap_dac_read_search,cap_net_admin,cap_net_raw=eip) %{_libexecdir}/%{name}/plugins.d/go.d.plugin
 %defattr(0644,root,netdata,0755)
 %defattr(0644,root,netdata,0755)
 %{_libdir}/%{name}/conf.d/go.d.conf
 %{_libdir}/%{name}/conf.d/go.d.conf
 %{_libdir}/%{name}/conf.d/go.d
 %{_libdir}/%{name}/conf.d/go.d

+ 74 - 36
packaging/check-for-go-toolchain.sh

@@ -16,6 +16,7 @@
 GOLANG_MIN_MAJOR_VERSION='1'
 GOLANG_MIN_MAJOR_VERSION='1'
 GOLANG_MIN_MINOR_VERSION='21'
 GOLANG_MIN_MINOR_VERSION='21'
 GOLANG_MIN_PATCH_VERSION='0'
 GOLANG_MIN_PATCH_VERSION='0'
+GOLANG_MIN_VERSION="${GOLANG_MIN_MAJOR_VERSION}.${GOLANG_MIN_MINOR_VERSION}.${GOLANG_MIN_PATCH_VERSION}"
 
 
 GOLANG_TEMP_PATH="${TMPDIR}/go-toolchain"
 GOLANG_TEMP_PATH="${TMPDIR}/go-toolchain"
 
 
@@ -48,49 +49,84 @@ install_go_toolchain() {
     GOLANG_ARCHIVE_NAME="${GOLANG_TEMP_PATH}/golang.tar.gz"
     GOLANG_ARCHIVE_NAME="${GOLANG_TEMP_PATH}/golang.tar.gz"
     GOLANG_CHECKSUM_FILE="${GOLANG_TEMP_PATH}/golang.sha256sums"
     GOLANG_CHECKSUM_FILE="${GOLANG_TEMP_PATH}/golang.sha256sums"
 
 
-    if [ "$(uname -s)" != "Linux" ]; then
-        GOLANG_FAILURE_REASON="We do not support automatic handling of a Go toolchain on this system, you must install one manually."
-        return 1
-    fi
-
-    case "$(uname -m)" in
-        i?86)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-386.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="05d09041b5a1193c14e4b2db3f7fcc649b236c567f5eb93305c537851b72dd95"
-            ;;
-        x86_64)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-amd64.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="3f934f40ac360b9c01f616a9aa1796d227d8b0328bf64cb045c7b8c4ee9caea4"
-            ;;
-        aarch64)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-arm64.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="e2e8aa88e1b5170a0d495d7d9c766af2b2b6c6925a8f8956d834ad6b4cacbd9a"
-            ;;
-        armv*)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-armv6l.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="6a8eda6cc6a799ff25e74ce0c13fdc1a76c0983a0bb07c789a2a3454bf6ec9b2"
+    case "$(uname -s)" in
+        Linux)
+            case "$(uname -m)" in
+                i?86)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-386.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="05d09041b5a1193c14e4b2db3f7fcc649b236c567f5eb93305c537851b72dd95"
+                    ;;
+                x86_64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-amd64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="3f934f40ac360b9c01f616a9aa1796d227d8b0328bf64cb045c7b8c4ee9caea4"
+                    ;;
+                aarch64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-arm64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="e2e8aa88e1b5170a0d495d7d9c766af2b2b6c6925a8f8956d834ad6b4cacbd9a"
+                    ;;
+                armv*)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-armv6l.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="6a8eda6cc6a799ff25e74ce0c13fdc1a76c0983a0bb07c789a2a3454bf6ec9b2"
+                    ;;
+                ppc64le)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-ppc64le.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="e872b1e9a3f2f08fd4554615a32ca9123a4ba877ab6d19d36abc3424f86bc07f"
+                    ;;
+                riscv64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-riscv64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="86a2fe6597af4b37d98bca632f109034b624786a8d9c1504d340661355ed31f7"
+                    ;;
+                s390x)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-s390x.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="92894d0f732d3379bc414ffdd617eaadad47e1d72610e10d69a1156db03fc052"
+                    ;;
+                *)
+                    GOLANG_FAILURE_REASON="Linux $(uname -m) platform is not supported out-of-box by Go, you must install a toolchain for it yourself."
+                    return 1
+                    ;;
+            esac
             ;;
             ;;
-        ppc64le)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-ppc64le.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="e872b1e9a3f2f08fd4554615a32ca9123a4ba877ab6d19d36abc3424f86bc07f"
-            ;;
-        riscv64)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-riscv64.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="86a2fe6597af4b37d98bca632f109034b624786a8d9c1504d340661355ed31f7"
-            ;;
-        s390x)
-            GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.21.6.linux-s390x.tar.gz"
-            GOLANG_ARCHIVE_CHECKSUM="92894d0f732d3379bc414ffdd617eaadad47e1d72610e10d69a1156db03fc052"
+        FreeBSD)
+            case "$(uname -m)" in
+                386)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.22.0.freebsd-386.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="b8065da37783e8b9e7086365a54d74537e832c92311b61101a66989ab2458d8e"
+                    ;;
+                amd64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.22.0.freebsd-amd64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="50f421c7f217083ac94aab1e09400cb9c2fea7d337679ec11f1638a11460da30"
+                    ;;
+                arm)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.22.0.freebsd-arm.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="c9c8b305f90903536f4981bad9f029828c2483b3216ca1783777344fbe603f2d"
+                    ;;
+                arm64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.22.0.freebsd-arm64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="e23385e5c640787fa02cd58f2301ea09e162c4d99f8ca9fa6d52766f428a933d"
+                    ;;
+                riscv64)
+                    GOLANG_ARCHIVE_URL="https://go.dev/dl/go1.22.0.freebsd-riscv64.tar.gz"
+                    GOLANG_ARCHIVE_CHECKSUM="c8f94d1de6024546194d58e7b9370dc7ea06176aad94a675b0062c25c40cb645"
+                    ;;
+                *)
+                    GOLANG_FAILURE_REASON="FreeBSD $(uname -m) platform is not supported out-of-box by Go, you must install a toolchain for it yourself."
+                    return 1
+                    ;;
+            esac
             ;;
             ;;
         *)
         *)
-            GOLANG_FAILURE_REASON="Linux $(uname -m) platform is not supported out-of-box by Go, you must install a toolchain for it yourself."
+            GOLANG_FAILURE_REASON="We do not support automatic handling of a Go toolchain on this system, you must install one manually."
             return 1
             return 1
             ;;
             ;;
     esac
     esac
 
 
-    if [ -d '/usr/local/go' ]; then
-        GOLANG_FAILURE_REASON="Refusing to overwrite existing Go toolchain install at /usr/local/go, it needs to be updated manually."
-        return 1
+    if [ -d '/usr/local/go' ]; then 
+        if [ -f '/usr/local/go/.installed-by-netdata' ]; then
+            rm -rf /usr/local/go
+        else
+            GOLANG_FAILURE_REASON="Refusing to overwrite existing Go toolchain install at /usr/local/go, it needs to be updated manually."
+            return 1
+        fi
     fi
     fi
 
 
     mkdir -p "${GOLANG_TEMP_PATH}"
     mkdir -p "${GOLANG_TEMP_PATH}"
@@ -112,6 +148,8 @@ install_go_toolchain() {
         return 1
         return 1
     fi
     fi
 
 
+    touch /usr/local/go/.installed-by-netdata
+
     rm -rf "${GOLANG_TEMP_PATH}"
     rm -rf "${GOLANG_TEMP_PATH}"
 }
 }
 
 

+ 39 - 0
packaging/cmake/Modules/FindGo.cmake

@@ -0,0 +1,39 @@
+# Custom CMake module to find the Go toolchain
+#
+# Copyright (c) 2024 Netdata Inc
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This is a relatively orthodox CMake Find Module. It can be used by
+# simply including it and then invoking `find_package(Go)`.
+#
+# Version handling is done by CMake itself via the
+# find_package_handle_standard_args() function, so `find_package(Go 1.21)`
+# will also work correctly.
+
+if(GO_FOUND)
+    return()
+endif()
+
+# Two passes are needed here so that we prefer a copy in `/usr/local/go/bin` over a system copy.
+find_program(GO_EXECUTABLE go PATHS /usr/local/go/bin DOC "Go toolchain" NO_DEFAULT_PATH)
+find_program(GO_EXECUTABLE go DOC "Go toolchain")
+
+if (GO_EXECUTABLE)
+  execute_process(
+       COMMAND ${GO_EXECUTABLE} version
+       OUTPUT_VARIABLE GO_VERSION_STRING
+       RESULT_VARIABLE RESULT
+  )
+  if (RESULT EQUAL 0)
+    string(REGEX MATCH "go([0-9]+\\.[0-9]+(\\.[0-9]+)?)" GO_VERSION_STRING "${GO_VERSION_STRING}")
+    string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" GO_VERSION_STRING "${GO_VERSION_STRING}")
+  endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+    Go
+    REQUIRED_VARS GO_EXECUTABLE
+    VERSION_VAR GO_VERSION_STRING
+)

Некоторые файлы не были показаны из-за большого количества измененных файлов