Skip to content
This repository has been archived by the owner on Oct 24, 2024. It is now read-only.

Commit

Permalink
[APP-4166] New Subsystem
Browse files Browse the repository at this point in the history
  • Loading branch information
Otterverse authored Mar 8, 2024
1 parent c272d5e commit ec9a014
Show file tree
Hide file tree
Showing 8 changed files with 1,148 additions and 0 deletions.
89 changes: 89 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
service:
golangci-lint-version: 1.55.2
run:
deadline: 900s
modules-download-mode: readonly
tests: true
linters:
enable-all: true
disable:
- asasalint
- containedctx
- contextcheck
- cyclop
- deadcode
- depguard
- exhaustivestruct
- exhaustruct
- forcetypeassert
- funlen
- gocognit
- godox
- goerr113
- gochecknoglobals
- gochecknoinits
- gocyclo
- gofmt
- goimports
- golint
- gomnd
- ifshort
- importas
- interfacebloat
- interfacer
- ireturn
- maintidx
- maligned
- makezero
- musttag
- nestif
- nlreturn
- nosnakecase
- nonamedreturns
- nosprintfhostport
- paralleltest
- prealloc
- revive
- scopelint
- structcheck
- tagliatelle
- testpackage
- thelper # false positives
- varcheck
- varnamelen
- wrapcheck
- wsl
linters-settings:
errcheck:
check-blank: true
gci:
sections:
- standard
- default
- prefix(github.com/viamrobotics/agent-syscfg)
gofumpt:
lang-version: "1.21"
extra-rules: true
govet:
enable-all: true
disable:
- fieldalignment
- shadow
- composites
lll:
line-length: 140
issues:
exclude-rules:
- path: _test\.go$
linters:
- dupword
- errcheck
- exhaustive
- goconst
- gosec
- path: ^cmd/client/
linters:
- forbidigo
exclude-use-default: false
max-per-linter: 0
max-same-issues: 0
52 changes: 52 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
GOOS ?= "linux"
GOARCH ?= $(shell go env GOARCH)
ifeq ($(GOARCH),amd64)
LINUX_ARCH = x86_64
else ifeq ($(GOARCH),arm64)
LINUX_ARCH = aarch64
endif

GIT_REVISION = $(shell git rev-parse HEAD | tr -d '\n')
TAG_VERSION ?= $(shell git tag --points-at | sort -Vr | head -n1 | cut -c2-)
ifeq ($(TAG_VERSION),)
PATH_VERSION = custom
else
PATH_VERSION = v$(TAG_VERSION)
endif

LDFLAGS = "-s -w -X 'github.com/viamrobotics/agent-syscfg.Version=${TAG_VERSION}' -X 'github.com/viamrobotics/agent-syscfg.GitRevision=${GIT_REVISION}'"
TAGS = osusergo,netgo

.DEFAULT_GOAL := bin/viam-agent-syscfg-$(PATH_VERSION)-$(LINUX_ARCH)

.PHONY: all
all: amd64 arm64

.PHONY: arm64
arm64:
make GOARCH=arm64

.PHONY: amd64
amd64:
make GOARCH=amd64

bin/viam-agent-syscfg-$(PATH_VERSION)-$(LINUX_ARCH): go.* *.go */*/*.go
go build -o $@ -tags $(TAGS) -ldflags $(LDFLAGS) ./cmd/viam-agent-syscfg/main.go
test "$(PATH_VERSION)" != "custom" && cp $@ bin/viam-agent-syscfg-stable-$(LINUX_ARCH) || true

.PHONY: clean
clean:
rm -rf bin/

bin/golangci-lint:
GOBIN=`pwd`/bin go install github.com/golangci/golangci-lint/cmd/[email protected]

.PHONY: lint
lint: bin/golangci-lint
go mod tidy
bin/golangci-lint run -v --fix

.PHONY: upload-stable
upload-stable: bin/viam-agent-syscfg-$(PATH_VERSION)-x86_64 bin/viam-agent-syscfg-$(PATH_VERSION)-aarch64 bin/viam-agent-syscfg-stable-x86_64 bin/viam-agent-syscfg-stable-aarch64
test "$(PATH_VERSION)" != "custom"
gsutil -h "Cache-Control:no-cache" cp bin/viam-agent-syscfg-$(PATH_VERSION)-x86_64 bin/viam-agent-syscfg-$(PATH_VERSION)-aarch64 bin/viam-agent-syscfg-stable-x86_64 bin/viam-agent-syscfg-stable-aarch64 gs://packages.viam.com/apps/viam-agent-syscfg/
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# Agent Syscfg
This is a subsystem (plugin) for the viam-agent that provides a number of system/os configuration helpers.

## Current Options
Parameters are set via the `attributes` object of the agent-syscfg object in the agent config (currently via "Raw JSON" editor in https://app.viam.com/ )

Configuration is split into sections, each of which will control a different area of system management and/or configuration. Currently only logging control is available.

### Logging
Two parameters can be set for logging control. `system_max_use` and `runtime_max_use` The first sets the maximum disk space journald will user for persistent log storage. The second, the runtime/temporary limit. Both of these will be configured to 512M by default if not set. Numeric values are in bytes, with optional single letter suffix for larger units, e.g. K, M, or G.
There is also `disable` which may be set to `true` to remove any prior tweaks to the logging config and disable the use of defaults.

## Example Config

```json
"agent-syscfg": {
"release_channel": "stable",
"attributes": {
"logging": {
"disable": true,
"system_max_use": "128M",
"runtime_max_use": "96M"
}
}
}
```
135 changes: 135 additions & 0 deletions cmd/viam-agent-syscfg/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package main

import (
"bytes"
"context"
"fmt"
"os"
"os/signal"
"sync"
"sync/atomic"
"syscall"
"time"

"github.com/edaniels/golog"
"github.com/jessevdk/go-flags"

syscfg "github.com/viamrobotics/agent-syscfg"
)

var (
// only changed/set at startup, so no mutex.
log = golog.NewDevelopmentLogger("agent-syscfg")
activeBackgroundWorkers sync.WaitGroup
)

func main() {
var opts struct {
Config string `default:"/opt/viam/etc/agent-syscfg.json" description:"Path to config file" long:"config" short:"c"`
Debug bool `description:"Enable debug logging" long:"debug" short:"d"`
Help bool `description:"Show this help message" long:"help" short:"h"`
Version bool `description:"Show version" long:"version" short:"v"`
}

parser := flags.NewParser(&opts, flags.IgnoreUnknown)
parser.Usage = "runs as a background service and manages updates and the process lifecycle for viam-server."

_, err := parser.Parse()
if err != nil {
log.Fatal(err)
}

if opts.Help {
var b bytes.Buffer
parser.WriteHelp(&b)
//nolint:forbidigo
fmt.Println(b.String())
return
}

if opts.Version {
//nolint:forbidigo
fmt.Printf("Version: %s\nGit Revision: %s\n", syscfg.GetVersion(), syscfg.GetRevision())
return
}

if opts.Debug {
log = golog.NewDebugLogger("agent-syscfg")
}

ctx := setupExitSignalHandling()
defer activeBackgroundWorkers.Wait()

cfg, err := syscfg.LoadConfig(opts.Config)
if err != nil {
log.Warn(err)
}

log.Debugf("Config: %+v", cfg)
// core one-shot functions start

// set journald max size limits
syscfg.EnforceLogging(cfg.Logging, log)

// core one-shot functions end

// exact text "startup complete" is important, the parent process will watch for this line to indicate startup is successful
log.Info("agent-syscfg startup complete")

// do nothing forever, just respond to health checks
for {
if !syscfg.HealthySleep(ctx, time.Minute) {
break
}
// future tweaks that require regular checks/updates/etc (non one-shots) will go here
}

log.Info("agent-syscfg subsystem exiting")
}

func setupExitSignalHandling() context.Context {
ctx, cancel := context.WithCancel(context.Background())
sigChan := make(chan os.Signal, 16)

healthcheckRequest := &atomic.Bool{}
ctx = context.WithValue(ctx, syscfg.HCReqKey, healthcheckRequest)

activeBackgroundWorkers.Add(1)
go func() {
defer activeBackgroundWorkers.Done()
defer cancel()
for {
sig := <-sigChan
switch sig {
// things we exit for
case os.Interrupt:
fallthrough
case syscall.SIGQUIT:
fallthrough
case syscall.SIGABRT:
fallthrough
case syscall.SIGTERM:
log.Info("exit signal received")
signal.Ignore(os.Interrupt, syscall.SIGTERM, syscall.SIGABRT) // keeping SIGQUIT for stack trace debugging
return

// this will eventually be handled elsewhere as a restart, not exit
case syscall.SIGHUP:

// ignore SIGURG entirely, it's used for real-time scheduling notifications
case syscall.SIGURG:

// used by parent viam-agent for healthchecks
case syscall.SIGUSR1:
healthcheckRequest.Store(true)

// log everything else
default:
log.Debugw("received unknown signal", "signal", sig)
}
}
}()

signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGUSR1)
return ctx
}
18 changes: 18 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module github.com/viamrobotics/agent-syscfg

go 1.21.4

require (
github.com/edaniels/golog v0.0.0-20230215213219-28954395e8d0
github.com/jessevdk/go-flags v1.5.0
github.com/pkg/errors v0.9.1
github.com/sergeymakinen/go-systemdconf/v2 v2.0.2
go.uber.org/zap v1.23.0
)

require (
github.com/benbjohnson/clock v1.1.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/sys v0.5.0 // indirect
)
Loading

0 comments on commit ec9a014

Please sign in to comment.