mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Port all special logic from original alias commands: - startCmdAlias: custom Args validation, startOnly logic, iface handling - stopCmdAlias: iface flag handling and argument passing - restartCmdAlias: simple delegation to restartCmd.RunE - reloadCmdAlias: simple delegation to reloadCmd.RunE - statusCmdAlias: simple delegation to statusCmd.RunE - uninstallCmdAlias: iface flag handling and argument passing All aliases now have exact same behavior as original implementation including proper flag inheritance and argument handling.
311 lines
9.0 KiB
Go
311 lines
9.0 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
|
|
"github.com/kardianos/service"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// ServiceCommand handles service-related operations
|
|
type ServiceCommand struct {
|
|
serviceManager *ServiceManager
|
|
}
|
|
|
|
// NewServiceCommand creates a new service command handler
|
|
func NewServiceCommand() (*ServiceCommand, error) {
|
|
sm, err := NewServiceManager()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ServiceCommand{
|
|
serviceManager: sm,
|
|
}, nil
|
|
}
|
|
|
|
// createServiceConfig creates a properly initialized service configuration
|
|
func (sc *ServiceCommand) createServiceConfig() *service.Config {
|
|
return &service.Config{
|
|
Name: ctrldServiceName,
|
|
DisplayName: "Control-D Helper Service",
|
|
Description: "A highly configurable, multi-protocol DNS forwarding proxy",
|
|
Option: service.KeyValue{},
|
|
}
|
|
}
|
|
|
|
// Start implements the logic from cmdStart.Run
|
|
func (sc *ServiceCommand) Start(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdStart.Run
|
|
// This should include all the complex logic from initStartCmd
|
|
return nil
|
|
}
|
|
|
|
// Stop implements the logic from cmdStop.Run
|
|
func (sc *ServiceCommand) Stop(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdStop.Run
|
|
// This should include all the complex logic from initStopCmd
|
|
return nil
|
|
}
|
|
|
|
// Restart implements the logic from cmdRestart.Run
|
|
func (sc *ServiceCommand) Restart(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdRestart.Run
|
|
// This should include all the complex logic from initRestartCmd
|
|
return nil
|
|
}
|
|
|
|
// Reload implements the logic from cmdReload.Run
|
|
func (sc *ServiceCommand) Reload(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdReload.Run
|
|
// This should include all the complex logic from initReloadCmd
|
|
return nil
|
|
}
|
|
|
|
// Status implements the logic from cmdStatus.Run
|
|
func (sc *ServiceCommand) Status(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdStatus.Run
|
|
// This should include all the complex logic from initStatusCmd
|
|
return nil
|
|
}
|
|
|
|
// Uninstall implements the logic from cmdUninstall.Run
|
|
func (sc *ServiceCommand) Uninstall(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdUninstall.Run
|
|
// This should include all the complex logic from initUninstallCmd
|
|
return nil
|
|
}
|
|
|
|
// Interfaces implements the logic from cmdInterfaces.Run
|
|
func (sc *ServiceCommand) Interfaces(cmd *cobra.Command, args []string) error {
|
|
// TODO: Port the complete logic from cmdInterfaces.Run
|
|
// This should include all the complex logic from initInterfacesCmd
|
|
return nil
|
|
}
|
|
|
|
// InitServiceCmd creates the service command with proper logic and aliases
|
|
func InitServiceCmd() *cobra.Command {
|
|
// Create service command handlers
|
|
sc, err := NewServiceCommand()
|
|
if err != nil {
|
|
panic(fmt.Sprintf("failed to create service command: %v", err))
|
|
}
|
|
|
|
// Uninstall command
|
|
uninstallCmd := &cobra.Command{
|
|
Use: "uninstall",
|
|
Short: "Stop and uninstall the ctrld service",
|
|
Long: `Stop and uninstall the ctrld service.
|
|
|
|
NOTE: Uninstalling will set DNS to values provided by DHCP.`,
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Uninstall,
|
|
}
|
|
|
|
// Start command
|
|
startCmd := &cobra.Command{
|
|
Use: "start",
|
|
Short: "Start the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Start,
|
|
}
|
|
|
|
// Stop command
|
|
stopCmd := &cobra.Command{
|
|
Use: "stop",
|
|
Short: "Stop the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Stop,
|
|
}
|
|
|
|
// Restart command
|
|
restartCmd := &cobra.Command{
|
|
Use: "restart",
|
|
Short: "Restart the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Restart,
|
|
}
|
|
|
|
// Status command
|
|
statusCmd := &cobra.Command{
|
|
Use: "status",
|
|
Short: "Show status of the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
RunE: sc.Status,
|
|
}
|
|
if runtime.GOOS == "darwin" {
|
|
// On darwin, running status command without privileges may return wrong information.
|
|
statusCmd.PreRun = func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
}
|
|
}
|
|
|
|
// Reload command
|
|
reloadCmd := &cobra.Command{
|
|
Use: "reload",
|
|
Short: "Reload the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Reload,
|
|
}
|
|
|
|
// Interfaces command
|
|
interfacesCmd := &cobra.Command{
|
|
Use: "interfaces",
|
|
Short: "List network interfaces",
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
RunE: sc.Interfaces,
|
|
}
|
|
|
|
// Create aliases for root command
|
|
startCmdAlias := &cobra.Command{
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
Use: "start",
|
|
Short: "Quick start service and configure DNS on interface",
|
|
Long: `Quick start service and configure DNS on interface
|
|
|
|
NOTE: running "ctrld start" without any arguments will start already installed ctrld service.`,
|
|
Args: func(cmd *cobra.Command, args []string) error {
|
|
args = filterEmptyStrings(args)
|
|
if len(args) > 0 {
|
|
return fmt.Errorf("'ctrld start' doesn't accept positional arguments\n" +
|
|
"Use flags instead (e.g. --cd, --iface) or see 'ctrld start --help' for all options")
|
|
}
|
|
return nil
|
|
},
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if len(os.Args) == 2 {
|
|
startOnly = true
|
|
}
|
|
if !cmd.Flags().Changed("iface") {
|
|
os.Args = append(os.Args, "--iface="+ifaceStartStop)
|
|
}
|
|
iface = ifaceStartStop
|
|
return startCmd.RunE(cmd, args)
|
|
},
|
|
}
|
|
startCmdAlias.Flags().StringVarP(&ifaceStartStop, "iface", "", "auto", `Update DNS setting for iface, "auto" means the default interface gateway`)
|
|
startCmdAlias.Flags().AddFlagSet(startCmd.Flags())
|
|
rootCmd.AddCommand(startCmdAlias)
|
|
|
|
stopCmdAlias := &cobra.Command{
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
Use: "stop",
|
|
Short: "Quick stop service and remove DNS from interface",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if !cmd.Flags().Changed("iface") {
|
|
os.Args = append(os.Args, "--iface="+ifaceStartStop)
|
|
}
|
|
iface = ifaceStartStop
|
|
return stopCmd.RunE(cmd, args)
|
|
},
|
|
}
|
|
stopCmdAlias.Flags().StringVarP(&ifaceStartStop, "iface", "", "auto", `Reset DNS setting for iface, "auto" means the default interface gateway`)
|
|
stopCmdAlias.Flags().AddFlagSet(stopCmd.Flags())
|
|
rootCmd.AddCommand(stopCmdAlias)
|
|
|
|
// Create aliases for other service commands
|
|
restartCmdAlias := &cobra.Command{
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
Use: "restart",
|
|
Short: "Restart the ctrld service",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return restartCmd.RunE(cmd, args)
|
|
},
|
|
}
|
|
rootCmd.AddCommand(restartCmdAlias)
|
|
|
|
reloadCmdAlias := &cobra.Command{
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
Use: "reload",
|
|
Short: "Reload the ctrld service",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return reloadCmd.RunE(cmd, args)
|
|
},
|
|
}
|
|
rootCmd.AddCommand(reloadCmdAlias)
|
|
|
|
statusCmdAlias := &cobra.Command{
|
|
Use: "status",
|
|
Short: "Show status of the ctrld service",
|
|
Args: cobra.NoArgs,
|
|
RunE: statusCmd.RunE,
|
|
}
|
|
rootCmd.AddCommand(statusCmdAlias)
|
|
|
|
uninstallCmdAlias := &cobra.Command{
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
checkHasElevatedPrivilege()
|
|
},
|
|
Use: "uninstall",
|
|
Short: "Stop and uninstall the ctrld service",
|
|
Long: `Stop and uninstall the ctrld service.
|
|
|
|
NOTE: Uninstalling will set DNS to values provided by DHCP.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if !cmd.Flags().Changed("iface") {
|
|
os.Args = append(os.Args, "--iface="+ifaceStartStop)
|
|
}
|
|
iface = ifaceStartStop
|
|
return uninstallCmd.RunE(cmd, args)
|
|
},
|
|
}
|
|
uninstallCmdAlias.Flags().StringVarP(&ifaceStartStop, "iface", "", "auto", `Reset DNS setting for iface, "auto" means the default interface gateway`)
|
|
uninstallCmdAlias.Flags().AddFlagSet(uninstallCmd.Flags())
|
|
rootCmd.AddCommand(uninstallCmdAlias)
|
|
|
|
// Create service command
|
|
serviceCmd := &cobra.Command{
|
|
Use: "service",
|
|
Short: "Manage ctrld service",
|
|
Args: cobra.OnlyValidArgs,
|
|
}
|
|
serviceCmd.ValidArgs = make([]string, 7)
|
|
serviceCmd.ValidArgs[0] = startCmd.Use
|
|
serviceCmd.ValidArgs[1] = stopCmd.Use
|
|
serviceCmd.ValidArgs[2] = restartCmd.Use
|
|
serviceCmd.ValidArgs[3] = reloadCmd.Use
|
|
serviceCmd.ValidArgs[4] = statusCmd.Use
|
|
serviceCmd.ValidArgs[5] = uninstallCmd.Use
|
|
serviceCmd.ValidArgs[6] = interfacesCmd.Use
|
|
|
|
serviceCmd.AddCommand(uninstallCmd)
|
|
serviceCmd.AddCommand(startCmd)
|
|
serviceCmd.AddCommand(stopCmd)
|
|
serviceCmd.AddCommand(restartCmd)
|
|
serviceCmd.AddCommand(reloadCmd)
|
|
serviceCmd.AddCommand(statusCmd)
|
|
serviceCmd.AddCommand(interfacesCmd)
|
|
|
|
rootCmd.AddCommand(serviceCmd)
|
|
|
|
return serviceCmd
|
|
}
|