mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
cmd: allow import/running ctrld as library
This commit is contained in:
committed by
Cuong Manh Le
parent
4896563e3c
commit
829e93c079
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
161
cmd/cli/main.go
Normal file
161
cmd/cli/main.go
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build !darwin
|
//go:build !darwin
|
||||||
|
|
||||||
package main
|
package cli
|
||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//go:build !linux
|
//go:build !linux
|
||||||
|
|
||||||
package main
|
package cli
|
||||||
|
|
||||||
func (p *prog) watchLinkState() {}
|
func (p *prog) watchLinkState() {}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build !linux
|
//go:build !linux
|
||||||
|
|
||||||
package main
|
package cli
|
||||||
|
|
||||||
func setupNetworkManager() error {
|
func setupNetworkManager() error {
|
||||||
reloadNetworkManager()
|
reloadNetworkManager()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -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 {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
@@ -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"
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
type semaphore interface {
|
type semaphore interface {
|
||||||
acquire()
|
acquire()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build !windows
|
//go:build !windows
|
||||||
|
|
||||||
package main
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package main
|
package cli
|
||||||
|
|
||||||
import "golang.org/x/sys/windows"
|
import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user