Skip to content

Commit

Permalink
Add Prometheus Node Exporter as a system install
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
  • Loading branch information
alexellis committed Mar 7, 2025
1 parent 6551b09 commit 959c32f
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ Run the following to see what's available `arkade system install`:
gitlab-runner Install GitLab Runner
go Install Go
node Install Node.js
node_exporter Install Node Exporter
prometheus Install Prometheus
pwsh Install Powershell
registry Install registry
Expand Down
2 changes: 2 additions & 0 deletions cmd/system/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ func MakeInstall() *cobra.Command {
command.AddCommand(MakeInstallPowershell())
command.AddCommand(MakeInstallCaddyServer())

command.AddCommand(MakeInstallNodeExporter())

return command
}
131 changes: 131 additions & 0 deletions cmd/system/nodeexporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) arkade author(s) 2024. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package system

import (
"context"
"fmt"
"os"
"strings"

"github.com/alexellis/arkade/pkg/env"
"github.com/alexellis/arkade/pkg/get"
"github.com/spf13/cobra"
)

func MakeInstallNodeExporter() *cobra.Command {
command := &cobra.Command{
Use: "node_exporter",
Short: "Install Node Exporter",
Long: `Install Node Exporter which is a Prometheus exporter for hardware and OS
metrics exposed by a server/container such as CPU/RAM/Disk/Network.`,
RunE: installNodeExporterE,
SilenceUsage: true,
}

command.Flags().StringP("version", "v", "", "The version for Go, or leave blank for pinned version")
command.Flags().String("path", "/usr/local/", "Installation path, where a go subfolder will be created")
command.Flags().Bool("progress", true, "Show download progress")
command.Flags().Bool("systemd", false, "Install and start a systemd service")

return command
}

func installNodeExporterE(cmd *cobra.Command, args []string) error {
installPath, _ := cmd.Flags().GetString("path")
version, _ := cmd.Flags().GetString("version")
progress, _ := cmd.Flags().GetBool("progress")
systemd, _ := cmd.Flags().GetBool("systemd")

arch, osVer := env.GetClientArch()

if cmd.Flags().Changed("os") {
osVer, _ = cmd.Flags().GetString("os")
}
if cmd.Flags().Changed("arch") {
arch, _ = cmd.Flags().GetString("arch")
}

if strings.ToLower(osVer) != "linux" && strings.ToLower(osVer) != "darwin" {
return fmt.Errorf("this app only supports Linux and Darwin")
}

tools := get.MakeTools()
var tool *get.Tool
for _, t := range tools {
if t.Name == "node_exporter" {
tool = &t
break
}
}

if tool == nil {
return fmt.Errorf("unable to find node_exporter definition")
}

fmt.Printf("Installing node_exporter Server to %s\n", installPath)

installPath = strings.ReplaceAll(installPath, "$HOME", os.Getenv("HOME"))

if err := os.MkdirAll(installPath, 0755); err != nil && !os.IsExist(err) {
fmt.Printf("Error creating directory %s, error: %s\n", installPath, err.Error())
}

if version == "" {
v, err := get.FindGitHubRelease("prometheus", "node_exporter")
if err != nil {
return err
}
version = v
} else if !strings.HasPrefix(version, "v") {
version = "v" + version
}

outFilePath, _, err := get.Download(tool, arch, osVer, version, installPath, progress, !progress)
if err != nil {
return err
}
if err = os.Chmod(outFilePath, readWriteExecuteEveryone); err != nil {
return err
}

if systemd && strings.ToLower(osVer) != "linux" {
return fmt.Errorf("systemd is only supported on Linux")
}

if systemd {
systemdUnit := generateUnit(outFilePath)
unitName := "/etc/systemd/system/node_exporter.service"
if err := os.WriteFile(unitName, []byte(systemdUnit), readWriteExecuteEveryone); err != nil {
return err
}

fmt.Printf("Wrote: %s\n", systemdUnit)

if _, err = executeShellCmd(context.Background(), "systemctl", "daemon-reload"); err != nil {
return err
}

if _, err = executeShellCmd(context.Background(), "systemctl", "enable", "node_exporter", "--now"); err != nil {
return err
}

fmt.Printf("Started node_exporter\n")

}
return nil
}

func generateUnit(outFilePath string) string {
return fmt.Sprintf(`[Unit]
Description=Node Exporter
After=network.target
[Service]
ExecStart=%s/node_exporter
[Install]
WantedBy=multi-user.target
`, outFilePath)
}
36 changes: 36 additions & 0 deletions pkg/get/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,42 @@ https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/{{.Name}}
`,
})

tools = append(tools,
Tool{
Owner: "prometheus",
Repo: "node_exporter",
Name: "node_exporter",
Description: "Prometheus exporter for monitoring server metrics",
URLTemplate: `
{{$arch := ""}}
{{- if eq .Arch "x86_64" -}}
{{$arch = "amd64"}}
{{- else if eq .Arch "aarch64" -}}
{{$arch = "arm64"}}
{{- else if eq .Arch "arm64" -}}
{{$arch = "arm64"}}
{{- else if eq .Arch "armv7l" -}}
{{ $arch = "armv7" }}
{{- end -}}
{{$os := ""}}
{{ if HasPrefix .OS "ming" -}}
{{$os = "windows"}}
{{- else if eq .OS "linux" -}}
{{$os = "linux"}}
{{- else if eq .OS "darwin" -}}
{{$os = "darwin"}}
{{- end -}}
https://github.com/{{.Owner}}/{{.Repo}}/releases/download/{{.Version}}/{{.Repo}}-{{.VersionNumber}}.{{$os}}-{{$arch}}.tar.gz`,
BinaryTemplate: `
{{ if HasPrefix .OS "ming" -}}
{{ .Name }}.exe
{{- else -}}
{{ .Name }}
{{- end -}}
`,
})

tools = append(tools,
Tool{
Owner: "siderolabs",
Expand Down

0 comments on commit 959c32f

Please sign in to comment.