github.com/secure-build/gitlab-runner@v12.5.0+incompatible/commands/service.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "os" 6 "runtime" 7 8 "github.com/ayufan/golang-kardianos-service" 9 "github.com/sirupsen/logrus" 10 "github.com/urfave/cli" 11 12 "gitlab.com/gitlab-org/gitlab-runner/common" 13 "gitlab.com/gitlab-org/gitlab-runner/helpers" 14 "gitlab.com/gitlab-org/gitlab-runner/helpers/service" 15 ) 16 17 const ( 18 defaultServiceName = "gitlab-runner" 19 defaultDescription = "GitLab Runner" 20 ) 21 22 type NullService struct { 23 } 24 25 func (n *NullService) Start(s service.Service) error { 26 return nil 27 } 28 29 func (n *NullService) Stop(s service.Service) error { 30 return nil 31 } 32 33 func runServiceInstall(s service.Service, c *cli.Context) error { 34 if user := c.String("user"); user == "" && os.Getuid() == 0 { 35 logrus.Fatal("Please specify user that will run gitlab-runner service") 36 } 37 38 if configFile := c.String("config"); configFile != "" { 39 // try to load existing config 40 config := common.NewConfig() 41 err := config.LoadConfig(configFile) 42 if err != nil { 43 return err 44 } 45 46 // save config for the first time 47 if !config.Loaded { 48 err = config.SaveConfig(configFile) 49 if err != nil { 50 return err 51 } 52 } 53 } 54 return service.Control(s, "install") 55 } 56 57 func runServiceStatus(displayName string, s service.Service) error { 58 err := s.Status() 59 if err == nil { 60 fmt.Println(displayName+":", "Service is running!") 61 } else { 62 fmt.Fprintln(os.Stderr, displayName+":", err) 63 os.Exit(1) 64 } 65 return nil 66 } 67 68 func getServiceArguments(c *cli.Context) (arguments []string) { 69 if wd := c.String("working-directory"); wd != "" { 70 arguments = append(arguments, "--working-directory", wd) 71 } 72 73 if config := c.String("config"); config != "" { 74 arguments = append(arguments, "--config", config) 75 } 76 77 if sn := c.String("service"); sn != "" { 78 arguments = append(arguments, "--service", sn) 79 } 80 81 syslog := !c.IsSet("syslog") || c.Bool("syslog") 82 if syslog { 83 arguments = append(arguments, "--syslog") 84 } 85 86 return 87 } 88 89 func createServiceConfig(c *cli.Context) (svcConfig *service.Config) { 90 svcConfig = &service.Config{ 91 Name: c.String("service"), 92 DisplayName: c.String("service"), 93 Description: defaultDescription, 94 Arguments: []string{"run"}, 95 } 96 svcConfig.Arguments = append(svcConfig.Arguments, getServiceArguments(c)...) 97 98 switch runtime.GOOS { 99 case "linux": 100 if os.Getuid() != 0 { 101 logrus.Fatal("Please run the commands as root") 102 } 103 if user := c.String("user"); user != "" { 104 svcConfig.Arguments = append(svcConfig.Arguments, "--user", user) 105 } 106 107 case "darwin": 108 svcConfig.Option = service.KeyValue{ 109 "KeepAlive": true, 110 "RunAtLoad": true, 111 "UserService": os.Getuid() != 0, 112 } 113 114 if user := c.String("user"); user != "" { 115 if os.Getuid() == 0 { 116 svcConfig.Arguments = append(svcConfig.Arguments, "--user", user) 117 } else { 118 logrus.Fatalln("The --user is not supported for non-root users") 119 } 120 } 121 122 case "windows": 123 svcConfig.Option = service.KeyValue{ 124 "Password": c.String("password"), 125 } 126 svcConfig.UserName = c.String("user") 127 } 128 return 129 } 130 131 func RunServiceControl(c *cli.Context) { 132 svcConfig := createServiceConfig(c) 133 134 s, err := service_helpers.New(&NullService{}, svcConfig) 135 if err != nil { 136 logrus.Fatal(err) 137 } 138 139 switch c.Command.Name { 140 case "install": 141 err = runServiceInstall(s, c) 142 case "status": 143 err = runServiceStatus(svcConfig.DisplayName, s) 144 default: 145 err = service.Control(s, c.Command.Name) 146 } 147 148 if err != nil { 149 logrus.Fatal(err) 150 } 151 } 152 153 func getFlags() []cli.Flag { 154 return []cli.Flag{ 155 cli.StringFlag{ 156 Name: "service, n", 157 Value: defaultServiceName, 158 Usage: "Specify service name to use", 159 }, 160 } 161 } 162 163 func getInstallFlags() []cli.Flag { 164 installFlags := getFlags() 165 installFlags = append(installFlags, cli.StringFlag{ 166 Name: "working-directory, d", 167 Value: helpers.GetCurrentWorkingDirectory(), 168 Usage: "Specify custom root directory where all data are stored", 169 }) 170 installFlags = append(installFlags, cli.StringFlag{ 171 Name: "config, c", 172 Value: getDefaultConfigFile(), 173 Usage: "Specify custom config file", 174 }) 175 installFlags = append(installFlags, cli.BoolFlag{ 176 Name: "syslog", 177 Usage: "Setup system logging integration", 178 }) 179 180 if runtime.GOOS == "windows" { 181 installFlags = append(installFlags, cli.StringFlag{ 182 Name: "user, u", 183 Value: "", 184 Usage: "Specify user-name to secure the runner", 185 }) 186 installFlags = append(installFlags, cli.StringFlag{ 187 Name: "password, p", 188 Value: "", 189 Usage: "Specify user password to install service (required)", 190 }) 191 } else if os.Getuid() == 0 { 192 installFlags = append(installFlags, cli.StringFlag{ 193 Name: "user, u", 194 Value: "", 195 Usage: "Specify user-name to secure the runner", 196 }) 197 } 198 199 return installFlags 200 } 201 202 func init() { 203 flags := getFlags() 204 installFlags := getInstallFlags() 205 206 common.RegisterCommand(cli.Command{ 207 Name: "install", 208 Usage: "install service", 209 Action: RunServiceControl, 210 Flags: installFlags, 211 }) 212 common.RegisterCommand(cli.Command{ 213 Name: "uninstall", 214 Usage: "uninstall service", 215 Action: RunServiceControl, 216 Flags: flags, 217 }) 218 common.RegisterCommand(cli.Command{ 219 Name: "start", 220 Usage: "start service", 221 Action: RunServiceControl, 222 Flags: flags, 223 }) 224 common.RegisterCommand(cli.Command{ 225 Name: "stop", 226 Usage: "stop service", 227 Action: RunServiceControl, 228 Flags: flags, 229 }) 230 common.RegisterCommand(cli.Command{ 231 Name: "restart", 232 Usage: "restart service", 233 Action: RunServiceControl, 234 Flags: flags, 235 }) 236 common.RegisterCommand(cli.Command{ 237 Name: "status", 238 Usage: "get status of a service", 239 Action: RunServiceControl, 240 Flags: flags, 241 }) 242 }