cmd: allow import/running ctrld as library

This commit is contained in:
Cuong Manh Le
2023-08-15 11:15:37 +00:00
committed by Cuong Manh Le
parent 4896563e3c
commit 829e93c079
34 changed files with 195 additions and 188 deletions

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"bytes" "bytes"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"os" "os"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"net" "net"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"context" "context"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"context" "context"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"bytes" "bytes"

View File

@@ -1,4 +1,4 @@
package main package cli
//lint:ignore U1000 use in os_linux.go //lint:ignore U1000 use in os_linux.go
type getDNS func(iface string) []string type getDNS func(iface string) []string

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"context" "context"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"context" "context"

161
cmd/cli/main.go Normal file
View File

@@ -0,0 +1,161 @@
package cli
import (
"io"
"os"
"path/filepath"
"sync/atomic"
"time"
"github.com/kardianos/service"
"github.com/rs/zerolog"
"github.com/Control-D-Inc/ctrld"
)
var (
configPath string
configBase64 string
daemon bool
listenAddress string
primaryUpstream string
secondaryUpstream string
domains []string
logPath string
homedir string
cacheSize int
cfg ctrld.Config
verbose int
silent bool
cdUID string
cdOrg string
cdDev bool
iface string
ifaceStartStop string
mainLog atomic.Pointer[zerolog.Logger]
consoleWriter zerolog.ConsoleWriter
)
func init() {
l := zerolog.New(io.Discard)
mainLog.Store(&l)
}
func Main() {
ctrld.InitConfig(v, "ctrld")
initCLI()
if err := rootCmd.Execute(); err != nil {
mainLog.Load().Error().Msg(err.Error())
os.Exit(1)
}
}
func normalizeLogFilePath(logFilePath string) string {
if logFilePath == "" || filepath.IsAbs(logFilePath) || service.Interactive() {
return logFilePath
}
if homedir != "" {
return filepath.Join(homedir, logFilePath)
}
dir, _ := userHomeDir()
if dir == "" {
return logFilePath
}
return filepath.Join(dir, logFilePath)
}
func initConsoleLogging() {
consoleWriter = zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
w.TimeFormat = time.StampMilli
})
multi := zerolog.MultiLevelWriter(consoleWriter)
l := mainLog.Load().Output(multi).With().Timestamp().Logger()
mainLog.Store(&l)
switch {
case silent:
zerolog.SetGlobalLevel(zerolog.NoLevel)
case verbose == 1:
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case verbose > 1:
zerolog.SetGlobalLevel(zerolog.DebugLevel)
default:
zerolog.SetGlobalLevel(zerolog.NoticeLevel)
}
}
// initLogging initializes global logging setup.
func initLogging() {
initLoggingWithBackup(true)
}
// initLoggingWithBackup initializes log setup base on current config.
// If doBackup is true, backup old log file with ".1" suffix.
//
// This is only used in runCmd for special handling in case of logging config
// change in cd mode. Without special reason, the caller should use initLogging
// wrapper instead of calling this function directly.
func initLoggingWithBackup(doBackup bool) {
writers := []io.Writer{io.Discard}
if logFilePath := normalizeLogFilePath(cfg.Service.LogPath); logFilePath != "" {
// Create parent directory if necessary.
if err := os.MkdirAll(filepath.Dir(logFilePath), 0750); err != nil {
mainLog.Load().Error().Msgf("failed to create log path: %v", err)
os.Exit(1)
}
// Default open log file in append mode.
flags := os.O_CREATE | os.O_RDWR | os.O_APPEND
if doBackup {
// Backup old log file with .1 suffix.
if err := os.Rename(logFilePath, logFilePath+".1"); err != nil && !os.IsNotExist(err) {
mainLog.Load().Error().Msgf("could not backup old log file: %v", err)
} else {
// Backup was created, set flags for truncating old log file.
flags = os.O_CREATE | os.O_RDWR
}
}
logFile, err := os.OpenFile(logFilePath, flags, os.FileMode(0o600))
if err != nil {
mainLog.Load().Error().Msgf("failed to create log file: %v", err)
os.Exit(1)
}
writers = append(writers, logFile)
}
writers = append(writers, consoleWriter)
multi := zerolog.MultiLevelWriter(writers...)
l := mainLog.Load().Output(multi).With().Timestamp().Logger()
mainLog.Store(&l)
// TODO: find a better way.
ctrld.ProxyLogger.Store(&l)
zerolog.SetGlobalLevel(zerolog.NoticeLevel)
logLevel := cfg.Service.LogLevel
switch {
case silent:
zerolog.SetGlobalLevel(zerolog.NoLevel)
return
case verbose == 1:
logLevel = "info"
case verbose > 1:
logLevel = "debug"
}
if logLevel == "" {
return
}
level, err := zerolog.ParseLevel(logLevel)
if err != nil {
mainLog.Load().Warn().Err(err).Msg("could not set log level")
return
}
zerolog.SetGlobalLevel(level)
}
func initCache() {
if !cfg.Service.CacheEnable {
return
}
if cfg.Service.CacheSize == 0 {
cfg.Service.CacheSize = 4096
}
}

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"os" "os"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"bufio" "bufio"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"strings" "strings"

View File

@@ -1,6 +1,6 @@
//go:build !darwin //go:build !darwin
package main package cli
import "net" import "net"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"

View File

@@ -1,5 +1,5 @@
//go:build !linux //go:build !linux
package main package cli
func (p *prog) watchLinkState() {} func (p *prog) watchLinkState() {}

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"context" "context"

View File

@@ -1,6 +1,6 @@
//go:build !linux //go:build !linux
package main package cli
func setupNetworkManager() error { func setupNetworkManager() error {
reloadNetworkManager() reloadNetworkManager()

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"net" "net"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"net" "net"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"bufio" "bufio"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"reflect" "reflect"

View File

@@ -1,6 +1,6 @@
//go:build !linux && !darwin && !freebsd //go:build !linux && !darwin && !freebsd
package main package cli
// TODO(cuonglm): implement. // TODO(cuonglm): implement.
func allocateIP(ip string) error { func allocateIP(ip string) error {

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"errors" "errors"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"errors" "errors"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"github.com/kardianos/service" "github.com/kardianos/service"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"os" "os"

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"github.com/kardianos/service" "github.com/kardianos/service"

View File

@@ -1,6 +1,6 @@
//go:build !linux && !freebsd && !darwin //go:build !linux && !freebsd && !darwin
package main package cli
import "github.com/kardianos/service" import "github.com/kardianos/service"

View File

@@ -1,4 +1,4 @@
package main package cli
type semaphore interface { type semaphore interface {
acquire() acquire()

View File

@@ -1,4 +1,4 @@
package main package cli
import ( import (
"bytes" "bytes"

View File

@@ -1,6 +1,6 @@
//go:build !windows //go:build !windows
package main package cli
import ( import (
"os" "os"

View File

@@ -1,4 +1,4 @@
package main package cli
import "golang.org/x/sys/windows" import "golang.org/x/sys/windows"

View File

@@ -1,161 +1,7 @@
package main package main
import ( import "github.com/Control-D-Inc/ctrld/cmd/cli"
"io"
"os"
"path/filepath"
"sync/atomic"
"time"
"github.com/kardianos/service"
"github.com/rs/zerolog"
"github.com/Control-D-Inc/ctrld"
)
var (
configPath string
configBase64 string
daemon bool
listenAddress string
primaryUpstream string
secondaryUpstream string
domains []string
logPath string
homedir string
cacheSize int
cfg ctrld.Config
verbose int
silent bool
cdUID string
cdOrg string
cdDev bool
iface string
ifaceStartStop string
mainLog atomic.Pointer[zerolog.Logger]
consoleWriter zerolog.ConsoleWriter
)
func init() {
l := zerolog.New(io.Discard)
mainLog.Store(&l)
}
func main() { func main() {
ctrld.InitConfig(v, "ctrld") cli.Main()
initCLI()
if err := rootCmd.Execute(); err != nil {
mainLog.Load().Error().Msg(err.Error())
os.Exit(1)
}
}
func normalizeLogFilePath(logFilePath string) string {
if logFilePath == "" || filepath.IsAbs(logFilePath) || service.Interactive() {
return logFilePath
}
if homedir != "" {
return filepath.Join(homedir, logFilePath)
}
dir, _ := userHomeDir()
if dir == "" {
return logFilePath
}
return filepath.Join(dir, logFilePath)
}
func initConsoleLogging() {
consoleWriter = zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
w.TimeFormat = time.StampMilli
})
multi := zerolog.MultiLevelWriter(consoleWriter)
l := mainLog.Load().Output(multi).With().Timestamp().Logger()
mainLog.Store(&l)
switch {
case silent:
zerolog.SetGlobalLevel(zerolog.NoLevel)
case verbose == 1:
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case verbose > 1:
zerolog.SetGlobalLevel(zerolog.DebugLevel)
default:
zerolog.SetGlobalLevel(zerolog.NoticeLevel)
}
}
// initLogging initializes global logging setup.
func initLogging() {
initLoggingWithBackup(true)
}
// initLoggingWithBackup initializes log setup base on current config.
// If doBackup is true, backup old log file with ".1" suffix.
//
// This is only used in runCmd for special handling in case of logging config
// change in cd mode. Without special reason, the caller should use initLogging
// wrapper instead of calling this function directly.
func initLoggingWithBackup(doBackup bool) {
writers := []io.Writer{io.Discard}
if logFilePath := normalizeLogFilePath(cfg.Service.LogPath); logFilePath != "" {
// Create parent directory if necessary.
if err := os.MkdirAll(filepath.Dir(logFilePath), 0750); err != nil {
mainLog.Load().Error().Msgf("failed to create log path: %v", err)
os.Exit(1)
}
// Default open log file in append mode.
flags := os.O_CREATE | os.O_RDWR | os.O_APPEND
if doBackup {
// Backup old log file with .1 suffix.
if err := os.Rename(logFilePath, logFilePath+".1"); err != nil && !os.IsNotExist(err) {
mainLog.Load().Error().Msgf("could not backup old log file: %v", err)
} else {
// Backup was created, set flags for truncating old log file.
flags = os.O_CREATE | os.O_RDWR
}
}
logFile, err := os.OpenFile(logFilePath, flags, os.FileMode(0o600))
if err != nil {
mainLog.Load().Error().Msgf("failed to create log file: %v", err)
os.Exit(1)
}
writers = append(writers, logFile)
}
writers = append(writers, consoleWriter)
multi := zerolog.MultiLevelWriter(writers...)
l := mainLog.Load().Output(multi).With().Timestamp().Logger()
mainLog.Store(&l)
// TODO: find a better way.
ctrld.ProxyLogger.Store(&l)
zerolog.SetGlobalLevel(zerolog.NoticeLevel)
logLevel := cfg.Service.LogLevel
switch {
case silent:
zerolog.SetGlobalLevel(zerolog.NoLevel)
return
case verbose == 1:
logLevel = "info"
case verbose > 1:
logLevel = "debug"
}
if logLevel == "" {
return
}
level, err := zerolog.ParseLevel(logLevel)
if err != nil {
mainLog.Load().Warn().Err(err).Msg("could not set log level")
return
}
zerolog.SetGlobalLevel(level)
}
func initCache() {
if !cfg.Service.CacheEnable {
return
}
if cfg.Service.CacheSize == 0 {
cfg.Service.CacheSize = 4096
}
} }