cyclid 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|