1// Package cli implements the CLI adapter for Gordon.
2// This package provides Cobra commands that delegate to the app layer.
3package cli
4
5import (
6 "context"
7
8 "gordon/internal/app"
9
10 "github.com/spf13/cobra"
11)
12
13var (
14 // Version information (set at build time)
15 Version = "dev"
16 Commit = "unknown"
17 BuildDate = "unknown"
18)
19
20// NewRootCmd creates the root command for Gordon CLI.
21func NewRootCmd() *cobra.Command {
22 rootCmd := &cobra.Command{
23 Use: "gordon",
24 Short: "Gordon - A lightweight container deployment platform",
25 Long: `Gordon is a self-contained container deployment platform that combines
26a Docker registry with automatic container deployment capabilities.
27
28It listens for image pushes and automatically deploys containers based on
29configuration rules, making it ideal for single-server deployments.`,
30 }
31
32 // Add subcommands
33 rootCmd.AddCommand(newStartCmd())
34 rootCmd.AddCommand(newReloadCmd())
35 rootCmd.AddCommand(newDeployCmd())
36 rootCmd.AddCommand(newLogsCmd())
37 rootCmd.AddCommand(newVersionCmd())
38 rootCmd.AddCommand(newAuthCmd())
39
40 return rootCmd
41}
42
43// newStartCmd creates the start command.
44func newStartCmd() *cobra.Command {
45 var configPath string
46
47 cmd := &cobra.Command{
48 Use: "start",
49 Short: "Start the Gordon server",
50 Long: `Start the Gordon server, including the registry and proxy components.`,
51 RunE: func(cmd *cobra.Command, args []string) error {
52 return app.Run(context.Background(), configPath)
53 },
54 }
55
56 // Add flags
57 cmd.Flags().StringVarP(&configPath, "config", "c", "", "Path to config file")
58
59 return cmd
60}
61
62// newReloadCmd creates the reload command.
63func newReloadCmd() *cobra.Command {
64 return &cobra.Command{
65 Use: "reload",
66 Short: "Start containers for configured routes",
67 Long: `Starts containers for routes defined in config.toml that don't have
68a running container. Running containers are never restarted to ensure 100% uptime.
69
70Use this command after editing config.toml to add new routes, or after pushing
71images to the registry when the route was not yet configured.`,
72 RunE: func(cmd *cobra.Command, args []string) error {
73 return runReload()
74 },
75 }
76}
77
78// newVersionCmd creates the version command.
79func newVersionCmd() *cobra.Command {
80 return &cobra.Command{
81 Use: "version",
82 Short: "Print version information",
83 Run: func(cmd *cobra.Command, args []string) {
84 cmd.Printf("Gordon %s\n", Version)
85 cmd.Printf("Commit: %s\n", Commit)
86 cmd.Printf("Build Date: %s\n", BuildDate)
87 },
88 }
89}
90
91// runReload sends SIGUSR1 to the running Gordon process.
92func runReload() error {
93 return app.SendReloadSignal()
94}
95
96// newLogsCmd creates the logs command.
97func newLogsCmd() *cobra.Command {
98 var follow bool
99 var lines int
100 var configPath string
101
102 cmd := &cobra.Command{
103 Use: "logs",
104 Short: "Show Gordon process logs",
105 Long: `Shows logs from the Gordon process. By default reads from the log file
106configured in config.toml. If file logging is not enabled, falls back to
107journalctl (if running as a systemd service).`,
108 RunE: func(cmd *cobra.Command, args []string) error {
109 return app.ShowLogs(configPath, follow, lines)
110 },
111 }
112
113 cmd.Flags().StringVarP(&configPath, "config", "c", "", "Path to config file")
114 cmd.Flags().BoolVarP(&follow, "follow", "f", false, "Follow log output")
115 cmd.Flags().IntVarP(&lines, "lines", "n", 50, "Number of lines to show")
116
117 return cmd
118}
119
120// SetVersionInfo sets the version information for the CLI.
121func SetVersionInfo(version, commit, date string) {
122 Version = version
123 Commit = commit
124 BuildDate = date
125}