Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
6
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
gitlab-runner
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
1,989
Issues
1,989
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
189
Merge Requests
189
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Test Cases
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
GitLab.org
gitlab-runner
Commits
5e234e16
Commit
5e234e16
authored
Mar 27, 2015
by
Kamil Trzciński
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use kardianos/service module
parent
722b9ba5
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
281 additions
and
88 deletions
+281
-88
.travis.yml
.travis.yml
+1
-0
CHANGELOG.md
CHANGELOG.md
+1
-0
Godeps/Godeps.json
Godeps/Godeps.json
+8
-0
commands/multi.go
commands/multi.go
+99
-61
commands/service.go
commands/service.go
+142
-0
commands/setup.go
commands/setup.go
+4
-4
commands/single.go
commands/single.go
+7
-8
common/command.go
common/command.go
+17
-0
common/config.go
common/config.go
+0
-10
main.go
main.go
+2
-5
No files found.
.travis.yml
View file @
5e234e16
...
...
@@ -7,6 +7,7 @@ env:
install
:
-
go get github.com/tools/godep
-
go get -u github.com/golang/lint/golint
-
go get code.google.com/p/winsvc/eventlog
-
godep restore
before_script
:
-
make version
...
...
CHANGELOG.md
View file @
5e234e16
...
...
@@ -4,6 +4,7 @@ v 0.1.13
-
Select default shell for OS (bash for Unix, batch for Windows)
-
Added Windows Cmd support
-
Added Windows PowerShell support
-
Added the kardianos/service which allows to easily run gitlab-ci-multi-runner as service on different platforms
v 0.1.12
-
Abort all jobs if interrupt or SIGTERM is received
...
...
Godeps/Godeps.json
View file @
5e234e16
...
...
@@ -60,6 +60,14 @@
{
"ImportPath"
:
"github.com/fsouza/go-dockerclient"
,
"Rev"
:
"5da2a37ecfb5bcb921a36dbc18e912c3235f139a"
},
{
"ImportPath"
:
"github.com/kardianos/osext"
,
"Rev"
:
"efacde03154693404c65e7aa7d461ac9014acd0c"
},
{
"ImportPath"
:
"github.com/kardianos/service"
,
"Rev"
:
"9a30c55e3f15ea76eab5c4c42d9b9b5614437ddb"
}
]
}
commands/multi.go
View file @
5e234e16
...
...
@@ -8,9 +8,12 @@ import (
"time"
"github.com/codegangsta/cli"
"github.com/kardianos/service"
log
"github.com/Sirupsen/logrus"
"errors"
"fmt"
"github.com/ayufan/gitlab-ci-multi-runner/common"
)
...
...
@@ -20,15 +23,18 @@ type RunnerHealth struct {
}
type
MultiRunner
struct
{
config
*
common
.
Config
configFile
string
allBuilds
[]
*
common
.
Build
builds
[]
*
common
.
Build
buildsLock
sync
.
RWMutex
healthy
map
[
string
]
*
RunnerHealth
healthyLock
sync
.
Mutex
finished
bool
abortBuilds
chan
os
.
Signal
config
*
common
.
Config
configFile
string
listenAddr
string
allBuilds
[]
*
common
.
Build
builds
[]
*
common
.
Build
buildsLock
sync
.
RWMutex
healthy
map
[
string
]
*
RunnerHealth
healthyLock
sync
.
Mutex
finished
bool
abortBuilds
chan
os
.
Signal
interruptSignal
chan
os
.
Signal
reloadSignal
chan
os
.
Signal
}
func
(
mr
*
MultiRunner
)
errorln
(
args
...
interface
{})
{
...
...
@@ -217,13 +223,12 @@ func (mr *MultiRunner) loadConfig() error {
return
nil
}
func
RunMulti
(
c
*
cli
.
Context
)
{
mr
:=
MultiRunner
{
configFile
:
c
.
String
(
"config"
),
allBuilds
:
[]
*
common
.
Build
{},
builds
:
[]
*
common
.
Build
{},
abortBuilds
:
make
(
chan
os
.
Signal
),
}
func
(
mr
*
MultiRunner
)
Start
(
s
service
.
Service
)
error
{
mr
.
allBuilds
=
[]
*
common
.
Build
{}
mr
.
builds
=
[]
*
common
.
Build
{}
mr
.
abortBuilds
=
make
(
chan
os
.
Signal
)
mr
.
interruptSignal
=
make
(
chan
os
.
Signal
)
mr
.
reloadSignal
=
make
(
chan
os
.
Signal
,
1
)
mr
.
println
(
"Starting multi-runner from"
,
mr
.
configFile
,
"..."
)
...
...
@@ -232,16 +237,23 @@ func RunMulti(c *cli.Context) {
panic
(
err
)
}
// Start webserver
if
l
istenAddr
:=
c
.
String
(
"listen-addr"
);
len
(
listenAddr
)
>
0
{
// Start web
server
if
l
en
(
mr
.
listenAddr
)
>
0
{
mrs
:=
MultiRunnerServer
{
MultiRunner
:
&
mr
,
listenAddresses
:
[]
string
{
listenAddr
},
MultiRunner
:
mr
,
listenAddresses
:
[]
string
{
mr
.
listenAddr
},
}
go
mrs
.
Run
()
}
// Start should not block. Do the actual work async.
go
mr
.
Run
()
return
nil
}
func
(
mr
*
MultiRunner
)
Run
()
{
runners
:=
make
(
chan
*
common
.
RunnerConfig
)
go
mr
.
feedRunners
(
runners
)
...
...
@@ -249,11 +261,7 @@ func RunMulti(c *cli.Context) {
stopWorker
:=
make
(
chan
bool
)
go
mr
.
startWorkers
(
startWorker
,
stopWorker
,
runners
)
interruptSignal
:=
make
(
chan
os
.
Signal
,
2
)
signal
.
Notify
(
interruptSignal
,
os
.
Interrupt
,
syscall
.
SIGTERM
)
reloadSignal
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
reloadSignal
,
syscall
.
SIGHUP
)
signal
.
Notify
(
mr
.
reloadSignal
,
syscall
.
SIGHUP
)
currentWorkers
:=
0
workerIndex
:=
0
...
...
@@ -267,7 +275,7 @@ finish_worker:
for
currentWorkers
>
buildLimit
{
select
{
case
stopWorker
<-
true
:
case
signaled
=
<-
interruptSignal
:
case
signaled
=
<-
mr
.
interruptSignal
:
break
finish_worker
}
currentWorkers
--
...
...
@@ -276,7 +284,7 @@ finish_worker:
for
currentWorkers
<
buildLimit
{
select
{
case
startWorker
<-
workerIndex
:
case
signaled
=
<-
interruptSignal
:
case
signaled
=
<-
mr
.
interruptSignal
:
break
finish_worker
}
currentWorkers
++
...
...
@@ -305,7 +313,7 @@ finish_worker:
mr
.
println
(
"Config reloaded."
)
case
<-
reloadSignal
:
case
<-
mr
.
reloadSignal
:
err
:=
mr
.
loadConfig
()
if
err
!=
nil
{
mr
.
errorln
(
"Failed to load config"
,
err
)
...
...
@@ -314,16 +322,12 @@ finish_worker:
mr
.
println
(
"Config reloaded."
)
case
signaled
=
<-
interruptSignal
:
case
signaled
=
<-
mr
.
interruptSignal
:
break
finish_worker
}
}
mr
.
errorln
(
"Received signal:"
,
signaled
)
mr
.
finished
=
true
close
:=
make
(
chan
int
)
// Pump signal to abort all builds
go
func
()
{
for
{
...
...
@@ -331,39 +335,73 @@ finish_worker:
}
}()
// Watch for second signal which will force to close process
go
func
()
{
newSignal
:=
<-
interruptSignal
mr
.
errorln
(
"Forced exit:"
,
newSignal
)
close
<-
1
}()
// Wait for workers to shutdown
go
func
()
{
for
currentWorkers
>
0
{
stopWorker
<-
true
currentWorkers
--
}
mr
.
println
(
"All workers stopped. Can exit now"
)
close
<-
0
}()
for
currentWorkers
>
0
{
stopWorker
<-
true
currentWorkers
--
}
mr
.
println
(
"All workers stopped. Can exit now"
)
os
.
Exit
(
0
)
}
// Timeout shutdown
go
func
()
{
time
.
Sleep
(
common
.
ShutdownTimeout
*
time
.
Second
)
mr
.
errorln
(
"Shutdown timedout."
)
close
<-
1
}()
func
(
mr
*
MultiRunner
)
Stop
(
s
service
.
Service
)
error
{
mr
.
errorln
(
"Requested service stop"
)
mr
.
interruptSignal
<-
os
.
Interrupt
os
.
Exit
(
<-
close
)
signals
:=
make
(
chan
os
.
Signal
)
signal
.
Notify
(
signals
,
os
.
Interrupt
,
syscall
.
SIGTERM
)
select
{
case
newSignal
:=
<-
signals
:
return
fmt
.
Errorf
(
"forced exit:"
,
newSignal
)
case
<-
time
.
After
(
common
.
ShutdownTimeout
*
time
.
Second
)
:
return
errors
.
New
(
"shutdown timedout"
)
}
}
var
(
CmdRunMulti
=
cli
.
Command
{
func
CreateService
(
c
*
cli
.
Context
)
service
.
Service
{
svcConfig
:=
&
service
.
Config
{
Name
:
"gitlab-ci-multi-runner"
,
DisplayName
:
"GitLab-CI Multi-purpose Runner"
,
Description
:
"Unofficial GitLab CI runner written in Go"
,
Arguments
:
[]
string
{
"run"
},
}
mr
:=
&
MultiRunner
{
configFile
:
c
.
String
(
"config"
),
listenAddr
:
c
.
String
(
"listen-addr"
),
}
s
,
err
:=
service
.
New
(
mr
,
svcConfig
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
return
s
}
func
RunService
(
c
*
cli
.
Context
)
{
s
:=
CreateService
(
c
)
logger
,
err
:=
s
.
Logger
(
nil
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
if
!
service
.
Interactive
()
{
log
.
AddHook
(
&
ServiceLogHook
{
logger
})
}
err
=
s
.
Run
()
if
err
!=
nil
{
logger
.
Error
(
err
)
}
}
func
init
()
{
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"run"
,
ShortName
:
"r"
,
Usage
:
"run multi runner"
,
Action
:
Run
Multi
,
Usage
:
"run multi runner
service
"
,
Action
:
Run
Service
,
Flags
:
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"docker-host"
,
...
...
@@ -384,5 +422,5 @@ var (
EnvVar
:
"API_LISTEN"
,
},
},
}
)
}
)
}
commands/service.go
0 → 100644
View file @
5e234e16
package
commands
import
(
log
"github.com/Sirupsen/logrus"
"github.com/ayufan/gitlab-ci-multi-runner/common"
"github.com/codegangsta/cli"
"github.com/kardianos/service"
"os"
"os/user"
"runtime"
)
type
ServiceLogHook
struct
{
service
.
Logger
}
func
(
s
*
ServiceLogHook
)
Levels
()
[]
log
.
Level
{
return
[]
log
.
Level
{
log
.
PanicLevel
,
log
.
FatalLevel
,
log
.
ErrorLevel
,
log
.
WarnLevel
,
log
.
InfoLevel
,
}
}
func
(
s
*
ServiceLogHook
)
Fire
(
e
*
log
.
Entry
)
error
{
switch
e
.
Level
{
case
log
.
PanicLevel
,
log
.
FatalLevel
,
log
.
ErrorLevel
:
s
.
Error
(
e
.
Message
)
case
log
.
WarnLevel
:
s
.
Warning
(
e
.
Message
)
case
log
.
InfoLevel
:
s
.
Info
(
e
.
Message
)
}
return
nil
}
type
NullService
struct
{
}
func
(
n
*
NullService
)
Start
(
s
service
.
Service
)
error
{
return
nil
}
func
(
n
*
NullService
)
Stop
(
s
service
.
Service
)
error
{
return
nil
}
func
RunServiceControl
(
c
*
cli
.
Context
)
{
svcConfig
:=
&
service
.
Config
{
Name
:
c
.
String
(
"service-name"
),
DisplayName
:
"GitLab-CI Multi-purpose Runner"
,
Description
:
"Unofficial GitLab CI runner written in Go"
,
Arguments
:
[]
string
{
"run"
},
UserName
:
c
.
String
(
"user"
),
}
if
runtime
.
GOOS
==
"darwin"
{
svcConfig
.
UserService
=
true
svcConfig
.
Option
=
service
.
KeyValue
{
"KeepAlive"
:
true
,
"RunAtLoad"
:
true
,
}
}
if
config
:=
c
.
String
(
"config"
);
config
!=
""
{
svcConfig
.
Arguments
=
append
(
svcConfig
.
Arguments
,
"--config"
,
config
)
}
s
,
err
:=
service
.
New
(
&
NullService
{},
svcConfig
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
err
=
service
.
Control
(
s
,
c
.
Command
.
Name
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
}
func
getCurrentUserName
()
string
{
user
,
_
:=
user
.
Current
()
if
user
!=
nil
{
return
user
.
Username
}
return
""
}
func
init
()
{
flags
:=
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"service-name, n"
,
Value
:
"gitlab-ci-multi-runner"
,
Usage
:
"Use different names for different services"
,
},
cli
.
StringFlag
{
Name
:
"config, c"
,
Value
:
"config.toml"
,
Usage
:
"Specify custom config file"
,
},
}
if
runtime
.
GOOS
!=
"darwin"
{
flags
=
append
(
flags
,
cli
.
StringFlag
{
Name
:
"user, u"
,
Value
:
getCurrentUserName
(),
Usage
:
"Specify user-name to secure the runner"
,
})
}
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"install"
,
Usage
:
"install service"
,
Action
:
RunServiceControl
,
Flags
:
flags
,
})
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"uninstall"
,
Usage
:
"uninstall service"
,
Action
:
RunServiceControl
,
Flags
:
flags
,
})
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"start"
,
Usage
:
"start service"
,
Action
:
RunServiceControl
,
Flags
:
flags
,
})
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"stop"
,
Usage
:
"stop service"
,
Action
:
RunServiceControl
,
Flags
:
flags
,
})
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"restart"
,
Usage
:
"restart service"
,
Action
:
RunServiceControl
,
Flags
:
flags
,
})
}
commands/setup.go
View file @
5e234e16
...
...
@@ -232,8 +232,8 @@ func getHostname() string {
return
hostname
}
var
(
CmdRunSetup
=
cli
.
Command
{
func
init
()
{
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"setup"
,
ShortName
:
"s"
,
Usage
:
"setup a new runner"
,
...
...
@@ -357,5 +357,5 @@ var (
EnvVar
:
"SSH_USER"
,
},
},
}
)
}
)
}
commands/single.go
View file @
5e234e16
...
...
@@ -92,12 +92,11 @@ func runSingle(c *cli.Context) {
}
}
var
(
CmdRunSingle
=
cli
.
Command
{
Name
:
"run-single"
,
ShortName
:
"rs"
,
Usage
:
"start single runner"
,
Action
:
runSingle
,
func
init
()
{
common
.
RegisterCommand
(
cli
.
Command
{
Name
:
"run-single"
,
Usage
:
"start single runner"
,
Action
:
runSingle
,
Flags
:
[]
cli
.
Flag
{
cli
.
StringFlag
{
Name
:
"token"
,
...
...
@@ -142,5 +141,5 @@ var (
EnvVar
:
"RUNNER_BUILDS_DIR"
,
},
},
}
)
}
)
}
common/command.go
0 → 100644
View file @
5e234e16
package
common
import
(
log
"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
)
var
commands
[]
cli
.
Command
func
RegisterCommand
(
command
cli
.
Command
)
{
log
.
Debugln
(
"Registering"
,
command
.
Name
,
"command..."
)
commands
=
append
(
commands
,
command
)
}
func
GetCommands
()
[]
cli
.
Command
{
return
commands
}
common/config.go
View file @
5e234e16
...
...
@@ -56,7 +56,6 @@ type RunnerConfig struct {
type
BaseConfig
struct
{
Concurrent
int
`toml:"concurrent" json:"concurrent"`
RootDir
string
`toml:"root_dir" json:"root_dir"`
Runners
[]
*
RunnerConfig
`toml:"runners" json:"runners"`
}
...
...
@@ -110,12 +109,3 @@ func (c *Config) SaveConfig(configFile string) error {
return
nil
}
func
(
c
*
Config
)
SetChdir
()
{
if
len
(
c
.
RootDir
)
>
0
{
err
:=
os
.
Chdir
(
c
.
RootDir
)
if
err
!=
nil
{
panic
(
err
)
}
}
}
main.go
View file @
5e234e16
...
...
@@ -8,6 +8,7 @@ import (
"github.com/codegangsta/cli"
"github.com/ayufan/gitlab-ci-multi-runner/commands"
"github.com/ayufan/gitlab-ci-multi-runner/common"
_
"github.com/ayufan/gitlab-ci-multi-runner/executors/docker"
_
"github.com/ayufan/gitlab-ci-multi-runner/executors/parallels"
_
"github.com/ayufan/gitlab-ci-multi-runner/executors/shell"
...
...
@@ -53,11 +54,7 @@ func main() {
return
nil
}
app
.
Commands
=
[]
cli
.
Command
{
commands
.
CmdRunMulti
,
commands
.
CmdRunSetup
,
commands
.
CmdRunSingle
,
}
app
.
Commands
=
common
.
GetCommands
()
if
err
:=
app
.
Run
(
os
.
Args
);
err
!=
nil
{
log
.
Fatal
(
err
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment