Skip to content
Open
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
51 changes: 28 additions & 23 deletions device-discovery-agent/cmd/device-discovery/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
"context"
"flag"
"fmt"
"log"
"os"

"device-discovery/internal/config"
"device-discovery/internal/logger"
"device-discovery/internal/mode"
"device-discovery/internal/sysinfo"
)
Expand All @@ -25,14 +25,17 @@ func main() {
// Step 1: Parse CLI flags to get -config and -use-kernel-args flags
parseInitialFlags(cfg)

// Initialize logger early (before other operations)
logger.InitLogger(cfg.Debug)

// Track if kernel args were explicitly enabled via CLI
kernelArgsFromCLI := cfg.UseKernelArgs

// Step 2: Load config file first (if specified)
// This allows us to check if USE_KERNEL_ARGS is set in the config
if cfg.ConfigFile != "" {
if err := config.LoadFromFile(cfg, cfg.ConfigFile); err != nil {
log.Fatalf("Failed to load config file: %v", err)
logger.Logger.Fatalf("Failed to load config file: %v", err)
}
}

Expand All @@ -41,20 +44,23 @@ func main() {
// then reload config file to let it override
if cfg.UseKernelArgs {
if err := config.LoadFromKernelArgs(cfg); err != nil {
log.Fatalf("Failed to parse kernel arguments: %v", err)
logger.Logger.Fatalf("Failed to parse kernel arguments: %v", err)
}

// If USE_KERNEL_ARGS was set in config file (not CLI), reload config to override kernel args
if !kernelArgsFromCLI && cfg.ConfigFile != "" {
if err := config.LoadFromFile(cfg, cfg.ConfigFile); err != nil {
log.Fatalf("Failed to reload config file: %v", err)
logger.Logger.Fatalf("Failed to reload config file: %v", err)
}
}
}

// Step 4: Re-parse CLI flags - overrides everything (highest priority)
parseFinalFlags(cfg)

// Re-initialize logger in case debug flag changed
logger.InitLogger(cfg.Debug)

// Validate required flags if not auto-detecting
if !cfg.AutoDetect {
validateConfig(cfg)
Expand All @@ -63,7 +69,7 @@ func main() {
// Auto-detect system information if requested
if cfg.AutoDetect || cfg.MacAddr != "" {
if err := sysinfo.AutoDetectSystemInfo(cfg); err != nil {
log.Fatalf("Failed to auto-detect system information: %v", err)
logger.Logger.Fatalf("Failed to auto-detect system information: %v", err)
}
}

Expand All @@ -72,37 +78,36 @@ func main() {

// Write validated configuration to file
if err := config.WriteToFile(cfg); err != nil {
log.Fatalf("Failed to write configuration to file: %v", err)
logger.Logger.Fatalf("Failed to write configuration to file: %v", err)
}

// Add extra hosts if provided
if cfg.ExtraHosts != "" {
if err := config.UpdateHosts(cfg.ExtraHosts); err != nil {
log.Fatalf("Failed to add extra hosts: %v", err)
logger.Logger.Fatalf("Failed to add extra hosts: %v", err)
}
}

// Display configuration
fmt.Println("Device Discovery Configuration:")
fmt.Printf(" Onboarding Manager: %s:%d\n", cfg.ObmSvc, cfg.ObmPort)
fmt.Printf(" Onboarding Stream: %s:%d\n", cfg.ObsSvc, cfg.ObmPort)
fmt.Printf(" Keycloak URL: %s\n", cfg.KeycloakURL)
fmt.Printf(" MAC Address: %s\n", cfg.MacAddr)
fmt.Printf(" Serial Number: %s\n", cfg.SerialNumber)
fmt.Printf(" UUID: %s\n", cfg.UUID)
fmt.Printf(" IP Address: %s\n", cfg.IPAddress)
fmt.Printf(" Debug Mode: %v\n", cfg.Debug)
// Display configuration (DEBUG mode only)
logger.Logger.Debug("Device Discovery Configuration:")
logger.Logger.Debugf(" Onboarding Manager: %s:%d", cfg.ObmSvc, cfg.ObmPort)
logger.Logger.Debugf(" Onboarding Stream: %s:%d", cfg.ObsSvc, cfg.ObmPort)
logger.Logger.Debugf(" Keycloak URL: %s", cfg.KeycloakURL)
logger.Logger.Debugf(" MAC Address: %s", cfg.MacAddr)
logger.Logger.Debugf(" Serial Number: %s", cfg.SerialNumber)
logger.Logger.Debugf(" UUID: %s", cfg.UUID)
logger.Logger.Debugf(" IP Address: %s", cfg.IPAddress)
logger.Logger.Debugf(" Debug Mode: %v", cfg.Debug)
if cfg.Debug {
fmt.Printf(" Timeout: %v\n", cfg.Timeout)
logger.Logger.Debugf(" Timeout: %v", cfg.Timeout)
}
fmt.Println()

// Run device discovery
if err := deviceDiscovery(cfg); err != nil {
log.Fatalf("Device discovery failed: %v", err)
logger.Logger.Fatalf("Device discovery failed: %v", err)
}

fmt.Println("Device discovery completed successfully")
logger.Logger.Info("Device discovery completed successfully")
}

// parseInitialFlags does the first parse to get -config and -use-kernel-args flags only
Expand Down Expand Up @@ -246,11 +251,11 @@ func deviceDiscovery(cfg *config.Config) error {
// Set a timeout when debug is true
ctx, cancel = context.WithTimeout(context.Background(), cfg.Timeout)
defer cancel()
fmt.Println("Starting device onboarding with timeout")
logger.Logger.Info("Starting device onboarding with timeout")
} else {
// Run without timeout if debug is false
ctx = context.Background()
fmt.Println("Starting device onboarding without timeout")
logger.Logger.Info("Starting device onboarding without timeout")
}

// Create controller configuration
Expand Down
1 change: 1 addition & 0 deletions device-discovery-agent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ go 1.24.9

require (
github.com/open-edge-platform/infra-onboarding/onboarding-manager v1.39.1
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af
golang.org/x/oauth2 v0.34.0
google.golang.org/grpc v1.80.0-dev
)
Expand Down
18 changes: 18 additions & 0 deletions device-discovery-agent/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
Expand All @@ -16,6 +20,15 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/open-edge-platform/infra-onboarding/onboarding-manager v1.39.1 h1:bd7SA9S101DMlkU9MQAR78CnggNe8PQ6t24375MLdqU=
github.com/open-edge-platform/infra-onboarding/onboarding-manager v1.39.1/go.mod h1:BpEsTCyKBV8zAgMEW9pWKVskhyQ7xyemo4GJCq6YYkE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af h1:Sp5TG9f7K39yfB+If0vjp97vuT74F72r8hfRpP8jLU0=
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
Expand All @@ -32,6 +45,7 @@ golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
Expand All @@ -44,3 +58,7 @@ google.golang.org/grpc v1.80.0-dev h1:n93B3+tPiXo01iQAJ2dniKR8veelXd9upFkDNvweUA
google.golang.org/grpc v1.80.0-dev/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
12 changes: 7 additions & 5 deletions device-discovery-agent/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"strconv"
"strings"
"time"

"device-discovery/internal/logger"
)

const (
Expand Down Expand Up @@ -44,7 +46,7 @@ func UpdateHosts(extraHosts string) error {
return fmt.Errorf("error updating /etc/hosts: %w", err)
}

fmt.Println("Adding extra host mappings completed")
logger.Logger.Info("Adding extra host mappings completed")
}
return nil
}
Expand Down Expand Up @@ -207,7 +209,7 @@ func LoadFromKernelArgs(cfg *Config) error {
// Map worker_id from Tinkerbell to MAC address
if kernelCfg.WorkerID != "" {
cfg.MacAddr = kernelCfg.WorkerID
fmt.Printf("Mapped worker_id from kernel args to MAC address: %s\n", kernelCfg.WorkerID)
logger.Logger.Infof("Mapped worker_id from kernel args to MAC address: %s", kernelCfg.WorkerID)
}

// DEBUG flag from kernel args
Expand All @@ -216,7 +218,7 @@ func LoadFromKernelArgs(cfg *Config) error {
if err == nil {
cfg.Debug = debug
if debug {
fmt.Println("Debug mode enabled via kernel arguments")
logger.Logger.Info("Debug mode enabled via kernel arguments")
}
}
}
Expand All @@ -226,7 +228,7 @@ func LoadFromKernelArgs(cfg *Config) error {
timeout, err := time.ParseDuration(kernelCfg.Timeout)
if err == nil {
cfg.Timeout = timeout
fmt.Printf("Timeout set from kernel args: %v\n", cfg.Timeout)
logger.Logger.Infof("Timeout set from kernel args: %v", cfg.Timeout)
}
}

Expand Down Expand Up @@ -390,6 +392,6 @@ func WriteToFile(cfg *Config) error {
fmt.Fprintf(file, "TIMEOUT=%s\n", cfg.Timeout.String())
}

fmt.Printf("Configuration written to: %s\n", EnvConfigPath)
logger.Logger.Infof("Configuration written to: %s", EnvConfigPath)
return nil
}
25 changes: 25 additions & 0 deletions device-discovery-agent/internal/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: (C) 2025 Intel Corporation
Copy link
Contributor

Choose a reason for hiding this comment

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

Update the year in the copyright header

// SPDX-License-Identifier: Apache-2.0

package logger

import (
"github.com/sirupsen/logrus"
)

// Logger is the global logger instance
var Logger = logrus.New()

// InitLogger initializes the logger with the specified debug mode
func InitLogger(debug bool) {
Logger.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
})

if debug {
Logger.SetLevel(logrus.DebugLevel)
Logger.Debug("Debug mode enabled")
} else {
Logger.SetLevel(logrus.InfoLevel)
}
}
17 changes: 9 additions & 8 deletions device-discovery-agent/internal/mode/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"device-discovery/internal/auth"
"device-discovery/internal/config"
"device-discovery/internal/logger"
"device-discovery/internal/mode/interactive"
"device-discovery/internal/mode/noninteractive"
)
Expand Down Expand Up @@ -67,7 +68,7 @@ func NewOnboardingController(cfg Config) *OnboardingController {
// It first attempts non-interactive mode, and falls back to interactive mode if the
// device is not found in the system (unless interactive mode is disabled).
func (o *OnboardingController) Execute(ctx context.Context) error {
fmt.Println("Starting device onboarding...")
logger.Logger.Info("Starting device onboarding...")

// Try non-interactive mode first
result := o.tryNonInteractiveMode(ctx)
Expand All @@ -79,7 +80,7 @@ func (o *OnboardingController) Execute(ctx context.Context) error {
}

// Fall back to interactive mode
fmt.Printf("Executing fallback to interactive mode because: %v\n", result.Error)
logger.Logger.Infof("Executing fallback to interactive mode because: %v", result.Error)
return o.executeInteractiveMode(ctx)
}

Expand All @@ -93,7 +94,7 @@ func (o *OnboardingController) Execute(ctx context.Context) error {

// tryNonInteractiveMode attempts automatic onboarding via streaming gRPC.
func (o *OnboardingController) tryNonInteractiveMode(ctx context.Context) noninteractive.StreamResult {
fmt.Println("Attempting non-interactive (streaming) onboarding...")
logger.Logger.Info("Attempting non-interactive (streaming) onboarding...")

client := noninteractive.NewClient(
o.obsSvc,
Expand All @@ -119,7 +120,7 @@ func (o *OnboardingController) completeNonInteractiveAuth(clientID, clientSecret
return fmt.Errorf("failed to save client secret: %w", err)
}

fmt.Println("Credentials written successfully.")
logger.Logger.Info("Credentials written successfully.")

// Client authentication - exchange credentials for tokens
idpAccessToken, releaseToken, err := auth.ClientAuth(
Expand All @@ -144,16 +145,16 @@ func (o *OnboardingController) completeNonInteractiveAuth(clientID, clientSecret
return fmt.Errorf("failed to save release token: %w", err)
}

fmt.Println("Tokens saved successfully (non-interactive mode)")
logger.Logger.Info("Tokens saved successfully (non-interactive mode)")
return nil
}

// executeInteractiveMode performs manual onboarding with user authentication.
func (o *OnboardingController) executeInteractiveMode(ctx context.Context) error {
fmt.Println("Starting interactive (manual) onboarding...")
logger.Logger.Info("Starting interactive (manual) onboarding...")

// Step 1: Execute client-auth.sh for TTY-based authentication
fmt.Println("Executing client authentication script...")
logger.Logger.Info("Executing client authentication script...")
if err := interactive.ExecuteAuthScript(ctx); err != nil {
return fmt.Errorf("failed to run client auth script: %w", err)
}
Expand All @@ -175,6 +176,6 @@ func (o *OnboardingController) executeInteractiveMode(ctx context.Context) error
return fmt.Errorf("interactive onboarding failed after retries: %w", err)
}

fmt.Println("Device discovery completed (interactive mode)")
logger.Logger.Info("Device discovery completed (interactive mode)")
return nil
}
9 changes: 5 additions & 4 deletions device-discovery-agent/internal/mode/interactive/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"google.golang.org/grpc/credentials/oauth"

"device-discovery/internal/config"
"device-discovery/internal/logger"
)

// Client handles interactive (manual) device onboarding with JWT authentication.
Expand Down Expand Up @@ -89,7 +90,7 @@ func (c *Client) Onboard(ctx context.Context) error {
return fmt.Errorf("could not dial server %s: %v", target, err)
}
defer conn.Close()
fmt.Println("Dial Complete")
logger.Logger.Debug("Dial Complete")

cli := pb.NewInteractiveOnboardingServiceClient(conn)

Expand Down Expand Up @@ -142,10 +143,10 @@ func (c *Client) OnboardWithRetry(ctx context.Context) error {
}

// Log the error and retry info
fmt.Printf("There was an error in updating the edge-node details with the onboarding manager: %v\n", err)
logger.Logger.Warnf("There was an error in updating the edge-node details with the onboarding manager: %v", err)
if retries < maxRetries-1 {
fmt.Printf("Retrying update... attempt %d of %d\n", retries+2, maxRetries) // retries+2 to show next attempt
time.Sleep(retryDelay + time.Duration(rand.Intn(1000))*time.Millisecond) // Slight random jitter
logger.Logger.Infof("Retrying update... attempt %d of %d", retries+2, maxRetries) // retries+2 to show next attempt
time.Sleep(retryDelay + time.Duration(rand.Intn(1000))*time.Millisecond) // Slight random jitter
}
}

Expand Down
10 changes: 6 additions & 4 deletions device-discovery-agent/internal/mode/interactive/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"os"
"os/exec"
"syscall"

"device-discovery/internal/logger"
)

//go:embed client-auth.sh
Expand Down Expand Up @@ -65,16 +67,16 @@ func ExecuteAuthScript(ctx context.Context) error {
case err := <-done:
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
fmt.Printf("STDERR:\n%s\n", string(exitErr.Stderr))
logger.Logger.Errorf("STDERR:\n%s", string(exitErr.Stderr))
}
return fmt.Errorf("error executing command: %w", err)
}
fmt.Println("client-auth.sh executed successfully")
logger.Logger.Info("client-auth.sh executed successfully")
return nil
case <-ctx.Done():
fmt.Println("client-auth.sh timed out, killing process group...")
logger.Logger.Warn("client-auth.sh timed out, killing process group...")
if err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL); err != nil {
fmt.Printf("Failed to kill process group: %v\n", err)
logger.Logger.Warnf("Failed to kill process group: %v", err)
}
return fmt.Errorf("client-auth.sh timed out: %w", ctx.Err())
}
Expand Down
Loading