cyclid 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/cyclid/plugins/action/cobertura.rb +71 -0
- data/app/cyclid/plugins/action/simplecov.rb +59 -0
- data/app/cyclid/plugins/builder/docker.rb +100 -0
- data/app/cyclid/plugins/builder/google.rb +3 -1
- data/app/cyclid/plugins/helpers/docker.rb +53 -0
- data/app/cyclid/plugins/provisioner/centos.rb +51 -0
- data/app/cyclid/plugins/provisioner/fedora.rb +51 -0
- data/app/cyclid/plugins/provisioner/redhat/helpers.rb +180 -0
- data/app/cyclid/plugins/provisioner/rhel.rb +51 -0
- data/app/cyclid/plugins/transport/dockerapi.rb +99 -0
- data/lib/cyclid/version.rb +1 -1
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea995b9c7270ae9d3e38e97ad81397ceb4b73e13
|
4
|
+
data.tar.gz: 7642bb2b0a8703a0199e092858091de720d9bb19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4e2f3529858bdba00c9be839fff1c6a0a7091355abdf7ec002781c44d0acad9764f37b39f1eb322ea0fe63f5c9141a536cd34dea6126252f0bd8fdcf1464717
|
7
|
+
data.tar.gz: f3e00484f2d3491f56424612bc317b178b936109403ccbca9f802899b62fc5d69f9ceeff8f8720d02771209345c6883af60536749aa0f38d021f38de2feff2b1
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Cyclid
|
|
4
4
|
|
5
5
|
See http://docs.cyclid.io/en/latest/ for full documentation, including [installation instructions](http://docs.cyclid.io/en/latest/server.html#installation).
|
6
6
|
|
7
|
-
#
|
7
|
+
# Development
|
8
8
|
|
9
9
|
Cyclid is an Open Source project and we welcome contributions. These instructions will help you get your development environment set up to develop & test Cyclid.
|
10
10
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016, 2017 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'nokogiri'
|
17
|
+
|
18
|
+
# Top level module for the core Cyclid code.
|
19
|
+
module Cyclid
|
20
|
+
# Module for the Cyclid API
|
21
|
+
module API
|
22
|
+
# Module for Cyclid Plugins
|
23
|
+
module Plugins
|
24
|
+
# Cobertura (& compatible) coverage reader plugin
|
25
|
+
class Cobertura < Action
|
26
|
+
def initialize(args = {})
|
27
|
+
args.symbolize_keys!
|
28
|
+
|
29
|
+
# There must be the path to the coverage report..
|
30
|
+
raise 'a Cobertura action requires a path' unless args.include? :path
|
31
|
+
|
32
|
+
@path = args[:path]
|
33
|
+
end
|
34
|
+
|
35
|
+
def perform(log)
|
36
|
+
# Retrieve the Cobertura XML report
|
37
|
+
report = StringIO.new
|
38
|
+
@transport.download(report, @path ** @ctx)
|
39
|
+
|
40
|
+
# Parse the report and extract the line & branch coverage.
|
41
|
+
xml = Nokogiri.parse(report.string)
|
42
|
+
coverage = xml.xpath('//coverage')
|
43
|
+
line_rate = coverage.attr('line-rate').value.to_f
|
44
|
+
branch_rate = coverage.attr('branch-rate').value.to_f
|
45
|
+
|
46
|
+
# Coverage is given as a fraction, so convert it to a percentage.
|
47
|
+
#
|
48
|
+
# Cobertura can produce oddly specific coverage metrics, so round it
|
49
|
+
# to only 2 decimal points...
|
50
|
+
line_rate_pct = (line_rate * 100).round(2)
|
51
|
+
branch_rate_pct = (branch_rate * 100).round(2)
|
52
|
+
|
53
|
+
log.write "Cobertura coverage line rate is #{line_rate_pct}%, " \
|
54
|
+
"branch rate is #{branch_rate_pct}%\n"
|
55
|
+
|
56
|
+
@ctx[:cobertura_line_rate] = "#{line_rate_pct}%"
|
57
|
+
@ctx[:cobertura_branch_rate] = "#{branch_rate_pct}%"
|
58
|
+
|
59
|
+
return [true, 0]
|
60
|
+
rescue StandardError => ex
|
61
|
+
log.write "Failed to read Cobertura coverage report: #{ex}"
|
62
|
+
|
63
|
+
return [false, 0]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Register this plugin
|
67
|
+
register_plugin 'cobertura'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016, 2017 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
# Top level module for the core Cyclid code.
|
17
|
+
module Cyclid
|
18
|
+
# Module for the Cyclid API
|
19
|
+
module API
|
20
|
+
# Module for Cyclid Plugins
|
21
|
+
module Plugins
|
22
|
+
# Simplecov coverage reader plugin
|
23
|
+
class Simplecov < Action
|
24
|
+
def initialize(args = {})
|
25
|
+
args.symbolize_keys!
|
26
|
+
|
27
|
+
# There must be the path to the coverage report..
|
28
|
+
raise 'a simplecov action requires a path' unless args.include? :path
|
29
|
+
|
30
|
+
@path = args[:path]
|
31
|
+
end
|
32
|
+
|
33
|
+
def perform(log)
|
34
|
+
# Retrieve the Simplecov JSON report
|
35
|
+
report = StringIO.new
|
36
|
+
@transport.download(report, @path ** @ctx)
|
37
|
+
|
38
|
+
# Parse the report and extract the total coverage percentage;
|
39
|
+
# Simplecov can produce oddly specific coverage metrics, so round it
|
40
|
+
# to only 2 decimal points...
|
41
|
+
coverage = JSON.parse(report.string)
|
42
|
+
covered_percent = coverage['metrics']['covered_percent'].round(2)
|
43
|
+
|
44
|
+
log.write "Simplecov coverage is #{covered_percent}%\n"
|
45
|
+
@ctx[:simplecov_coverage] = "#{covered_percent}%"
|
46
|
+
|
47
|
+
return [true, 0]
|
48
|
+
rescue StandardError => ex
|
49
|
+
log.write "Failed to read Simplecov coverage report: #{ex}"
|
50
|
+
|
51
|
+
return [false, 0]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Register this plugin
|
55
|
+
register_plugin 'simplecov'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
|
14
|
+
require 'docker'
|
15
|
+
require_rel '../helpers/docker'
|
16
|
+
|
17
|
+
# Top level module for the core Cyclid code
|
18
|
+
module Cyclid
|
19
|
+
# Module for the Cyclid API
|
20
|
+
module API
|
21
|
+
# Module for Cyclid plugins
|
22
|
+
module Plugins
|
23
|
+
# Docker build host
|
24
|
+
class DockerHost < BuildHost
|
25
|
+
# Docker is the only acceptable transport
|
26
|
+
def transports
|
27
|
+
['dockerapi']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Docker builder, uses the Docker API to create a build host container
|
32
|
+
class Docker < Builder
|
33
|
+
include Cyclid::API::Plugins::Helpers::Docker
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@config = load_docker_config(
|
37
|
+
Cyclid.config.plugins
|
38
|
+
)
|
39
|
+
::Docker.url = @config[:api]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Create and return a build host
|
43
|
+
def get(args = {})
|
44
|
+
args.symbolize_keys!
|
45
|
+
|
46
|
+
Cyclid.logger.debug "docker: args=#{args}"
|
47
|
+
|
48
|
+
# If there is one, split the 'os' into a 'distro' and 'release'
|
49
|
+
if args.key? :os
|
50
|
+
match = args[:os].match(/\A(\w*)_(.*)\Z/)
|
51
|
+
distro = match[1] if match
|
52
|
+
release = match[2] if match
|
53
|
+
else
|
54
|
+
# No OS was specified; use the default
|
55
|
+
# XXX Defaults should be configurable
|
56
|
+
distro = 'ubuntu'
|
57
|
+
release = 'trusty'
|
58
|
+
end
|
59
|
+
|
60
|
+
# Find the image for the given distribution & release
|
61
|
+
image_alias = "#{distro}:#{release}"
|
62
|
+
Cyclid.logger.debug "image_alias=#{image_alias}"
|
63
|
+
|
64
|
+
# Create a new instance
|
65
|
+
name = create_name
|
66
|
+
container = create_container(name, image_alias)
|
67
|
+
|
68
|
+
Cyclid.logger.debug "container=#{container}"
|
69
|
+
|
70
|
+
# Create a buildhost from the container details
|
71
|
+
DockerHost.new(
|
72
|
+
host: container.id,
|
73
|
+
name: name,
|
74
|
+
username: 'root',
|
75
|
+
workspace: '/root',
|
76
|
+
distro: distro,
|
77
|
+
release: release
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Destroy the container when done
|
82
|
+
def release(_transport, buildhost)
|
83
|
+
container = get_container(buildhost[:host])
|
84
|
+
container.delete(force: true)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Register this plugin
|
88
|
+
register_plugin 'docker'
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Get a unique name for the container
|
93
|
+
def create_name
|
94
|
+
base = @config[:instance_name]
|
95
|
+
"#{base}-#{SecureRandom.hex(16)}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -144,7 +144,9 @@ module Cyclid
|
|
144
144
|
|
145
145
|
match = image.name.match(/^#{distro}-((\d*)-(.*)-v.*$|(\d*)-v.*$)/)
|
146
146
|
next unless match
|
147
|
-
next unless match[2] == release or
|
147
|
+
next unless match[2] == release or
|
148
|
+
match[3] == release or
|
149
|
+
match[4] == release
|
148
150
|
|
149
151
|
# Found one
|
150
152
|
Cyclid.logger.info "found image #{image.name} for #{distro}:#{release}"
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Top level module for the core Cyclid code.
|
3
|
+
module Cyclid
|
4
|
+
# Module for the Cyclid API
|
5
|
+
module API
|
6
|
+
# Module for Cyclid Plugins
|
7
|
+
module Plugins
|
8
|
+
# Module for helper methods
|
9
|
+
module Helpers
|
10
|
+
# Module for Docker related bits within Cyclid
|
11
|
+
module Docker
|
12
|
+
# Load the config for the docker builder
|
13
|
+
def load_docker_config(config)
|
14
|
+
config.symbolize_keys!
|
15
|
+
|
16
|
+
docker_config = config[:docker] || {}
|
17
|
+
Cyclid.logger.debug "docker: config=#{docker_config}"
|
18
|
+
|
19
|
+
docker_config[:api] = 'unix:///var/run/docker.sock' \
|
20
|
+
unless docker_config.key? :api
|
21
|
+
docker_config[:instance_name] = 'cyclid-build' \
|
22
|
+
unless docker_config.key? :instance_name
|
23
|
+
|
24
|
+
docker_config
|
25
|
+
end
|
26
|
+
|
27
|
+
# Actually create the container
|
28
|
+
def create_container(name, image)
|
29
|
+
# Pull a suitable image
|
30
|
+
Cyclid.logger.debug "Creating image '#{image}'"
|
31
|
+
::Docker::Image.create('fromImage' => image)
|
32
|
+
|
33
|
+
# Create the container
|
34
|
+
# XXX How do we (reliably) know what to run? /sbin/init is a good
|
35
|
+
# guess but not bullet proof
|
36
|
+
Cyclid.logger.debug "Creating container '#{name}'"
|
37
|
+
container = ::Docker::Container.create('Name' => name,
|
38
|
+
'Image' => image,
|
39
|
+
'Cmd' => ['/sbin/init'])
|
40
|
+
container.start
|
41
|
+
|
42
|
+
return container
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get information about a container
|
46
|
+
def get_container(id)
|
47
|
+
::Docker::Container.get(id)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2017, 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require_relative 'redhat/helpers'
|
17
|
+
|
18
|
+
# Top level module for the core Cyclid code.
|
19
|
+
module Cyclid
|
20
|
+
# Module for the Cyclid API
|
21
|
+
module API
|
22
|
+
# Module for Cyclid Plugins
|
23
|
+
module Plugins
|
24
|
+
# CentOS provisioner
|
25
|
+
class Centos < Provisioner
|
26
|
+
def initialize
|
27
|
+
@quiet = true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prepare a CentOS based build host
|
31
|
+
def prepare(transport, buildhost, env = {})
|
32
|
+
release = buildhost[:release].to_i
|
33
|
+
|
34
|
+
Cyclid.logger.debug 'is Centos'
|
35
|
+
if release >= 6
|
36
|
+
Cyclid.logger.debug 'is >= 6'
|
37
|
+
prepare_redhat(transport, env)
|
38
|
+
else
|
39
|
+
Cyclid.logger.debug 'is < 5'
|
40
|
+
prepare_redhat_5(transport, env)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register this plugin
|
45
|
+
register_plugin 'centos'
|
46
|
+
|
47
|
+
include Helpers::Redhat
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2017, 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require_relative 'redhat/helpers'
|
17
|
+
|
18
|
+
# Top level module for the core Cyclid code.
|
19
|
+
module Cyclid
|
20
|
+
# Module for the Cyclid API
|
21
|
+
module API
|
22
|
+
# Module for Cyclid Plugins
|
23
|
+
module Plugins
|
24
|
+
# Fedora provisioner
|
25
|
+
class Fedora < Provisioner
|
26
|
+
def initialize
|
27
|
+
@quiet = true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prepare a Fedora based build host
|
31
|
+
def prepare(transport, buildhost, env = {})
|
32
|
+
release = buildhost[:release].to_i
|
33
|
+
|
34
|
+
Cyclid.logger.debug 'is Fedora'
|
35
|
+
if release >= 22
|
36
|
+
Cyclid.logger.debug 'is >= 22'
|
37
|
+
prepare_fedora_dnf(transport, env)
|
38
|
+
else
|
39
|
+
Cyclid.logger.debug 'is < 22'
|
40
|
+
prepare_fedora_yum(transport, env)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register this plugin
|
45
|
+
register_plugin 'fedora'
|
46
|
+
|
47
|
+
include Helpers::Redhat
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2017, 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
# Top level module for the core Cyclid code.
|
17
|
+
module Cyclid
|
18
|
+
# Module for the Cyclid API
|
19
|
+
module API
|
20
|
+
# Module for Cyclid Plugins
|
21
|
+
module Plugins
|
22
|
+
# Module for helper methods
|
23
|
+
module Helpers
|
24
|
+
# Redhatish provisioner helper methods
|
25
|
+
module Redhat
|
26
|
+
# Insert the --quiet flag if required
|
27
|
+
def quiet
|
28
|
+
@quiet ? '-q' : ''
|
29
|
+
end
|
30
|
+
|
31
|
+
# Install the yum-utils package
|
32
|
+
def install_yum_utils(transport)
|
33
|
+
transport.exec 'yum install -q -y yum-utils'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Import a signing key with RPM
|
37
|
+
def import_signing_key(transport, key_url)
|
38
|
+
transport.exec("rpm #{quiet} --import #{key_url}") \
|
39
|
+
end
|
40
|
+
|
41
|
+
# Install a package group with yum
|
42
|
+
def yum_groupinstall(transport, groups)
|
43
|
+
grouplist = groups.map{ |g| "\"#{g}\"" }.join(' ')
|
44
|
+
transport.exec "yum groupinstall #{quiet} -y #{grouplist}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Install a list of packages with yum
|
48
|
+
def yum_install(transport, packages)
|
49
|
+
transport.exec "yum install #{quiet} -y #{packages.join(' ')}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Add a repository with yum-config-manager
|
53
|
+
def yum_add_repo(transport, url)
|
54
|
+
transport.exec("yum-config-manager #{quiet} --add-repo #{url}")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Use DNF to configure & install Fedora
|
58
|
+
def prepare_fedora_dnf(transport, env)
|
59
|
+
Cyclid.logger.debug 'using DNF'
|
60
|
+
|
61
|
+
if env.key? :repos
|
62
|
+
# We need the config-manager plugin
|
63
|
+
transport.exec("dnf install #{quiet} -y 'dnf-command(config-manager)'")
|
64
|
+
|
65
|
+
env[:repos].each do |repo|
|
66
|
+
next unless repo.key? :url
|
67
|
+
|
68
|
+
# If there's a key, install it
|
69
|
+
import_signing_key(transport, repo[:key_url]) \
|
70
|
+
if repo.key? :key_url
|
71
|
+
|
72
|
+
if repo[:url] =~ /\.rpm$/
|
73
|
+
# If the URL is an RPM just install it
|
74
|
+
transport.exec("dnf install #{quiet} -y #{repo[:url]}")
|
75
|
+
else
|
76
|
+
# Not an RPM? Let's hope it's a repo file
|
77
|
+
transport.exec("dnf config-manager #{quiet} --add-repo #{repo[:url]}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if env.key? :groups
|
83
|
+
groups = env[:groups].map{ |g| "\"#{g}\"" }.join(' ')
|
84
|
+
transport.exec "dnf groups install #{quiet} -y #{groups}"
|
85
|
+
end
|
86
|
+
|
87
|
+
transport.exec "dnf install #{quiet} -y #{env[:packages].join(' ')}" \
|
88
|
+
if env.key? :packages
|
89
|
+
end
|
90
|
+
|
91
|
+
# Use YUM to configure & install Fedora
|
92
|
+
def prepare_fedora_yum(transport, env)
|
93
|
+
Cyclid.logger.debug 'using YUM'
|
94
|
+
|
95
|
+
if env.key? :repos
|
96
|
+
# We'll need yum-utils for yum-config-manager
|
97
|
+
install_yum_utils(transport)
|
98
|
+
|
99
|
+
env[:repos].each do |repo|
|
100
|
+
next unless repo.key? :url
|
101
|
+
|
102
|
+
# If there's a key, install it
|
103
|
+
import_signing_key(transport, repo[:key_url]) \
|
104
|
+
if repo.key? :key_url
|
105
|
+
|
106
|
+
if repo[:url] =~ /\.rpm$/
|
107
|
+
# If the URL is an RPM just install it
|
108
|
+
transport.exec("yum install #{quiet} -y --nogpgcheck #{repo[:url]}")
|
109
|
+
else
|
110
|
+
# Not an RPM? Let's hope it's a repo file
|
111
|
+
yum_add_repo(transport, repo[:url])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
yum_groupinstall(transport, env[:groups]) \
|
117
|
+
if env.key? :groups
|
118
|
+
|
119
|
+
yum_install(transport, env[:packages]) \
|
120
|
+
if env.key? :packages
|
121
|
+
end
|
122
|
+
|
123
|
+
# Use YUM to configure & install a Redhat-like (RHEL, CentOS etc.)
|
124
|
+
def prepare_redhat(transport, env)
|
125
|
+
Cyclid.logger.debug 'using YUM'
|
126
|
+
|
127
|
+
if env.key? :repos
|
128
|
+
# We'll need yum-utils for yum-config-manager
|
129
|
+
install_yum_utils(transport)
|
130
|
+
|
131
|
+
env[:repos].each do |repo|
|
132
|
+
next unless repo.key? :url
|
133
|
+
|
134
|
+
# If there's a key, install it
|
135
|
+
import_signing_key(transport, repo[:key_url]) \
|
136
|
+
if repo.key? :key_url
|
137
|
+
|
138
|
+
if repo[:url] =~ /\.rpm$/
|
139
|
+
# If the URL is an RPM just install it
|
140
|
+
transport.exec("yum localinstall #{quiet} -y --nogpgcheck #{repo[:url]}")
|
141
|
+
else
|
142
|
+
# Not an RPM? Let's hope it's a repo file
|
143
|
+
yum_add_repo(transport, repo[:url])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
yum_groupinstall(transport, env[:groups]) \
|
149
|
+
if env.key? :groups
|
150
|
+
|
151
|
+
yum_install(transport, env[:packages]) \
|
152
|
+
if env.key? :packages
|
153
|
+
end
|
154
|
+
|
155
|
+
# Use YUM & RPM to configure & install a Redhat-like (RHEL, CentOS etc.)
|
156
|
+
def prepare_redhat_5(transport, env)
|
157
|
+
if env.key? :repos
|
158
|
+
env[:repos].each do |repo|
|
159
|
+
next unless repo.key? :url
|
160
|
+
|
161
|
+
# If there's a key, install it
|
162
|
+
import_signing_key(transport, repo[:key_url]) \
|
163
|
+
if repo.key? :key_url
|
164
|
+
|
165
|
+
# Assume the URL is an RPM
|
166
|
+
transport.exec("rpm -U #{quiet} #{repo[:url]}")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
yum_groupinstall(transport, env[:groups]) \
|
171
|
+
if env.key? :groups
|
172
|
+
|
173
|
+
yum_install(transport, env[:packages]) \
|
174
|
+
if env.key? :packages
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2017, 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require_relative 'redhat/helpers'
|
17
|
+
|
18
|
+
# Top level module for the core Cyclid code.
|
19
|
+
module Cyclid
|
20
|
+
# Module for the Cyclid API
|
21
|
+
module API
|
22
|
+
# Module for Cyclid Plugins
|
23
|
+
module Plugins
|
24
|
+
# RHEL provisioner
|
25
|
+
class RHEL < Provisioner
|
26
|
+
def initialize
|
27
|
+
@quiet = true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prepare a RHEL based build host
|
31
|
+
def prepare(transport, buildhost, env = {})
|
32
|
+
release = buildhost[:release].to_i
|
33
|
+
|
34
|
+
Cyclid.logger.debug 'is RHEL'
|
35
|
+
if release >= 6
|
36
|
+
Cyclid.logger.debug 'is >= 6'
|
37
|
+
prepare_redhat(transport, env)
|
38
|
+
else
|
39
|
+
Cyclid.logger.debug 'is < 5'
|
40
|
+
prepare_redhat_5(transport, env)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register this plugin
|
45
|
+
register_plugin 'rhel'
|
46
|
+
|
47
|
+
include Helpers::Redhat
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_rel '../helpers/docker'
|
16
|
+
|
17
|
+
# Top level module for the core Cyclid code.
|
18
|
+
module Cyclid
|
19
|
+
# Module for the Cyclid API
|
20
|
+
module API
|
21
|
+
# Module for Cyclid Plugins
|
22
|
+
module Plugins
|
23
|
+
# Docker based transport
|
24
|
+
class DockerApi < Transport
|
25
|
+
include Cyclid::API::Plugins::Helpers::Docker
|
26
|
+
|
27
|
+
attr_reader :exit_code
|
28
|
+
|
29
|
+
def initialize(args = {})
|
30
|
+
args.symbolize_keys!
|
31
|
+
|
32
|
+
Cyclid.logger.debug "Docker Transport: args=#{args}"
|
33
|
+
|
34
|
+
# Configure Docker
|
35
|
+
config = load_docker_config(
|
36
|
+
Cyclid.config.plugins
|
37
|
+
)
|
38
|
+
::Docker.url = config[:api]
|
39
|
+
|
40
|
+
# Container name & a log target are required
|
41
|
+
return false unless args.include?(:host) && \
|
42
|
+
args.include?(:log)
|
43
|
+
|
44
|
+
@container = get_container(args[:host])
|
45
|
+
@log = args[:log]
|
46
|
+
|
47
|
+
ctx = args[:ctx]
|
48
|
+
@username = ctx[:username]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Execute a command via the Docker API
|
52
|
+
def exec(cmd, path = nil)
|
53
|
+
command = build_command(cmd, path, @env)
|
54
|
+
Cyclid.logger.debug "command=#{command}"
|
55
|
+
result = @container.exec(command, wait: 300) do |_stream, chunk|
|
56
|
+
@log.write chunk
|
57
|
+
end
|
58
|
+
@exit_code = result[2]
|
59
|
+
@exit_code.zero? ? true : false
|
60
|
+
end
|
61
|
+
|
62
|
+
# Copy data from local IO object to a remote file
|
63
|
+
def upload(io, path)
|
64
|
+
@container.store_file(path, io.read)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Copy data from remote file to local IO
|
68
|
+
def download(io, path)
|
69
|
+
result = @container.read_file(path)
|
70
|
+
io.write(result)
|
71
|
+
end
|
72
|
+
|
73
|
+
register_plugin('dockerapi')
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def build_command(cmd, path = nil, env = {})
|
78
|
+
command = []
|
79
|
+
if env
|
80
|
+
vars = env.map do |k, value|
|
81
|
+
key = k.upcase
|
82
|
+
key.gsub!(/\s/, '_')
|
83
|
+
"export #{key}=\"#{value}\""
|
84
|
+
end
|
85
|
+
command << vars.join(';')
|
86
|
+
end
|
87
|
+
|
88
|
+
command << "cd #{path}" if path
|
89
|
+
command << if @username == 'root'
|
90
|
+
cmd
|
91
|
+
else
|
92
|
+
"sudo -E #{cmd}"
|
93
|
+
end
|
94
|
+
['sh', '-l', '-c', command.join(';')]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/cyclid/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cyclid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kristian Van Der Vliet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -346,6 +346,20 @@ dependencies:
|
|
346
346
|
- - "~>"
|
347
347
|
- !ruby/object:Gem::Version
|
348
348
|
version: 0.8.6
|
349
|
+
- !ruby/object:Gem::Dependency
|
350
|
+
name: docker-api
|
351
|
+
requirement: !ruby/object:Gem::Requirement
|
352
|
+
requirements:
|
353
|
+
- - "~>"
|
354
|
+
- !ruby/object:Gem::Version
|
355
|
+
version: '1.33'
|
356
|
+
type: :runtime
|
357
|
+
prerelease: false
|
358
|
+
version_requirements: !ruby/object:Gem::Requirement
|
359
|
+
requirements:
|
360
|
+
- - "~>"
|
361
|
+
- !ruby/object:Gem::Version
|
362
|
+
version: '1.33'
|
349
363
|
description: The Cyclid CI system
|
350
364
|
email: contact@cyclid.io
|
351
365
|
executables:
|
@@ -392,12 +406,14 @@ files:
|
|
392
406
|
- app/cyclid/plugin_registry.rb
|
393
407
|
- app/cyclid/plugins.rb
|
394
408
|
- app/cyclid/plugins/action.rb
|
409
|
+
- app/cyclid/plugins/action/cobertura.rb
|
395
410
|
- app/cyclid/plugins/action/command.rb
|
396
411
|
- app/cyclid/plugins/action/email.rb
|
397
412
|
- app/cyclid/plugins/action/email/html.erb
|
398
413
|
- app/cyclid/plugins/action/email/text.erb
|
399
414
|
- app/cyclid/plugins/action/log.rb
|
400
415
|
- app/cyclid/plugins/action/script.rb
|
416
|
+
- app/cyclid/plugins/action/simplecov.rb
|
401
417
|
- app/cyclid/plugins/action/slack.rb
|
402
418
|
- app/cyclid/plugins/action/slack/note.erb
|
403
419
|
- app/cyclid/plugins/api.rb
|
@@ -411,15 +427,22 @@ files:
|
|
411
427
|
- app/cyclid/plugins/api/github/pull_request.rb
|
412
428
|
- app/cyclid/plugins/api/github/push.rb
|
413
429
|
- app/cyclid/plugins/builder.rb
|
430
|
+
- app/cyclid/plugins/builder/docker.rb
|
414
431
|
- app/cyclid/plugins/builder/google.rb
|
415
432
|
- app/cyclid/plugins/dispatcher.rb
|
416
433
|
- app/cyclid/plugins/dispatcher/local.rb
|
434
|
+
- app/cyclid/plugins/helpers/docker.rb
|
417
435
|
- app/cyclid/plugins/provisioner.rb
|
436
|
+
- app/cyclid/plugins/provisioner/centos.rb
|
418
437
|
- app/cyclid/plugins/provisioner/debian.rb
|
438
|
+
- app/cyclid/plugins/provisioner/fedora.rb
|
439
|
+
- app/cyclid/plugins/provisioner/redhat/helpers.rb
|
440
|
+
- app/cyclid/plugins/provisioner/rhel.rb
|
419
441
|
- app/cyclid/plugins/provisioner/ubuntu.rb
|
420
442
|
- app/cyclid/plugins/source.rb
|
421
443
|
- app/cyclid/plugins/source/git.rb
|
422
444
|
- app/cyclid/plugins/transport.rb
|
445
|
+
- app/cyclid/plugins/transport/dockerapi.rb
|
423
446
|
- app/cyclid/plugins/transport/ssh.rb
|
424
447
|
- app/cyclid/sinatra/api_helpers.rb
|
425
448
|
- app/cyclid/sinatra/auth_helpers.rb
|