File: abstract.go

package info (click to toggle)
gitlab-ci-multi-runner 14.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 31,248 kB
  • sloc: sh: 1,694; makefile: 384; asm: 79; ruby: 68
file content (156 lines) | stat: -rw-r--r-- 3,506 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package executors

import (
	"context"
	"os"
	"sync"

	"gitlab.com/gitlab-org/gitlab-runner/common"
	"gitlab.com/gitlab-org/gitlab-runner/session/proxy"
)

type ExecutorOptions struct {
	DefaultCustomBuildsDirEnabled bool
	DefaultBuildsDir              string
	DefaultCacheDir               string
	SharedBuildsDir               bool
	Shell                         common.ShellScriptInfo
	ShowHostname                  bool
	Metadata                      map[string]string
}

type AbstractExecutor struct {
	ExecutorOptions
	common.BuildLogger
	Config       common.RunnerConfig
	Build        *common.Build
	Trace        common.JobTrace
	BuildShell   *common.ShellConfiguration
	currentStage common.ExecutorStage
	Context      context.Context
	ProxyPool    proxy.Pool

	stageLock sync.RWMutex
}

func (e *AbstractExecutor) updateShell() error {
	script := e.Shell()
	script.Build = e.Build
	if e.Config.Shell != "" {
		script.Shell = e.Config.Shell
	}
	return nil
}

func (e *AbstractExecutor) generateShellConfiguration() error {
	info := e.Shell()
	info.PreCloneScript = e.Config.PreCloneScript
	info.PostCloneScript = e.Config.PostCloneScript
	info.PreBuildScript = e.Config.PreBuildScript
	info.PostBuildScript = e.Config.PostBuildScript
	shellConfiguration, err := common.GetShellConfiguration(*info)
	if err != nil {
		return err
	}
	e.BuildShell = shellConfiguration
	e.Debugln("Shell configuration:", shellConfiguration)
	return nil
}

func (e *AbstractExecutor) startBuild() error {
	// Save hostname
	if e.ShowHostname && e.Build.Hostname == "" {
		e.Build.Hostname, _ = os.Hostname()
	}

	return e.Build.StartBuild(
		e.RootDir(),
		e.CacheDir(),
		e.CustomBuildEnabled(),
		e.SharedBuildsDir,
	)
}

func (e *AbstractExecutor) RootDir() string {
	if e.Config.BuildsDir != "" {
		return e.Config.BuildsDir
	}

	return e.DefaultBuildsDir
}

func (e *AbstractExecutor) CacheDir() string {
	if e.Config.CacheDir != "" {
		return e.Config.CacheDir
	}

	return e.DefaultCacheDir
}

func (e *AbstractExecutor) CustomBuildEnabled() bool {
	if e.Config.CustomBuildDir != nil {
		return e.Config.CustomBuildDir.Enabled
	}

	return e.DefaultCustomBuildsDirEnabled
}

func (e *AbstractExecutor) Shell() *common.ShellScriptInfo {
	return &e.ExecutorOptions.Shell
}

func (e *AbstractExecutor) Prepare(options common.ExecutorPrepareOptions) error {
	e.PrepareConfiguration(options)

	return e.PrepareBuildAndShell()
}

func (e *AbstractExecutor) PrepareConfiguration(options common.ExecutorPrepareOptions) {
	e.SetCurrentStage(common.ExecutorStagePrepare)
	e.Context = options.Context
	e.Config = *options.Config
	e.Build = options.Build
	e.Trace = options.Trace
	e.BuildLogger = common.NewBuildLogger(options.Trace, options.Build.Log())
	e.ProxyPool = proxy.NewPool()
}

func (e *AbstractExecutor) PrepareBuildAndShell() error {
	err := e.startBuild()
	if err != nil {
		return err
	}

	err = e.updateShell()
	if err != nil {
		return err
	}

	err = e.generateShellConfiguration()
	if err != nil {
		return err
	}
	return nil
}

func (e *AbstractExecutor) Finish(err error) {
	e.SetCurrentStage(common.ExecutorStageFinish)
}

func (e *AbstractExecutor) Cleanup() {
	e.SetCurrentStage(common.ExecutorStageCleanup)
}

func (e *AbstractExecutor) GetCurrentStage() common.ExecutorStage {
	e.stageLock.RLock()
	defer e.stageLock.RUnlock()

	return e.currentStage
}

func (e *AbstractExecutor) SetCurrentStage(stage common.ExecutorStage) {
	e.stageLock.Lock()
	defer e.stageLock.Unlock()

	e.currentStage = stage
}