github.com/nilium/gitlab-runner@v12.5.0+incompatible/commands/exec.go (about) 1 package commands 2 3 import ( 4 "os" 5 "os/exec" 6 "strings" 7 8 "github.com/sirupsen/logrus" 9 "github.com/urfave/cli" 10 "gitlab.com/ayufan/golang-cli-helpers" 11 12 "gitlab.com/gitlab-org/gitlab-runner/common" 13 "gitlab.com/gitlab-org/gitlab-runner/helpers/gitlab_ci_yaml_parser" 14 // Force to load all executors, executes init() on them 15 _ "gitlab.com/gitlab-org/gitlab-runner/executors/custom" 16 _ "gitlab.com/gitlab-org/gitlab-runner/executors/docker" 17 _ "gitlab.com/gitlab-org/gitlab-runner/executors/parallels" 18 _ "gitlab.com/gitlab-org/gitlab-runner/executors/shell" 19 _ "gitlab.com/gitlab-org/gitlab-runner/executors/ssh" 20 _ "gitlab.com/gitlab-org/gitlab-runner/executors/virtualbox" 21 ) 22 23 type ExecCommand struct { 24 common.RunnerSettings 25 Job string 26 Timeout int `long:"timeout" description:"Job execution timeout (in seconds)"` 27 } 28 29 func (c *ExecCommand) runCommand(name string, arg ...string) (string, error) { 30 cmd := exec.Command(name, arg...) 31 cmd.Env = os.Environ() 32 cmd.Stderr = os.Stderr 33 result, err := cmd.Output() 34 return string(result), err 35 } 36 37 func (c *ExecCommand) createBuild(repoURL string, abortSignal chan os.Signal) (build *common.Build, err error) { 38 // Check if we have uncommitted changes 39 _, err = c.runCommand("git", "diff", "--quiet", "HEAD") 40 if err != nil { 41 logrus.Warningln("You most probably have uncommitted changes.") 42 logrus.Warningln("These changes will not be tested.") 43 } 44 45 // Parse Git settings 46 sha, err := c.runCommand("git", "rev-parse", "HEAD") 47 if err != nil { 48 return 49 } 50 51 beforeSha, err := c.runCommand("git", "rev-parse", "HEAD~1") 52 if err != nil { 53 beforeSha = "0000000000000000000000000000000000000000" 54 } 55 56 refName, err := c.runCommand("git", "rev-parse", "--abbrev-ref", "HEAD") 57 if err != nil { 58 return 59 } 60 61 jobResponse := common.JobResponse{ 62 ID: 1, 63 Token: "", 64 AllowGitFetch: false, 65 JobInfo: common.JobInfo{ 66 Name: "", 67 Stage: "", 68 ProjectID: 1, 69 ProjectName: "", 70 }, 71 GitInfo: common.GitInfo{ 72 RepoURL: repoURL, 73 Ref: strings.TrimSpace(refName), 74 Sha: strings.TrimSpace(sha), 75 BeforeSha: strings.TrimSpace(beforeSha), 76 }, 77 RunnerInfo: common.RunnerInfo{ 78 Timeout: c.getTimeout(), 79 }, 80 } 81 82 runner := &common.RunnerConfig{ 83 RunnerSettings: c.RunnerSettings, 84 } 85 86 build, err = common.NewBuild(jobResponse, runner, abortSignal, nil) 87 88 return 89 } 90 91 func (c *ExecCommand) getTimeout() int { 92 if c.Timeout > 0 { 93 return c.Timeout 94 } 95 96 return common.DefaultExecTimeout 97 } 98 99 func (c *ExecCommand) Execute(context *cli.Context) { 100 wd, err := os.Getwd() 101 if err != nil { 102 logrus.Fatalln(err) 103 } 104 105 switch len(context.Args()) { 106 case 1: 107 c.Job = context.Args().Get(0) 108 default: 109 cli.ShowSubcommandHelp(context) 110 os.Exit(1) 111 return 112 } 113 114 c.Executor = context.Command.Name 115 116 abortSignal := make(chan os.Signal) 117 doneSignal := make(chan int, 1) 118 119 go waitForInterrupts(nil, abortSignal, doneSignal, nil) 120 121 // Add self-volume to docker 122 if c.RunnerSettings.Docker == nil { 123 c.RunnerSettings.Docker = &common.DockerConfig{} 124 } 125 c.RunnerSettings.Docker.Volumes = append(c.RunnerSettings.Docker.Volumes, wd+":"+wd+":ro") 126 127 // Create build 128 build, err := c.createBuild(wd, abortSignal) 129 if err != nil { 130 logrus.Fatalln(err) 131 } 132 133 parser := gitlab_ci_yaml_parser.NewGitLabCiYamlParser(c.Job) 134 err = parser.ParseYaml(&build.JobResponse) 135 if err != nil { 136 logrus.Fatalln(err) 137 } 138 139 err = build.Run(&common.Config{}, &common.Trace{Writer: os.Stdout}) 140 if err != nil { 141 logrus.Fatalln(err) 142 } 143 } 144 145 func init() { 146 cmd := &ExecCommand{} 147 148 flags := clihelpers.GetFlagsFromStruct(cmd) 149 cliCmd := cli.Command{ 150 Name: "exec", 151 Usage: "execute a build locally", 152 } 153 154 for _, executor := range common.GetExecutors() { 155 subCmd := cli.Command{ 156 Name: executor, 157 Usage: "use " + executor + " executor", 158 Action: cmd.Execute, 159 Flags: flags, 160 } 161 cliCmd.Subcommands = append(cliCmd.Subcommands, subCmd) 162 } 163 164 common.RegisterCommand(cliCmd) 165 }