Skip to content

Commit 959c32f

Browse files
committedMar 7, 2025·
Add Prometheus Node Exporter as a system install
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent 6551b09 commit 959c32f

File tree

4 files changed

+170
-0
lines changed

4 files changed

+170
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ Run the following to see what's available `arkade system install`:
251251
gitlab-runner Install GitLab Runner
252252
go Install Go
253253
node Install Node.js
254+
node_exporter Install Node Exporter
254255
prometheus Install Prometheus
255256
pwsh Install Powershell
256257
registry Install registry

‎cmd/system/install.go

+2
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,7 @@ func MakeInstall() *cobra.Command {
3737
command.AddCommand(MakeInstallPowershell())
3838
command.AddCommand(MakeInstallCaddyServer())
3939

40+
command.AddCommand(MakeInstallNodeExporter())
41+
4042
return command
4143
}

‎cmd/system/nodeexporter.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright (c) arkade author(s) 2024. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
package system
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"os"
10+
"strings"
11+
12+
"github.com/alexellis/arkade/pkg/env"
13+
"github.com/alexellis/arkade/pkg/get"
14+
"github.com/spf13/cobra"
15+
)
16+
17+
func MakeInstallNodeExporter() *cobra.Command {
18+
command := &cobra.Command{
19+
Use: "node_exporter",
20+
Short: "Install Node Exporter",
21+
Long: `Install Node Exporter which is a Prometheus exporter for hardware and OS
22+
metrics exposed by a server/container such as CPU/RAM/Disk/Network.`,
23+
RunE: installNodeExporterE,
24+
SilenceUsage: true,
25+
}
26+
27+
command.Flags().StringP("version", "v", "", "The version for Go, or leave blank for pinned version")
28+
command.Flags().String("path", "/usr/local/", "Installation path, where a go subfolder will be created")
29+
command.Flags().Bool("progress", true, "Show download progress")
30+
command.Flags().Bool("systemd", false, "Install and start a systemd service")
31+
32+
return command
33+
}
34+
35+
func installNodeExporterE(cmd *cobra.Command, args []string) error {
36+
installPath, _ := cmd.Flags().GetString("path")
37+
version, _ := cmd.Flags().GetString("version")
38+
progress, _ := cmd.Flags().GetBool("progress")
39+
systemd, _ := cmd.Flags().GetBool("systemd")
40+
41+
arch, osVer := env.GetClientArch()
42+
43+
if cmd.Flags().Changed("os") {
44+
osVer, _ = cmd.Flags().GetString("os")
45+
}
46+
if cmd.Flags().Changed("arch") {
47+
arch, _ = cmd.Flags().GetString("arch")
48+
}
49+
50+
if strings.ToLower(osVer) != "linux" && strings.ToLower(osVer) != "darwin" {
51+
return fmt.Errorf("this app only supports Linux and Darwin")
52+
}
53+
54+
tools := get.MakeTools()
55+
var tool *get.Tool
56+
for _, t := range tools {
57+
if t.Name == "node_exporter" {
58+
tool = &t
59+
break
60+
}
61+
}
62+
63+
if tool == nil {
64+
return fmt.Errorf("unable to find node_exporter definition")
65+
}
66+
67+
fmt.Printf("Installing node_exporter Server to %s\n", installPath)
68+
69+
installPath = strings.ReplaceAll(installPath, "$HOME", os.Getenv("HOME"))
70+
71+
if err := os.MkdirAll(installPath, 0755); err != nil && !os.IsExist(err) {
72+
fmt.Printf("Error creating directory %s, error: %s\n", installPath, err.Error())
73+
}
74+
75+
if version == "" {
76+
v, err := get.FindGitHubRelease("prometheus", "node_exporter")
77+
if err != nil {
78+
return err
79+
}
80+
version = v
81+
} else if !strings.HasPrefix(version, "v") {
82+
version = "v" + version
83+
}
84+
85+
outFilePath, _, err := get.Download(tool, arch, osVer, version, installPath, progress, !progress)
86+
if err != nil {
87+
return err
88+
}
89+
if err = os.Chmod(outFilePath, readWriteExecuteEveryone); err != nil {
90+
return err
91+
}
92+
93+
if systemd && strings.ToLower(osVer) != "linux" {
94+
return fmt.Errorf("systemd is only supported on Linux")
95+
}
96+
97+
if systemd {
98+
systemdUnit := generateUnit(outFilePath)
99+
unitName := "/etc/systemd/system/node_exporter.service"
100+
if err := os.WriteFile(unitName, []byte(systemdUnit), readWriteExecuteEveryone); err != nil {
101+
return err
102+
}
103+
104+
fmt.Printf("Wrote: %s\n", systemdUnit)
105+
106+
if _, err = executeShellCmd(context.Background(), "systemctl", "daemon-reload"); err != nil {
107+
return err
108+
}
109+
110+
if _, err = executeShellCmd(context.Background(), "systemctl", "enable", "node_exporter", "--now"); err != nil {
111+
return err
112+
}
113+
114+
fmt.Printf("Started node_exporter\n")
115+
116+
}
117+
return nil
118+
}
119+
120+
func generateUnit(outFilePath string) string {
121+
return fmt.Sprintf(`[Unit]
122+
Description=Node Exporter
123+
After=network.target
124+
125+
[Service]
126+
ExecStart=%s/node_exporter
127+
128+
[Install]
129+
WantedBy=multi-user.target
130+
`, outFilePath)
131+
}

‎pkg/get/tools.go

+36
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,42 @@ https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/{{.Name}}
27572757
`,
27582758
})
27592759

2760+
tools = append(tools,
2761+
Tool{
2762+
Owner: "prometheus",
2763+
Repo: "node_exporter",
2764+
Name: "node_exporter",
2765+
Description: "Prometheus exporter for monitoring server metrics",
2766+
URLTemplate: `
2767+
{{$arch := ""}}
2768+
{{- if eq .Arch "x86_64" -}}
2769+
{{$arch = "amd64"}}
2770+
{{- else if eq .Arch "aarch64" -}}
2771+
{{$arch = "arm64"}}
2772+
{{- else if eq .Arch "arm64" -}}
2773+
{{$arch = "arm64"}}
2774+
{{- else if eq .Arch "armv7l" -}}
2775+
{{ $arch = "armv7" }}
2776+
{{- end -}}
2777+
2778+
{{$os := ""}}
2779+
{{ if HasPrefix .OS "ming" -}}
2780+
{{$os = "windows"}}
2781+
{{- else if eq .OS "linux" -}}
2782+
{{$os = "linux"}}
2783+
{{- else if eq .OS "darwin" -}}
2784+
{{$os = "darwin"}}
2785+
{{- end -}}
2786+
https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/{{.Repo}}-{{.VersionNumber}}.{{$os}}-{{$arch}}.tar.gz`,
2787+
BinaryTemplate: `
2788+
{{ if HasPrefix .OS "ming" -}}
2789+
{{ .Name }}.exe
2790+
{{- else -}}
2791+
{{ .Name }}
2792+
{{- end -}}
2793+
`,
2794+
})
2795+
27602796
tools = append(tools,
27612797
Tool{
27622798
Owner: "siderolabs",

0 commit comments

Comments
 (0)
Please sign in to comment.