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