...
 
Commits (34)
......@@ -52,6 +52,14 @@ https://about.gitlab.com/2019/04/22/gitlab-11-10-released/#release-deprecations
- Change helper image to servercore !1290
- Add note about git-lfs !1294
v11.9.2 (2019-04-09)
- Fix git lfs not getting submodule objects !1298
v11.9.1 (2019-04-03)
- Make it again possible to disable Git LFS pull !1273
- Use delayed variable expansion for error check in cmd !1260
- Unexport common.RepoRemoteURL !1276
v11.9.0 (2019-03-22)
**Deprecations:**
......
......@@ -19,11 +19,11 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
## Contribute to GitLab runner
The following contents has to be considered as an extension over [gitlab-ce contributing guidelines](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md).
The following contents has to be considered as an extension over [gitlab-ce contributing guidelines](https://docs.gitlab.com/ce/development/contributing/index.html).
## Workflow lables
We have some additional labels plus those defined in [gitlab-ce workflow labels](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#workflow-labels)
We have some additional labels plus those defined in [gitlab-ce workflow labels](https://docs.gitlab.com/ce/development/contributing/issue_workflow.html)
- Additional subjects: ~cache, ~executors, ~"git operations"
- OS: ~"os::Linux" ~"os::MacOSX" ~"os:FreeBSD" ~"os::Windows"
......
......@@ -20,7 +20,7 @@ import (
api "k8s.io/api/core/v1"
"gitlab.com/gitlab-org/gitlab-runner/helpers"
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker"
docker_helpers "gitlab.com/gitlab-org/gitlab-runner/helpers/docker"
"gitlab.com/gitlab-org/gitlab-runner/helpers/ssh"
"gitlab.com/gitlab-org/gitlab-runner/helpers/timeperiod"
)
......@@ -32,8 +32,6 @@ const (
PullPolicyAlways = "always"
PullPolicyNever = "never"
PullPolicyIfNotPresent = "if-not-present"
defaultHelperImage = "gitlab/gitlab-runner-helper"
)
// Get returns one of the predefined values or returns an error if the value can't match the predefined
......@@ -506,19 +504,6 @@ func (c *DockerConfig) GetOomKillDisable() *bool {
return &c.OomKillDisable
}
func (c *KubernetesConfig) GetHelperImage() string {
if len(c.HelperImage) > 0 {
return c.HelperImage
}
rev := REVISION
if rev == "HEAD" {
rev = "latest"
}
return fmt.Sprintf("%s:x86_64-%s", defaultHelperImage, rev)
}
func (c *KubernetesConfig) GetPollAttempts() int {
if c.PollTimeout <= 0 {
c.PollTimeout = KubernetesPollTimeout
......
......@@ -111,7 +111,7 @@ This defines one runner entry.
| `tls-key-file` | File containing the private key to authenticate with the peer when using HTTPS |
| `limit` | Limit how many jobs can be handled concurrently by this token. `0` (default) simply means don't limit |
| `executor` | Select how a project should be built, see next section |
| `shell` | The name of shell to generate the script (default value is platform dependent) |
| `shell` | Name of shell to generate the script. Default value is [platform dependent](../shells/index.md#overview). |
| `builds_dir` | Directory where builds will be stored in context of selected executor (Locally, Docker, SSH) |
| `cache_dir` | Directory where build caches will be stored in context of selected executor (locally, Docker, SSH). If the `docker` executor is used, this directory needs to be included in its `volumes` parameter. |
| `environment` | Append or overwrite environment variables |
......
......@@ -34,11 +34,13 @@ The flags are defined in `./helpers/feature_flags/flags.go` file.
-->
<!-- feature_flags_list_start -->
| Feature flag | Default value | Deprecated | To be removed with | Description |
|--------------|---------------|------------|--------------------|-------------|
| `FF_K8S_USE_ENTRYPOINT_OVER_COMMAND` | `true` | ✓ | 12.0 | Enables [the fix](https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1010) for entrypoint configuration when `kubernetes` executor is used |
| `FF_DOCKER_HELPER_IMAGE_V2` | `false` | ✓ | 12.0 | Enable the helper image to use the new commands when [helper_image](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersdocker-section) is specified. This will start using the new API that will be used in 12.0 and stop showing the warning message in the build log |
| `FF_CMD_DISABLE_DELAYED_ERROR_LEVEL_EXPANSION` | `false` | ✗ | | Disables [EnableDelayedExpansion](https://ss64.com/nt/delayedexpansion.html) for error checking for when using [Window Batch](https://docs.gitlab.com/runner/shells/#windows-batch) shell |
| `FF_USE_LEGACY_GIT_CLEAN_STRATEGY` | `false` | ✓ | 12.0 | Enables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS` |
| `FF_USE_LEGACY_BUILDS_DIR_FOR_DOCKER` | `false` | ✓ | 13.0 | Enables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org` |
| `FF_USE_LEGACY_GIT_CLEAN_STRATEGY` | `false` | ✓ | 12.0 | Disables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS` |
| `FF_USE_LEGACY_BUILDS_DIR_FOR_DOCKER` | `false` | ✓ | 12.3 | Disables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org` |
<!-- feature_flags_list_end -->
......@@ -13,7 +13,7 @@ well as information how to set up Prometheus metrics:
- [Autoscaling using Docker machine](autoscale.md) Execute jobs on machines that are created on demand using Docker machine.
- [Autoscaling GitLab Runner on AWS](runner_autoscale_aws/index.md)
- [The init system of GitLab Runner](init.md) Learn how the Runner installs its init service files based on your operating system.
- [Supported shells](../shells/README.md) Learn what shell script generators are supported that allow to execute builds on different systems.
- [Supported shells](../shells/index.md) Learn what shell script generators are supported that allow to execute builds on different systems.
- [Security considerations](../security/index.md) Be aware of potential security implications when running your jobs with GitLab Runner.
- [Runner monitoring](../monitoring/README.md) Learn how to monitor the Runner's behavior.
- [Cleanup the Docker images automatically](https://gitlab.com/gitlab-org/gitlab-runner-docker-cleanup) A simple Docker application that automatically garbage collects the GitLab Runner caches and images when running low on disk space.
......
# The Docker executor
GitLab Runner can use Docker to run builds on user provided images. This is
GitLab Runner can use Docker to run jobs on user provided images. This is
possible with the use of **Docker** executor.
The **Docker** executor when used with GitLab CI, connects to [Docker Engine]
......@@ -22,18 +22,19 @@ compatible versions of Docker.
## Workflow
The Docker executor divides the build into multiple steps:
The Docker executor divides the job into multiple steps:
1. **Prepare**: Create and start the services.
1. **Pre-build**: Clone, restore cache and download artifacts from previous
stages. This is run on a special Docker Image.
1. **Build**: User build. This is run on the user-provided docker image.
1. **Post-build**: Create cache, upload artifacts to GitLab. This is run on
1. **Prepare**: Create and start the [services](https://docs.gitlab.com/ee/ci/yaml/#services).
1. **Pre-job**: Clone, restore [cache](https://docs.gitlab.com/ee/ci/yaml/#cache)
and download [artifacts](https://docs.gitlab.com/ee/ci/yaml/#artifacts) from previous
stages. This is run on a special Docker image.
1. **Job**: User build. This is run on the user-provided Docker image.
1. **Post-job**: Create cache, upload artifacts to GitLab. This is run on
a special Docker Image.
The special Docker Image is based on [Alpine Linux] and contains all the tools
required to run the prepare step the build: the Git binary and the Runner
binary for supporting caching and artifacts. You can find the definition of
The special Docker image is based on [Alpine Linux] and contains all the tools
required to run the prepare, pre-job, and post-job steps, like the Git and the
Runner binaries for supporting caching and artifacts. You can find the definition of
this special image [in the official Runner repository][special-build].
## The `image` keyword
......
......@@ -54,6 +54,19 @@ usermod -aG docker gitlab-runner
usermod -aG vboxusers gitlab-runner
```
## Selecting your shell
GitLab Runner [supports certain shells](../shells/index.md). To select a shell, specify it in your `config.toml` file. For example:
```toml
...
[[runners]]
name = "shell executor runner"
executor = "shell"
shell = "powershell"
...
```
## Security
Generally it's unsafe to run tests with shell executors. The jobs are run with
......
......@@ -106,7 +106,7 @@ See information on [configuring GitLab Runner](configuration/index.md), and:
- [Autoscaling using Docker machine](configuration/autoscale.md): Execute jobs on machines that are created on demand using Docker machine.
- [Autoscaling GitLab Runner on AWS](configuration/runner_autoscale_aws/index.md)
- [The init system of GitLab Runner](configuration/init.md): Learn how the Runner installs its init service files based on your operating system.
- [Supported shells](shells/README.md): Learn what shell script generators are supported that allow to execute builds on different systems.
- [Supported shells](shells/index.md): Learn what shell script generators are supported that allow to execute builds on different systems.
- [Security considerations](security/index.md): Be aware of potential security implications when running your jobs with GitLab Runner.
- [Runner monitoring](monitoring/README.md): Learn how to monitor the Runner's behavior.
- [Cleanup the Docker images automatically](https://gitlab.com/gitlab-org/gitlab-runner-docker-cleanup): A simple Docker application that automatically garbage collects the GitLab Runner caches and images when running low on disk space.
......
......@@ -25,6 +25,8 @@ The currently supported shells are:
| `cmd` | Windows Batch script. All commands are executed in Batch context (default for Windows) |
| `powershell` | Windows PowerShell script. All commands are executed in PowerShell context |
If you want to select a particular shell to use other than the default, you will need to [specify the shell](../executors/shell.md#selecting-your-shell) in your `config.toml` file.
## Sh/Bash shells
This is the default shell used on all Unix based systems. The bash script used
......@@ -69,13 +71,13 @@ set nl=^
echo Running on %COMPUTERNAME%...
call :prescript
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
call :buildscript
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
call :postscript
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
goto :EOF
:prescript
......@@ -101,25 +103,25 @@ SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_
echo Cloning repository...
rd /s /q "C:\GitLab-Runner\builds\0\project-1" 2>NUL 1>NUL
"git" "clone" "http://gitlab.example.com/group/project.git" "Z:\Gitlab\tests\test\builds\0\project-1"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
cd /D "C:\GitLab-Runner\builds\0\project-1"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
echo Checking out db45ad9a as master...
"git" "checkout" "db45ad9af9d7af5e61b829442fd893d96e31250c"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
IF EXIST "..\..\..\cache\project-1\pages\master\cache.tgz" (
echo Restoring cache...
"gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\master\cache.tgz"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
) ELSE (
IF EXIST "..\..\..\cache\project-1\pages\master\cache.tgz" (
echo Restoring cache...
"gitlab-runner-windows-amd64.exe" "extract" "--file" "..\..\..\cache\project-1\pages\master\cache.tgz"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
)
)
......@@ -146,7 +148,7 @@ md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
cd /D "C:\GitLab-Runner\builds\0\project-1"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
echo $ echo true
echo true
......@@ -173,11 +175,11 @@ md "C:\\GitLab-Runner\\builds\\0\\project-1.tmp" 2>NUL 1>NUL
echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
cd /D "C:\GitLab-Runner\builds\0\project-1"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
echo Archiving cache...
"gitlab-runner-windows-amd64.exe" "archive" "--file" "..\..\..\cache\project-1\pages\master\cache.tgz" "--path" "vendor"
IF %errorlevel% NEQ 0 exit /b %errorlevel%
IF !errorlevel! NEQ 0 exit /b !errorlevel!
goto :EOF
```
......
......@@ -278,49 +278,41 @@ func (e *executor) getPrebuiltImage() (*types.ImageInspect, error) {
return e.getDockerImage(imageNameFromConfig)
}
helperImageInfo, err := helperimage.GetInfo(e.info)
helperImageInfo, err := helperimage.Get(common.REVISION, helperimage.Config{
OSType: e.info.OSType,
Architecture: e.info.Architecture,
OperatingSystem: e.info.OperatingSystem,
})
if err != nil {
return nil, err
}
revision := "latest"
if common.REVISION != "HEAD" {
revision = common.REVISION
}
tag, err := helperImageInfo.Tag(revision)
if err != nil {
return nil, err
}
// Try to find already loaded prebuilt image
imageName := fmt.Sprintf("%s:%s", prebuiltImageName, tag)
e.Debugln("Looking for prebuilt image", imageName, "...")
image, _, err := e.client.ImageInspectWithRaw(e.Context, imageName)
e.Debugln(fmt.Sprintf("Looking for prebuilt image %s...", helperImageInfo))
image, _, err := e.client.ImageInspectWithRaw(e.Context, helperImageInfo.String())
if err == nil {
return &image, nil
}
// Try to load prebuilt image from local filesystem
loadedImage := e.getLocalDockerImage(helperImageInfo, tag)
loadedImage := e.getLocalDockerImage(helperImageInfo)
if loadedImage != nil {
return loadedImage, nil
}
// Fallback to getting image from DockerHub
e.Debugln("Loading image from registry:", imageName)
return e.getDockerImage(imageName)
e.Debugln(fmt.Sprintf("Loading image form registry: %s", helperImageInfo))
return e.getDockerImage(helperImageInfo.String())
}
func (e *executor) getLocalDockerImage(helperImageInfo helperimage.Info, tag string) *types.ImageInspect {
if !helperImageInfo.IsSupportingLocalImport() {
func (e *executor) getLocalDockerImage(helperImageInfo helperimage.Info) *types.ImageInspect {
if !helperImageInfo.IsSupportingLocalImport {
return nil
}
architecture := helperImageInfo.Architecture()
architecture := helperImageInfo.Architecture
for _, dockerPrebuiltImagesPath := range DockerPrebuiltImagesPaths {
dockerPrebuiltImageFilePath := filepath.Join(dockerPrebuiltImagesPath, "prebuilt-"+architecture+prebuiltImageExtension)
image, err := e.loadPrebuiltImage(dockerPrebuiltImageFilePath, prebuiltImageName, tag)
image, err := e.loadPrebuiltImage(dockerPrebuiltImageFilePath, prebuiltImageName, helperImageInfo.Tag)
if err != nil {
e.Debugln("Failed to load prebuilt image from:", dockerPrebuiltImageFilePath, "error:", err)
continue
......
......@@ -8,19 +8,20 @@ import (
"net/url"
"strings"
"gitlab.com/gitlab-org/gitlab-terminal"
"github.com/sirupsen/logrus"
terminal "gitlab.com/gitlab-org/gitlab-terminal"
"golang.org/x/net/context"
api "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
// Register all available authentication methods
_ "k8s.io/client-go/plugin/pkg/client/auth"
_ "k8s.io/client-go/plugin/pkg/client/auth" // Register all available authentication methods
restclient "k8s.io/client-go/rest"
"gitlab.com/gitlab-org/gitlab-runner/common"
"gitlab.com/gitlab-org/gitlab-runner/executors"
"gitlab.com/gitlab-org/gitlab-runner/helpers/dns"
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker/helperimage"
"gitlab.com/gitlab-org/gitlab-runner/helpers/featureflags"
terminalsession "gitlab.com/gitlab-org/gitlab-runner/session/terminal"
)
......@@ -61,6 +62,8 @@ type executor struct {
serviceRequests api.ResourceList
helperRequests api.ResourceList
pullPolicy common.KubernetesPullPolicy
helperImageInfo helperimage.Info
}
func (s *executor) setupResources() error {
......@@ -463,7 +466,6 @@ func (s *executor) setupBuildPod() error {
}
buildImage := s.Build.GetAllVariables().ExpandValue(s.options.Image.Name)
helperImage := common.AppVersion.Variables().ExpandValue(s.Config.Kubernetes.GetHelperImage())
pod, err := s.kubeClient.CoreV1().Pods(s.configurationOverwrites.namespace).Create(&api.Pod{
ObjectMeta: metav1.ObjectMeta{
......@@ -481,7 +483,7 @@ func (s *executor) setupBuildPod() error {
Containers: append([]api.Container{
// TODO use the build and helper template here
s.buildContainer("build", buildImage, s.options.Image, s.buildRequests, s.buildLimits, s.BuildShell.DockerCommand...),
s.buildContainer("helper", helperImage, common.Image{}, s.helperRequests, s.helperLimits, s.BuildShell.DockerCommand...),
s.buildContainer("helper", s.getHelperImage(), common.Image{}, s.helperRequests, s.helperLimits, s.BuildShell.DockerCommand...),
}, services...),
TerminationGracePeriodSeconds: &s.Config.Kubernetes.TerminationGracePeriodSeconds,
ImagePullSecrets: imagePullSecrets,
......@@ -497,6 +499,14 @@ func (s *executor) setupBuildPod() error {
return nil
}
func (s *executor) getHelperImage() string {
if len(s.Config.Kubernetes.HelperImage) > 0 {
return common.AppVersion.Variables().ExpandValue(s.Config.Kubernetes.HelperImage)
}
return s.helperImageInfo.String()
}
func (s *executor) runInContainer(ctx context.Context, name string, command []string, script string) <-chan error {
errc := make(chan error, 1)
go func() {
......@@ -670,10 +680,19 @@ func (s *executor) checkDefaults() error {
}
func createFn() common.Executor {
helperImageInfo, err := helperimage.Get(common.REVISION, helperimage.Config{
OSType: helperimage.OSTypeLinux,
Architecture: "amd64",
})
if err != nil {
logrus.WithError(err).Fatal("Failed to set up helper image for kubernetes executor")
}
return &executor{
AbstractExecutor: executors.AbstractExecutor{
ExecutorOptions: executorOptions,
},
helperImageInfo: helperImageInfo,
}
}
......
......@@ -30,6 +30,7 @@ import (
"gitlab.com/gitlab-org/gitlab-runner/executors"
"gitlab.com/gitlab-org/gitlab-runner/helpers"
dns_test "gitlab.com/gitlab-org/gitlab-runner/helpers/dns/test"
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker/helperimage"
"gitlab.com/gitlab-org/gitlab-runner/helpers/featureflags"
"gitlab.com/gitlab-org/gitlab-runner/session"
)
......@@ -1460,6 +1461,12 @@ func TestSetupBuildPod(t *testing.T) {
for testName, test := range tests {
t.Run(testName, func(t *testing.T) {
helperImageInfo, err := helperimage.Get(common.REVISION, helperimage.Config{
OSType: helperimage.OSTypeLinux,
Architecture: "amd64",
})
require.NoError(t, err)
vars := test.Variables
if vars == nil {
vars = []common.JobVariable{}
......@@ -1488,13 +1495,14 @@ func TestSetupBuildPod(t *testing.T) {
Runner: &test.RunnerConfig,
},
},
helperImageInfo: helperImageInfo,
}
if test.PrepareFn != nil {
test.PrepareFn(t, test, &ex)
}
err := ex.prepareOverwrites(make(common.JobVariables, 0))
err = ex.prepareOverwrites(make(common.JobVariables, 0))
assert.NoError(t, err, "error preparing overwrites")
err = ex.setupBuildPod()
......
package helperimage
import (
"github.com/docker/docker/api/types"
"fmt"
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker/errors"
)
......@@ -9,28 +9,54 @@ import (
const (
OSTypeLinux = "linux"
OSTypeWindows = "windows"
name = "gitlab/gitlab-runner-helper"
headRevision = "HEAD"
latestImageRevision = "latest"
)
// Info provides information about the helper image that can be used to
// pull from Docker Hub.
type Info interface {
Architecture() string
Tag(revision string) (string, error)
IsSupportingLocalImport() bool
type Info struct {
Architecture string
Name string
Tag string
IsSupportingLocalImport bool
}
func (i Info) String() string {
return fmt.Sprintf("%s:%s", i.Name, i.Tag)
}
type infoFactory func(info types.Info) Info
// Config specifies details about the consumer of this package that need to be
// taken in consideration when building Container.
type Config struct {
OSType string
Architecture string
OperatingSystem string
}
var supportedOsTypesFactories = map[string]infoFactory{
OSTypeWindows: newWindowsInfo,
OSTypeLinux: newLinuxInfo,
type creator interface {
Create(revision string, cfg Config) (Info, error)
}
func GetInfo(info types.Info) (Info, error) {
factory, ok := supportedOsTypesFactories[info.OSType]
var supportedOsTypesFactories = map[string]creator{
OSTypeWindows: new(windowsInfo),
OSTypeLinux: new(linuxInfo),
}
func Get(revision string, cfg Config) (Info, error) {
factory, ok := supportedOsTypesFactories[cfg.OSType]
if !ok {
return nil, errors.NewErrOSNotSupported(info.OSType)
return Info{}, errors.NewErrOSNotSupported(cfg.OSType)
}
return factory.Create(imageRevision(revision), cfg)
}
func imageRevision(revision string) string {
if revision != headRevision {
return revision
}
return factory(info), nil
return latestImageRevision
}
......@@ -3,29 +3,59 @@ package helperimage
import (
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker/errors"
)
func TestGetInfo(t *testing.T) {
testCases := []struct {
tests := []struct {
osType string
expectedHelperImageType interface{}
expectedError interface{}
}{
{osType: OSTypeLinux, expectedHelperImageType: &linuxInfo{}, expectedError: nil},
{osType: OSTypeWindows, expectedHelperImageType: &windowsInfo{}, expectedError: nil},
{osType: "unsupported", expectedHelperImageType: nil, expectedError: errors.NewErrOSNotSupported("unsupported")},
{osType: OSTypeLinux, expectedError: nil},
{osType: OSTypeWindows, expectedError: ErrUnsupportedOSVersion},
{osType: "unsupported", expectedError: errors.NewErrOSNotSupported("unsupported")},
}
for _, testCase := range testCases {
t.Run(testCase.osType, func(t *testing.T) {
i, err := GetInfo(types.Info{OSType: testCase.osType})
for _, test := range tests {
t.Run(test.osType, func(t *testing.T) {
_, err := Get(headRevision, Config{OSType: test.osType})
assert.IsType(t, testCase.expectedHelperImageType, i)
assert.Equal(t, testCase.expectedError, err)
assert.Equal(t, test.expectedError, err)
})
}
}
func TestContainerImage_String(t *testing.T) {
image := Info{
Name: "abc",
Tag: "1234",
}
assert.Equal(t, "abc:1234", image.String())
}
func Test_imageRevision(t *testing.T) {
tests := []struct {
revision string
expectedTag string
}{
{
revision: headRevision,
expectedTag: latestImageRevision,
},
{
revision: "1234",
expectedTag: "1234",
},
}
for _, test := range tests {
t.Run(test.revision, func(t *testing.T) {
assert.Equal(t, test.expectedTag, imageRevision(test.revision))
})
}
}
......@@ -3,24 +3,32 @@ package helperimage
import (
"fmt"
"runtime"
"github.com/docker/docker/api/types"
)
type linuxInfo struct {
dockerArch string
type linuxInfo struct{}
func (l *linuxInfo) Create(revision string, cfg Config) (Info, error) {
arch := l.architecture(cfg.Architecture)
return Info{
Architecture: arch,
Name: name,
Tag: fmt.Sprintf("%s-%s", arch, revision),
IsSupportingLocalImport: true,
}, nil
}
func (u *linuxInfo) Architecture() string {
switch u.dockerArch {
func (l *linuxInfo) architecture(arch string) string {
switch arch {
case "armv6l", "armv7l", "aarch64":
return "arm"
case "amd64":
return "x86_64"
}
if u.dockerArch != "" {
return u.dockerArch
if arch != "" {
return arch
}
switch runtime.GOARCH {
......@@ -30,17 +38,3 @@ func (u *linuxInfo) Architecture() string {
return runtime.GOARCH
}
}
func (u *linuxInfo) Tag(revision string) (string, error) {
return fmt.Sprintf("%s-%s", u.Architecture(), revision), nil
}
func (u *linuxInfo) IsSupportingLocalImport() bool {
return true
}
func newLinuxInfo(info types.Info) Info {
return &linuxInfo{
dockerArch: info.Architecture,
}
}
......@@ -5,45 +5,55 @@ import (
"runtime"
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
func Test_linuxInfo_Tag(t *testing.T) {
cases := []struct {
name string
dockerArch string
revision string
expectedTag string
func Test_linuxInfo_create(t *testing.T) {
tests := map[string]struct {
dockerArch string
revision string
expectedInfo Info
}{
{
name: "When dockerArch not specified we fallback to runtime arch",
dockerArch: "",
revision: "2923a43",
expectedTag: fmt.Sprintf("%s-2923a43", getExpectedArch()),
"When dockerArch not specified we fallback to runtime arch": {
dockerArch: "",
revision: "2923a43",
expectedInfo: Info{
Architecture: getExpectedArch(),
Name: name,
Tag: fmt.Sprintf("%s-2923a43", getExpectedArch()),
IsSupportingLocalImport: true,
},
},
{
name: "Docker runs on armv6l",
dockerArch: "armv6l",
revision: "2923a43",
expectedTag: "arm-2923a43",
"Docker runs on armv6l": {
dockerArch: "armv6l",
revision: "2923a43",
expectedInfo: Info{
Architecture: "arm",
Name: name,
Tag: "arm-2923a43",
IsSupportingLocalImport: true,
},
},
{
name: "Docker runs on amd64",
dockerArch: "amd64",
revision: "2923a43",
expectedTag: "x86_64-2923a43",
"Docker runs on amd64": {
dockerArch: "amd64",
revision: "2923a43",
expectedInfo: Info{
Architecture: "x86_64",
Name: name,
Tag: "x86_64-2923a43",
IsSupportingLocalImport: true,
},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
u := newLinuxInfo(types.Info{Architecture: c.dockerArch})
for name, test := range tests {
t.Run(name, func(t *testing.T) {
l := new(linuxInfo)
tag, err := u.Tag(c.revision)
image, err := l.Create(test.revision, Config{Architecture: test.dockerArch})
assert.NoError(t, err)
assert.Equal(t, c.expectedTag, tag)
assert.Equal(t, test.expectedInfo, image)
})
}
}
......@@ -58,8 +68,3 @@ func getExpectedArch() string {
return runtime.GOARCH
}
func Test_linuxInfo_IsSupportingLocalImport(t *testing.T) {
u := newLinuxInfo(types.Info{})
assert.True(t, u.IsSupportingLocalImport())
}
......@@ -4,8 +4,6 @@ import (
"errors"
"fmt"
"strings"
"github.com/docker/docker/api/types"
)
const (
......@@ -25,39 +23,29 @@ var supportedOSVersions = map[string]string{
var ErrUnsupportedOSVersion = errors.New("could not determine windows version")
type windowsInfo struct {
operatingSystem string
}
type windowsInfo struct{}
func (*windowsInfo) Architecture() string {
return windowsSupportedArchitecture
}
func (u *windowsInfo) Tag(revision string) (string, error) {
osVersion, err := u.osVersion()
func (w *windowsInfo) Create(revision string, cfg Config) (Info, error) {
osVersion, err := w.osVersion(cfg.OperatingSystem)
if err != nil {
return "", err
return Info{}, err
}
return fmt.Sprintf("%s-%s-%s", u.Architecture(), revision, osVersion), nil
return Info{
Architecture: windowsSupportedArchitecture,
Name: name,
Tag: fmt.Sprintf("%s-%s-%s", windowsSupportedArchitecture, revision, osVersion),
IsSupportingLocalImport: false,
}, nil
}
func (u *windowsInfo) osVersion() (string, error) {
for operatingSystem, osVersion := range supportedOSVersions {
if strings.Contains(u.operatingSystem, fmt.Sprintf(" %s ", operatingSystem)) {
return osVersion, nil
func (w *windowsInfo) osVersion(operatingSystem string) (string, error) {
for osVersion, baseImage := range supportedOSVersions {
if strings.Contains(operatingSystem, fmt.Sprintf(" %s ", osVersion)) {
return baseImage, nil
}
}
return "", ErrUnsupportedOSVersion
}
func (u *windowsInfo) IsSupportingLocalImport() bool {
return false
}
func newWindowsInfo(info types.Info) Info {
return &windowsInfo{
operatingSystem: info.OperatingSystem,
}
}
......@@ -4,31 +4,45 @@ import (
"fmt"
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
func Test_windowsInfo_Tag(t *testing.T) {
func Test_windowsInfo_create(t *testing.T) {
revision := "4011f186"
cases := []struct {
tests := []struct {
operatingSystem string
expectedVersion string
expectedInfo Info
expectedErr error
}{
{
operatingSystem: "Windows Server 2019 Datacenter Evaluation Version 1809 (OS Build 17763.316)",
expectedVersion: fmt.Sprintf("%s-%s-%s", "x86_64", revision, baseImage1809),
expectedErr: nil,
expectedInfo: Info{
Architecture: windowsSupportedArchitecture,
Name: name,
Tag: fmt.Sprintf("%s-%s-%s", windowsSupportedArchitecture, revision, baseImage1809),
IsSupportingLocalImport: false,
},
expectedErr: nil,
},
{
operatingSystem: "Windows Server Datacenter Version 1809 (OS Build 1803.590)",
expectedVersion: fmt.Sprintf("%s-%s-%s", "x86_64", revision, baseImage1809),
expectedErr: nil,
expectedInfo: Info{
Architecture: windowsSupportedArchitecture,
Name: name,
Tag: fmt.Sprintf("%s-%s-%s", windowsSupportedArchitecture, revision, baseImage1809),
IsSupportingLocalImport: false,
},
expectedErr: nil,
},
{
operatingSystem: "Windows Server Datacenter Version 1803 (OS Build 17134.590)",
expectedVersion: fmt.Sprintf("%s-%s-%s", "x86_64", revision, baseImage1803),
expectedErr: nil,
expectedInfo: Info{
Architecture: windowsSupportedArchitecture,
Name: name,
Tag: fmt.Sprintf("%s-%s-%s", windowsSupportedArchitecture, revision, baseImage1803),
IsSupportingLocalImport: false,
},
expectedErr: nil,
},
{
operatingSystem: "some random string",
......@@ -36,19 +50,14 @@ func Test_windowsInfo_Tag(t *testing.T) {
},
}
for _, c := range cases {
t.Run(c.operatingSystem, func(t *testing.T) {
w := newWindowsInfo(types.Info{OperatingSystem: c.operatingSystem})
for _, test := range tests {
t.Run(test.operatingSystem, func(t *testing.T) {
w := new(windowsInfo)
tag, err := w.Tag(revision)
image, err := w.Create(revision, Config{OperatingSystem: test.operatingSystem})
assert.Equal(t, c.expectedVersion, tag)
assert.Equal(t, c.expectedErr, err)
assert.Equal(t, test.expectedInfo, image)
assert.Equal(t, test.expectedErr, err)
})
}
}
func Test_windowsInfo_IsSupportingLocalImport(t *testing.T) {
u := newWindowsInfo(types.Info{})
assert.False(t, u.IsSupportingLocalImport())
}
......@@ -52,14 +52,14 @@ var flags = []FeatureFlag{
DefaultValue: "false",
Deprecated: true,
ToBeRemovedWith: "12.0",
Description: "Enables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS`",
Description: "Disables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS`",
},
{
Name: UseLegacyBuildsDirForDocker,
DefaultValue: "false",
Deprecated: true,
ToBeRemovedWith: "13.0",
Description: "Enables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org`",
ToBeRemovedWith: "12.3",
Description: "Disables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org`",
},
}
......
......@@ -41,23 +41,21 @@ func TestIsOn(t *testing.T) {
expectedError: `strconv.ParseBool: parsing "a": invalid syntax`,
},
"true value": {
expectedResult: true,
testValue: "1",
expectedResult: true,
},
"false value": {
expectedResult: false,
testValue: "f",
expectedResult: false,
},
}
for testName, testCase := range testCases {
t.Run(testName, func(t *testing.T) {
result, err := IsOn(testCase.testValue)
assert.Equal(t, testCase.expectedResult, result)
if testCase.expectedError != "" {
assert.EqualError(t, err, testCase.expectedError)
} else {
assert.NoError(t, err)
}
......
#!/bin/bash
echo "Not yet supported"
exit 1
......@@ -150,7 +150,7 @@ computeCoverageReport() {
mkdir -p "${reportDirectory}"
echo "mode: ${coverMode}" > ${sourceFile}
grep -h -v -e "^mode:" -e "executors/docker/bindata.go" .cover/*.${coverMode}.cover.txt >> ${sourceFile}
grep -h -v -E -e "^mode:" -e "\/mock_[^\.]+\.go" .cover/*.${coverMode}.cover.txt >> ${sourceFile}
printMessage "Generating HTML coverage report"
go tool cover -o ${htmlReportFile} -html=${sourceFile}
......
......@@ -19,11 +19,12 @@ const (
)
var ffTableTemplate = `{{ placeholder "start" }}
| Feature flag | Default value | Deprecated | To be removed with | Description |
|--------------|---------------|------------|--------------------|-------------|
{{ range $_, $flag := . -}}
| {{ $flag.Name | raw }} | {{ $flag.DefaultValue | raw }} | {{ $flag.Deprecated | tick }} | {{ $flag.ToBeRemovedWith }} | {{ $flag.Description }} |
{{ end -}}
{{ end }}
{{ placeholder "end" }}
`
......