diff options
author | Marc Mettke | 2017-02-03 12:02:06 +0100 |
---|---|---|
committer | Marc Mettke | 2017-02-03 12:12:31 +0100 |
commit | bd45f984bc291047104f4e92013ceec067dc70d5 (patch) | |
tree | 2e7edd24cfb94b4fa9e2b01e7f705e1b2b1b3eb3 | |
download | aur-bd45f984bc291047104f4e92013ceec067dc70d5.tar.gz |
[gitlab-runner-custom-executors] 1.10.4-1
-rw-r--r-- | .SRCINFO | 45 | ||||
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | PKGBUILD | 81 | ||||
-rw-r--r-- | config.toml | 1 | ||||
-rw-r--r-- | gitlab-runner.install | 8 | ||||
-rw-r--r-- | gitlab-runner.service | 17 | ||||
-rw-r--r-- | gitlab-runner.sysusers | 1 | ||||
-rw-r--r-- | gitlab-runner.tmpfiles | 1 | ||||
-rw-r--r-- | lxc_executor.patch | 499 |
9 files changed, 664 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..31a97681ff69 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,45 @@ +pkgbase = gitlab-runner-custom-executors + pkgdesc = The official GitLab CI runner written in Go with a LXC Executor + pkgver = 1.10.4 + pkgrel = 1 + url = https://gitlab.com/gitlab-org/gitlab-ci-multi-runner + install = gitlab-runner.install + arch = i686 + arch = x86_64 + license = GPL3 + makedepends = git + makedepends = go + makedepends = git + makedepends = go-bindata + makedepends = mercurial + depends = ca-certificates + depends = curl + depends = git + depends = glibc + depends = tar + provides = gitlab-runner=1.10.4-1 + conflicts = gitlab-runner + noextract = prebuilt-x86_64.tar.xz + noextract = prebuilt-arm.tar.xz + backup = etc/gitlab-runner/config.toml + source = git+https://gitlab.com/gitlab-org/gitlab-ci-multi-runner.git#tag=v1.10.4 + source = https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-x86_64.tar.xz + source = https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-arm.tar.xz + source = gitlab-runner.install + source = gitlab-runner.service + source = gitlab-runner.sysusers + source = gitlab-runner.tmpfiles + source = config.toml + source = lxc_executor.patch + sha512sums = SKIP + sha512sums = SKIP + sha512sums = SKIP + sha512sums = d5888f378c5b12b84e4238b191ef56a97a81c9073d27dcb47065998f0a1f6caf9f13314ae908e72a06f4d29d1bd1f4f72338c97268391e2c98706216c8281f3e + sha512sums = ed24841242a56a3b10dd80cd23e0c980f6bbe5fd0ebd4c6b46529947e4920cc9c03e4f4b239da8a798c801a6cdd757415113f97e45c1032f2c519fdaec4d3ae0 + sha512sums = 8aa7f08702e99053c696fcc2aaba83beb9e9cd6f31973d82862db9350ac46df3a095377625d31fe909677525290d2de922d7a97930ed235774cb8f0da8944d40 + sha512sums = 6751d9fa0b27172d1b419c4138f5ac15cbc7c9147653a7258cf1470216142c637210bb60608c7ed0974e0e4057e5ddeae32225df1bb36e7dd1f20fec71e33cc3 + sha512sums = f39c23fc06636f31c3fadb9a630c54527e8255098f18d275772cb30875d0a7463717101704070d432f2b69ab71f076a9538172a439bc307722dad2c7e260f752 + sha512sums = f88b8e6a8afb4f11bf61cfb6f680f611946658a8ea9c31588fb0b4be505bc72ac1af30ce819a2e74631d47919d684f121a625c091b3e6e891df5c434ae04acff + +pkgname = gitlab-runner-custom-executors + diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..a9eb70d24404 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +* +!config.toml +!.git +!.gitignore +!gitlab-runner.install +!gitlab-runner.service +!gitlab-runner.sysusers +!gitlab-runner.tmpfiles +!lxc_executor.patch +!PKGBUILD +!.SRCINFO diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..a39608939d94 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,81 @@ +# Maintainer: Sven-Hendrik Haase <sh@lutzhaase.com> +# Contributor: Lubomir 'Kuci' Kucera <kuci24-at-gmail-dot-com> +# Custom Executor Maintainer: Marc Mettke <marc@itmettke.de> + +pkgname=gitlab-runner-custom-executors +pkgver=1.10.4 +pkgrel=1 +pkgdesc="The official GitLab CI runner written in Go with a LXC Executor" +arch=('i686' 'x86_64') +url='https://gitlab.com/gitlab-org/gitlab-ci-multi-runner' +license=('GPL3') +depends=('ca-certificates' 'curl' 'git' 'glibc' 'tar') +makedepends=('git' 'go' 'git' 'go-bindata' 'mercurial') +install='gitlab-runner.install' +backup=('etc/gitlab-runner/config.toml') +noextract=('prebuilt-x86_64.tar.xz' + 'prebuilt-arm.tar.xz') +provides=("${pkgname/-custom-executors}=${pkgver}-${pkgrel}") +conflicts=("${pkgname/-custom-executors}") + +# Note: This should be built using git because the runner gets its version information from there and I +# haven't found the place to patch that yet. +source=("git+https://gitlab.com/gitlab-org/gitlab-ci-multi-runner.git#tag=v${pkgver}" + "https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-x86_64.tar.xz" + "https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/master/docker/prebuilt-arm.tar.xz" + "gitlab-runner.install" + "gitlab-runner.service" + "gitlab-runner.sysusers" + "gitlab-runner.tmpfiles" + "config.toml" + "lxc_executor.patch") +sha512sums=('SKIP' + 'SKIP' + 'SKIP' + 'd5888f378c5b12b84e4238b191ef56a97a81c9073d27dcb47065998f0a1f6caf9f13314ae908e72a06f4d29d1bd1f4f72338c97268391e2c98706216c8281f3e' + 'ed24841242a56a3b10dd80cd23e0c980f6bbe5fd0ebd4c6b46529947e4920cc9c03e4f4b239da8a798c801a6cdd757415113f97e45c1032f2c519fdaec4d3ae0' + '8aa7f08702e99053c696fcc2aaba83beb9e9cd6f31973d82862db9350ac46df3a095377625d31fe909677525290d2de922d7a97930ed235774cb8f0da8944d40' + '6751d9fa0b27172d1b419c4138f5ac15cbc7c9147653a7258cf1470216142c637210bb60608c7ed0974e0e4057e5ddeae32225df1bb36e7dd1f20fec71e33cc3' + 'f39c23fc06636f31c3fadb9a630c54527e8255098f18d275772cb30875d0a7463717101704070d432f2b69ab71f076a9538172a439bc307722dad2c7e260f752' + 'f88b8e6a8afb4f11bf61cfb6f680f611946658a8ea9c31588fb0b4be505bc72ac1af30ce819a2e74631d47919d684f121a625c091b3e6e891df5c434ae04acff') + +prepare() { + mkdir -p "${srcdir}/src/gitlab.com/gitlab-org/" + ln -sf "${srcdir}/gitlab-ci-multi-runner" "${srcdir}/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner" + cd "${srcdir}/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner" + + msg "Patch add lxc Executor" + patch -Np1 -i "${srcdir}/lxc_executor.patch" + + export GOPATH="${srcdir}" + make deps + + ln -sf "${srcdir}/prebuilt-x86_64.tar.xz" prebuilt-x86_64.tar.xz + ln -sf "${srcdir}/prebuilt-x86_64.tar.xz" prebuilt-arm.tar.xz +} + +build() { + cd "${srcdir}/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner" + + GOPATH="${srcdir}" go-bindata \ + -pkg docker \ + -nocompress \ + -nomemcopy \ + -prefix out/docker/ \ + -o executors/docker/bindata.go \ + prebuilt-x86_64.tar.xz \ + prebuilt-arm.tar.xz + + GOPATH="${srcdir}" go build +} + +package() { + cd "${srcdir}/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner" + + install -Dm644 "${srcdir}/config.toml" "${pkgdir}/etc/gitlab-runner/config.toml" + install -Dm644 "${srcdir}/gitlab-runner.service" "${pkgdir}/usr/lib/systemd/system/gitlab-runner.service" + install -Dm644 "${srcdir}/gitlab-runner.sysusers" "${pkgdir}/usr/lib/sysusers.d/gitlab-runner.conf" + install -Dm644 "${srcdir}/gitlab-runner.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/gitlab-runner.conf" + install -Dm755 "gitlab-ci-multi-runner" "${pkgdir}/usr/bin/gitlab-ci-multi-runner" + ln -s /usr/bin/gitlab-ci-multi-runner "${pkgdir}/usr/bin/gitlab-runner" +} diff --git a/config.toml b/config.toml new file mode 100644 index 000000000000..97e906ccde9d --- /dev/null +++ b/config.toml @@ -0,0 +1 @@ +concurrent = 4 diff --git a/gitlab-runner.install b/gitlab-runner.install new file mode 100644 index 000000000000..28676f89116a --- /dev/null +++ b/gitlab-runner.install @@ -0,0 +1,8 @@ +post_install() { + systemd-sysusers gitlab-runner.conf + systemd-tmpfiles --create gitlab-runner.conf + echo "Register the runner as root using" + echo "# gitlab-ci-multi-runner register" + echo "Configure the runner in /etc/gitlab-runner/config.toml" + echo "Use gitlab-runner.service to control the runner" +} diff --git a/gitlab-runner.service b/gitlab-runner.service new file mode 100644 index 000000000000..77ea3c78cdef --- /dev/null +++ b/gitlab-runner.service @@ -0,0 +1,17 @@ +[Unit] +Description=GitLab Runner +After=syslog.target network.target +ConditionFileIsExecutable=/usr/bin/gitlab-ci-multi-runner + +[Service] +StartLimitInterval=5 +StartLimitBurst=10 +ExecStart=/usr/bin/gitlab-ci-multi-runner "run" "--working-directory" "/var/lib/gitlab-runner" "--config" "/etc/gitlab-runner/config.toml" "--service" "gitlab-runner" "--user" "gitlab-runner" +Restart=always +RestartSec=120 +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=gitlab-runner + +[Install] +WantedBy=multi-user.target diff --git a/gitlab-runner.sysusers b/gitlab-runner.sysusers new file mode 100644 index 000000000000..5ceb7a64df7c --- /dev/null +++ b/gitlab-runner.sysusers @@ -0,0 +1 @@ +u gitlab-runner 107 "GitLab Runner" /var/lib/gitlab-runner diff --git a/gitlab-runner.tmpfiles b/gitlab-runner.tmpfiles new file mode 100644 index 000000000000..73a9916a6277 --- /dev/null +++ b/gitlab-runner.tmpfiles @@ -0,0 +1 @@ +d /var/lib/gitlab-runner 0700 gitlab-runner gitlab-runner - diff --git a/lxc_executor.patch b/lxc_executor.patch new file mode 100644 index 000000000000..9f4727e0d88e --- /dev/null +++ b/lxc_executor.patch @@ -0,0 +1,499 @@ +From c9008c8525a3daacd8d21d129e98e103134615bb Mon Sep 17 00:00:00 2001 +From: Marc Mettke <marc@itmettke.de> +Date: Sun, 8 Jan 2017 20:50:32 +0100 +Subject: [PATCH] Implemented LXC as Executor + +* Container defined by "container-name" +* Detects whether a Container is started or not +* Container is started if currently not running +* SubContainers can be created with OverlayFS using "slave-name" +* Multiple SubContainers can be used by appending a "randomid" +* Added Exec Command +* Added Register Command +--- + commands/exec.go | 1 + + commands/register.go | 26 ++++++++++++++++++++++++++ + common/config.go | 7 +++++++ + executors/lxc/executor_lxc.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + executors/lxc/executor_lxc_test.go | 1 + + helpers/lxc/lxc.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + helpers/lxc/lxc_command.go | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + main.go | 1 + + 8 files changed, 380 insertions(+), 0 deletions(-) + create mode 100644 executors/lxc/executor_lxc.go + create mode 100644 executors/lxc/executor_lxc_test.go + create mode 100644 helpers/lxc/lxc.go + create mode 100644 helpers/lxc/lxc_command.go + +diff --git a/commands/exec.go b/commands/exec.go +index 5ae5491..2228d79 100644 +--- a/commands/exec.go ++++ b/commands/exec.go +@@ -16,6 +16,7 @@ import ( + + // Force to load all executors, executes init() on them + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/docker" ++ _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/lxc" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/parallels" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/shell" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/ssh" +diff --git a/commands/register.go b/commands/register.go +index ac1539e..a3eaec2 100644 +--- a/commands/register.go ++++ b/commands/register.go +@@ -107,6 +107,19 @@ func (s *RegisterCommand) askDocker() { + s.Docker.Volumes = append(s.Docker.Volumes, "/cache") + } + ++func (s *RegisterCommand) askLxc() { ++ s.LXC.ContainerName = s.ask("lxc-container-name", "Please enter the Name of the Container (e.g. my-container)") ++ s.LXC.SlaveName = s.ask("lxc-slave-name", "Please enter a Name for a Slave Container to be created by the runner if you don't want to persist changes in the container (e.g. my-slave-container)") ++ if s.LXC.SlaveName != "" { ++ var err error ++ answer := s.ask("lxc-container-name", "Please enter true if you want to use Random Ids for your Slave Container to use multiple at once (e.g. true)") ++ s.LXC.SlaveRandomIdentifier, err = strconv.ParseBool(answer) ++ if err != nil { ++ s.LXC.SlaveRandomIdentifier = false ++ } ++ } ++} ++ + func (s *RegisterCommand) askParallels() { + s.Parallels.BaseName = s.ask("parallels-vm", "Please enter the Parallels VM (e.g. my-vm):") + } +@@ -217,6 +230,18 @@ func (s *RegisterCommand) askExecutorOptions() { + s.askVirtualBox() + s.askSSHLogin() + } ++ additionalExecutors(s) ++} ++ ++func additionalExecutors(s *RegisterCommand) { ++ lxc := s.LXC ++ s.LXC = nil ++ ++ switch s.Executor { ++ case "lxc": ++ s.LXC = lxc ++ s.askLxc() ++ } + } + + func (s *RegisterCommand) Execute(context *cli.Context) { +@@ -279,6 +304,7 @@ func init() { + Machine: &common.DockerMachine{}, + Docker: &common.DockerConfig{}, + SSH: &ssh.Config{}, ++ LXC: &common.LxcConfig{}, + Parallels: &common.ParallelsConfig{}, + VirtualBox: &common.VirtualBoxConfig{}, + }, +diff --git a/common/config.go b/common/config.go +index 463a4bc..290b634 100644 +--- a/common/config.go ++++ b/common/config.go +@@ -87,6 +87,12 @@ type DockerMachine struct { + offPeakTimePeriods *timeperiod.TimePeriod + } + ++type LxcConfig struct { ++ ContainerName string `toml:"container-name,omitempty" json:"container-name" long:"container-name" env:"LXC_CONTAINER_NAME" description:"The Name of the Container to use"` ++ SlaveName string `toml:"slave-name,omitempty" json:"slave-name" long:"slave-name" env:"LXC_SLAVE_NAME" description:"The Name of the Slave to create from the Container (deleted after each build)"` ++ SlaveRandomIdentifier bool `toml:"slave-random-id,omitempty" json:"slave-random-id" long:"slave-random-identifier" env:"LXC_RANDOM_ID" description:"Adds a Random Id to the Slave at creation to allow a Runner to use multiple Machines at once"` ++} ++ + type ParallelsConfig struct { + BaseName string `toml:"base_name" json:"base_name" long:"base-name" env:"PARALLELS_BASE_NAME" description:"VM name to be used"` + TemplateName string `toml:"template_name,omitempty" json:"template_name" long:"template-name" env:"PARALLELS_TEMPLATE_NAME" description:"VM template to be created"` +@@ -172,6 +178,7 @@ type RunnerSettings struct { + Cache *CacheConfig `toml:"cache,omitempty" json:"cache" group:"cache configuration" namespace:"cache"` + Machine *DockerMachine `toml:"machine,omitempty" json:"machine" group:"docker machine provider" namespace:"machine"` + Kubernetes *KubernetesConfig `toml:"kubernetes,omitempty" json:"kubernetes" group:"kubernetes executor" namespace:"kubernetes"` ++ LXC *LxcConfig `toml:"lxc,omitempty" json:"lxc" group:"lxc executor" namespace:"lxc"` + } + + type RunnerConfig struct { +diff --git a/executors/lxc/executor_lxc.go b/executors/lxc/executor_lxc.go +new file mode 100644 +index 0000000..f043efb +--- /dev/null ++++ b/executors/lxc/executor_lxc.go +@@ -0,0 +1,92 @@ ++package lxc ++ ++import ( ++ "errors" ++ ++ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" ++ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors" ++ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers/lxc" ++) ++ ++type executor struct { ++ executors.AbstractExecutor ++ command lxc.Client ++} ++ ++func (e *executor) Prepare(globalConfig *common.Config, config *common.RunnerConfig, build *common.Build) error { ++ err := e.AbstractExecutor.Prepare(globalConfig, config, build) ++ if err != nil { ++ return err ++ } ++ ++ e.Println("Using LXC executor...") ++ if e.BuildShell.PassFile { ++ return errors.New("LXC doesn't support shells that require script file") ++ } ++ ++ if e.Config.LXC == nil { ++ return errors.New("Missing LXC configuration") ++ } ++ ++ e.Debugln("Starting LXC command...") ++ ++ // Create LXC command ++ e.command = lxc.Client{ ++ Config: *e.Config.LXC, ++ Stdout: e.BuildTrace, ++ Stderr: e.BuildTrace, ++ } ++ ++ e.Debugln("Connecting to LXC server...") ++ err = e.command.Connect() ++ if err != nil { ++ return err ++ } ++ return nil ++} ++ ++func (e *executor) Run(cmd common.ExecutorCommand) error { ++ err := e.command.Run(lxc.Command{ ++ Environment: e.BuildShell.Environment, ++ Command: e.BuildShell.GetCommandWithArguments(), ++ Stdin: cmd.Script, ++ Abort: cmd.Abort, ++ }) ++ return err ++} ++ ++func (e *executor) Cleanup() { ++ e.command.Cleanup() ++ e.AbstractExecutor.Cleanup() ++} ++ ++func init() { ++ options := executors.ExecutorOptions{ ++ DefaultBuildsDir: "builds", ++ DefaultCacheDir: "/cache", ++ SharedBuildsDir: true, ++ Shell: common.ShellScriptInfo{ ++ Shell: "bash", ++ Type: common.LoginShell, ++ RunnerCommand: "gitlab-runner", ++ }, ++ ShowHostname: true, ++ } ++ ++ creator := func() common.Executor { ++ return &executor{ ++ AbstractExecutor: executors.AbstractExecutor{ ++ ExecutorOptions: options, ++ }, ++ } ++ } ++ ++ featuresUpdater := func(features *common.FeaturesInfo) { ++ features.Variables = true ++ } ++ ++ common.RegisterExecutor("lxc", executors.DefaultExecutorProvider{ ++ Creator: creator, ++ FeaturesUpdater: featuresUpdater, ++ }) ++} +diff --git a/executors/lxc/executor_lxc_test.go b/executors/lxc/executor_lxc_test.go +new file mode 100644 +index 0000000..99b5cd3 +--- /dev/null ++++ b/executors/lxc/executor_lxc_test.go +@@ -0,0 +1 @@ ++package lxc_test +diff --git a/helpers/lxc/lxc.go b/helpers/lxc/lxc.go +new file mode 100644 +index 0000000..1ca0f94 +--- /dev/null ++++ b/helpers/lxc/lxc.go +@@ -0,0 +1,81 @@ ++package lxc ++ ++import ( ++ "io" ++ "math/rand" ++ "os/exec" ++ "strconv" ++ "strings" ++ "time" ++) ++ ++const ( ++ RUNNING = 1 ++ STOPPED = 2 ++ UNDEFINED = 3 ++) ++ ++func initializeRandomSeed() { ++ rand.Seed(time.Now().UTC().UnixNano()) ++} ++ ++func getRandomNumber(min int64, max int64) int64 { ++ return min + rand.Int63n(max-min) ++} ++ ++func getRandomNameForContainer(name string) string { ++ return name + strconv.FormatInt(getRandomNumber(100000000, 999999999), 10) ++} ++ ++func checkContainerState(name string, stderr io.Writer) (int, error) { ++ cmd := exec.Command("lxc-info", "-sHn", name) ++ cmd.Stderr = stderr ++ out, err := cmd.Output() ++ if err != nil { ++ return -1, err ++ } ++ output := string(out) ++ if strings.Contains(output, "RUNNING") { ++ return RUNNING, nil ++ } else if strings.Contains(output, "STOPPED") { ++ return STOPPED, nil ++ } else { ++ return UNDEFINED, nil ++ } ++} ++ ++func startContainer(name string, stdout io.Writer, stderr io.Writer) error { ++ cmd := exec.Command("lxc-start", "-n", name) ++ cmd.Stdout = stdout ++ cmd.Stderr = stderr ++ return cmd.Run() ++} ++ ++func attachToContainer(name string, stdout io.Writer, stderr io.Writer, commands ...string) *exec.Cmd { ++ arguments := append([]string{"-n", name, "--"}, commands...) ++ cmd := exec.Command("lxc-attach", arguments...) ++ cmd.Stdout = stdout ++ cmd.Stderr = stderr ++ return cmd ++} ++ ++func copyContainerAsSnapshot(name string, newname string, stdout io.Writer, stderr io.Writer) error { ++ cmd := exec.Command("lxc-copy", "-sn", name, "-N", newname) ++ cmd.Stdout = stdout ++ cmd.Stderr = stderr ++ return cmd.Run() ++} ++ ++func stopContainer(name string, stdout io.Writer, stderr io.Writer) error { ++ cmd := exec.Command("lxc-stop", "-n", name) ++ cmd.Stdout = stdout ++ cmd.Stderr = stderr ++ return cmd.Run() ++} ++ ++func destroyContainer(name string, stdout io.Writer, stderr io.Writer) error { ++ cmd := exec.Command("lxc-destroy", "-n", name) ++ cmd.Stdout = stdout ++ cmd.Stderr = stderr ++ return cmd.Run() ++} +diff --git a/helpers/lxc/lxc_command.go b/helpers/lxc/lxc_command.go +new file mode 100644 +index 0000000..76fc1c2 +--- /dev/null ++++ b/helpers/lxc/lxc_command.go +@@ -0,0 +1,171 @@ ++package lxc ++ ++import ( ++ "bytes" ++ "errors" ++ "io" ++ "time" ++ ++ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" ++ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers" ++) ++ ++type Client struct { ++ Config common.LxcConfig ++ ++ Stdout io.Writer ++ Stderr io.Writer ++ ConnectRetries int ++ ++ connected bool ++ stop bool ++ destroy bool ++ container string ++} ++ ++type Command struct { ++ Environment []string ++ Command []string ++ Stdin string ++ Abort chan interface{} ++} ++ ++type ExitError struct { ++ Inner error ++} ++ ++func (e *ExitError) Error() string { ++ if e.Inner == nil { ++ return "error" ++ } ++ return e.Inner.Error() ++} ++ ++func handleSlaveCreation(c *Client) error { ++ if c.Config.SlaveName != "" { ++ c.stop = true ++ c.destroy = true ++ c.container = c.Config.SlaveName ++ if c.Config.SlaveRandomIdentifier == true { ++ c.container = getRandomNameForContainer(c.container) ++ } ++ return copyContainerAsSnapshot(c.Config.ContainerName, c.container, c.Stdout, c.Stderr) ++ } ++ return nil ++} ++ ++func handleStarted(c *Client) error { ++ if c.Config.SlaveName != "" { ++ return errors.New("The Container " + c.Config.ContainerName + " must not be used when defining OverlayFSName. Please stop it and try again") ++ } ++ return nil ++} ++ ++func handleStopped(c *Client) error { ++ err := handleSlaveCreation(c) ++ if err != nil { ++ return err ++ } ++ err = startContainer(c.container, c.Stdout, c.Stderr) ++ if err != nil { ++ return err ++ } ++ state, err := checkContainerState(c.container, c.Stderr) ++ if err != nil { ++ return err ++ } ++ if state != RUNNING { ++ return errors.New("Unable to start Container") ++ } ++ return nil ++} ++ ++func waitForNetwork() { ++ time.Sleep(10 * time.Second) ++} ++ ++func (c *Client) Connect() error { ++ c.stop = false ++ c.destroy = false ++ if c.Config.ContainerName == "" { ++ return errors.New("Host cannot be empty") ++ } ++ if c.Config.SlaveRandomIdentifier == true && c.Config.SlaveName == "" { ++ c.Stdout.Write([]byte("Warning: RandomIndentifier: true can only be used with OverlayFSName and will be ignored")) ++ } ++ initializeRandomSeed() ++ state, err := checkContainerState(c.Config.ContainerName, c.Stderr) ++ if err != nil { ++ return err ++ } ++ if state == STOPPED { ++ handleStopped(c) ++ } else if state == RUNNING { ++ handleStarted(c) ++ } else { ++ return errors.New("Could not determinate Container State") ++ } ++ waitForNetwork() ++ c.connected = true ++ return nil ++} ++ ++func (c *Client) Exec(command string) error { ++ if c.connected != true { ++ return errors.New("Container not accessible") ++ } ++ return attachToContainer(c.container, c.Stdout, c.Stderr, command).Run() ++} ++ ++func (c *Command) fullCommand() []string { ++ var arguments []string ++ // TODO: This method is compatible only with Bjourne compatible shells ++ for _, part := range c.Command { ++ arguments = append(arguments, part) ++ } ++ return arguments ++} ++ ++func (c *Client) Run(command Command) error { ++ if c.connected != true { ++ return errors.New("Container not accessible") ++ } ++ ++ var envVariables bytes.Buffer ++ for _, keyValue := range command.Environment { ++ envVariables.WriteString("export " + helpers.ShellEscape(keyValue) + "\n") ++ } ++ ++ cmd := attachToContainer(c.container, c.Stdout, c.Stderr, command.fullCommand()...) ++ cmd.Stdin = io.MultiReader( ++ &envVariables, ++ bytes.NewBufferString(command.Stdin), ++ ) ++ err := cmd.Start() ++ if err != nil { ++ return err ++ } ++ ++ waitCh := make(chan error) ++ go func() { ++ waitCh <- cmd.Wait() ++ }() ++ ++ select { ++ case <-command.Abort: ++ cmd.Process.Kill() ++ return <-waitCh ++ ++ case err := <-waitCh: ++ return err ++ } ++} ++ ++func (c *Client) Cleanup() { ++ if c.stop { ++ stopContainer(c.container, c.Stdout, c.Stderr) ++ } ++ if c.destroy { ++ destroyContainer(c.container, c.Stdout, c.Stderr) ++ } ++} +diff --git a/main.go b/main.go +index 6a15969..71ee0e9 100644 +--- a/main.go ++++ b/main.go +@@ -15,6 +15,7 @@ import ( + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/docker" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/docker/machine" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/kubernetes" ++ _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/lxc" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/parallels" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/shell" + _ "gitlab.com/gitlab-org/gitlab-ci-multi-runner/executors/ssh" +-- +libgit2 0.24.0 + |