Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 55 additions & 21 deletions cmd/omni/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/spf13/cobra"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.yaml.in/yaml/v4"
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import path go.yaml.in/yaml/v4 appears unusual. The standard YAML library for Go uses the import path gopkg.in/yaml.v3. Please verify this is the correct package and that go.yaml.in/yaml/v4 is a valid, maintained library. If this is experimental or an RC version (v4.0.0-rc.2 as seen in go.mod), consider using the stable gopkg.in/yaml.v3 instead.

Suggested change
"go.yaml.in/yaml/v4"
"gopkg.in/yaml.v3"

Copilot uses AI. Check for mistakes.

"github.com/siderolabs/omni/client/pkg/constants"
"github.com/siderolabs/omni/client/pkg/panichandler"
Expand All @@ -37,28 +38,14 @@ var rootCmd = &cobra.Command{
SilenceUsage: true,
Version: version.Tag,
RunE: func(*cobra.Command, []string) error {
var loggerConfig zap.Config

if constants.IsDebugBuild {
loggerConfig = zap.NewDevelopmentConfig()
loggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
} else {
loggerConfig = zap.NewProductionConfig()
}

if !rootCmdArgs.debug {
loggerConfig.Level.SetLevel(zap.InfoLevel)
} else {
loggerConfig.Level.SetLevel(zap.DebugLevel)
}

logger, err := loggerConfig.Build(
zap.AddStacktrace(zapcore.FatalLevel), // only print stack traces for fatal errors
)
logger, err := buildLogger()
if err != nil {
return fmt.Errorf("failed to set up logging: %w", err)
}

zap.ReplaceGlobals(logger)
zap.RedirectStdLog(logger)

signals := make(chan os.Signal, 1)

signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
Expand All @@ -75,11 +62,24 @@ var rootCmd = &cobra.Command{
cancel()
}, logger)

config, err := app.PrepareConfig(logger, cmdConfig)
skipConfigValidation := rootCmdArgs.printConfigAndExit

config, err := app.PrepareConfig(skipConfigValidation, logger, cmdConfig)
if err != nil {
return err
}

if rootCmdArgs.printConfigAndExit {
encoder := yaml.NewEncoder(os.Stdout)
encoder.SetIndent(2)

if err := encoder.Encode(config); err != nil {
return err
}

return nil
}

ctx = actor.MarkContextAsInternalActor(ctx)

state, err := omni.NewState(ctx, config, logger, prometheus.DefaultRegisterer)
Expand All @@ -106,8 +106,9 @@ var rootCmd = &cobra.Command{
}

var rootCmdArgs struct {
configPath string
debug bool
configPath string
debug bool
printConfigAndExit bool
}

// Execute the command.
Expand Down Expand Up @@ -140,6 +141,9 @@ var cmdConfig = config.Default()
func newCommand() *cobra.Command {
rootCmd.Flags().BoolVar(&rootCmdArgs.debug, "debug", constants.IsDebugBuild, "enable debug logs.")

rootCmd.Flags().BoolVar(&rootCmdArgs.printConfigAndExit, "print-config-and-exit", false, "print the final configuration and exit.")
rootCmd.Flags().MarkHidden("print-config-and-exit") //nolint:errcheck

rootCmd.Flags().StringVar(&cmdConfig.Account.ID, "account-id", cmdConfig.Account.ID, "instance account ID, should never be changed.")
rootCmd.Flags().StringVar(&cmdConfig.Account.Name, "name", cmdConfig.Account.Name, "instance user-facing name.")
rootCmd.Flags().StringVar(&cmdConfig.Account.UserPilot.AppToken, "user-pilot-app-token", cmdConfig.Account.UserPilot.AppToken, "user pilot app token.")
Expand All @@ -156,6 +160,36 @@ func newCommand() *cobra.Command {
return rootCmd
}

func buildLogger() (*zap.Logger, error) {
if rootCmdArgs.printConfigAndExit {
return zap.NewNop(), nil
}

var loggerConfig zap.Config

if constants.IsDebugBuild {
loggerConfig = zap.NewDevelopmentConfig()
loggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
} else {
loggerConfig = zap.NewProductionConfig()
}

if !rootCmdArgs.debug {
loggerConfig.Level.SetLevel(zap.InfoLevel)
} else {
loggerConfig.Level.SetLevel(zap.DebugLevel)
}

logger, err := loggerConfig.Build(
zap.AddStacktrace(zapcore.FatalLevel), // only print stack traces for fatal errors
)
if err != nil {
return nil, fmt.Errorf("failed to set up logging: %w", err)
}

return logger, nil
}

func defineServiceFlags() {
// API
rootCmd.Flags().StringVar(
Expand Down
4 changes: 2 additions & 2 deletions cmd/omni/pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ import (
)

// PrepareConfig prepare the Omni configuration.
func PrepareConfig(logger *zap.Logger, params ...*config.Params) (*config.Params, error) {
func PrepareConfig(skipValidation bool, logger *zap.Logger, params ...*config.Params) (*config.Params, error) {
var err error

config.Config, err = config.Init(logger, params...)
config.Config, err = config.Init(skipValidation, logger, params...)
if err != nil {
return nil, err
}
Expand Down
23 changes: 23 additions & 0 deletions deploy/helm/omni-v2/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
6 changes: 6 additions & 0 deletions deploy/helm/omni-v2/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: omni-v2
description: A helm chart to deploy Omni on a Kubernetes cluster
type: application
version: 2.0.0
appVersion: "v1.32.0"
62 changes: 62 additions & 0 deletions deploy/helm/omni-v2/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "omni-v2.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "omni-v2.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "omni-v2.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "omni-v2.labels" -}}
helm.sh/chart: {{ include "omni-v2.chart" . }}
{{ include "omni-v2.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "omni-v2.selectorLabels" -}}
app.kubernetes.io/name: {{ include "omni-v2.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "omni-v2.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "omni-v2.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
9 changes: 9 additions & 0 deletions deploy/helm/omni-v2/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "omni-v2.fullname" . }}
labels:
{{- include "omni-v2.labels" . | nindent 4 }}
data:
config.yaml: |
{{- .Values.config | toYamlPretty | nindent 4 }}
117 changes: 117 additions & 0 deletions deploy/helm/omni-v2/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "omni-v2.fullname" . }}
labels:
{{- include "omni-v2.labels" . | nindent 4 }}
spec:
{{- with .Values.strategy }}
strategy:
{{- toYaml . | nindent 4 }}
{{- end }}
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "omni-v2.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
# https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "omni-v2.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "omni-v2.serviceAccountName" . }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
envFrom:
- secretRef:
name: {{ include "omni-v2.fullname" . }}
{{- if .Values.existingSecret }}
- secretRef:
name: {{ .Values.existingSecret }}
{{- end }}
{{- with .Values.args }}
args:
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- name: omni
containerPort: 8080
protocol: TCP
- name: siderolink-api
containerPort: 8090
protocol: TCP
- name: k8s-proxy
containerPort: 8095
protocol: TCP
- name: wireguard
containerPort: 50180
protocol: UDP
{{- with .Values.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: config
configMap:
name: {{ include "omni-v2.fullname" . }}
- name: data
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim | default (include "omni-v2.fullname" .) }}
{{- else }}
emptyDir: {}
{{- end }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
Loading
Loading