sle2docker 0.2.4 → 0.4.0
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/.gitignore +3 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +7 -0
- data/Changelog +12 -0
- data/Gemfile +2 -0
- data/README.md +94 -65
- data/Rakefile +12 -1
- data/bin/sle2docker +11 -2
- data/lib/sle2docker.rb +3 -2
- data/lib/sle2docker/cli.rb +32 -92
- data/lib/sle2docker/exceptions.rb +8 -1
- data/lib/sle2docker/prebuilt_image.rb +114 -0
- data/lib/sle2docker/version.rb +3 -3
- data/lib/templates/docker_build/dockerfile.erb +4 -0
- data/package/sle2docker.8.ronn +94 -53
- data/sle2docker.gemspec +24 -14
- data/test/prebuilt_image_test.rb +91 -0
- data/test/test_helper.rb +15 -10
- metadata +99 -24
- data/lib/sle2docker/builder.rb +0 -118
- data/lib/sle2docker/template.rb +0 -21
- data/lib/templates/SLE11SP2/config.sh +0 -49
- data/lib/templates/SLE11SP2/config.xml.erb +0 -51
- data/lib/templates/SLE11SP2/root/etc/resolv.conf +0 -0
- data/lib/templates/SLE11SP3/config.sh +0 -49
- data/lib/templates/SLE11SP3/config.xml.erb +0 -45
- data/lib/templates/SLE11SP3/root/etc/resolv.conf +0 -0
- data/lib/templates/SLE12/config.sh +0 -49
- data/lib/templates/SLE12/config.xml.erb +0 -44
- data/lib/templates/SLE12/root/etc/resolv.conf +0 -0
- data/test/builder_test.rb +0 -190
- data/test/fixtures/sle11sp3_config.xml +0 -45
- data/test/fixtures/sle11sp3_smt_auth_config.xml +0 -45
- data/test/fixtures/sle11sp3_smt_no_auth_https_config.xml +0 -45
- data/test/fixtures/sle11sp3_smt_no_auth_no_https_config.xml +0 -45
- data/test/template_test.rb +0 -30
@@ -1,9 +1,16 @@
|
|
1
1
|
module Sle2Docker
|
2
|
-
|
3
2
|
class TemplateNotFoundError < RuntimeError
|
4
3
|
end
|
5
4
|
|
6
5
|
class ConfigNotFoundError < RuntimeError
|
7
6
|
end
|
8
7
|
|
8
|
+
class PrebuiltImageNotFoundError < RuntimeError
|
9
|
+
end
|
10
|
+
|
11
|
+
class DockerTagError < RuntimeError
|
12
|
+
end
|
13
|
+
|
14
|
+
class PrebuiltImageVerificationError < RuntimeError
|
15
|
+
end
|
9
16
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Sle2Docker
|
2
|
+
# This class takes care of handling the pre-build images for
|
3
|
+
# SUSE Linux Enterprise
|
4
|
+
class PrebuiltImage
|
5
|
+
IMAGES_DIR = '/usr/share/suse-docker-images'
|
6
|
+
DOCKERFILE_TEMPLATE = File.join(
|
7
|
+
File.expand_path('../../templates/docker_build', __FILE__),
|
8
|
+
'dockerfile.erb')
|
9
|
+
|
10
|
+
attr_reader :image_id
|
11
|
+
|
12
|
+
def self.list
|
13
|
+
if File.exist?(PrebuiltImage::IMAGES_DIR)
|
14
|
+
Dir[File.join(IMAGES_DIR, '*.tar.xz')].map do |image|
|
15
|
+
File.basename(image, '.tar.xz')
|
16
|
+
end
|
17
|
+
else
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(image_name, options)
|
23
|
+
@image_name = image_name
|
24
|
+
@options = options
|
25
|
+
compute_repository_and_tag
|
26
|
+
end
|
27
|
+
|
28
|
+
def activated?
|
29
|
+
Docker::Image.exist?(image_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def activate
|
33
|
+
unless File.exist?(File.join(IMAGES_DIR, "#{@image_name}.tar.xz"))
|
34
|
+
fail PrebuiltImageNotFoundError,
|
35
|
+
"Cannot find pre-built image #{@image_name}"
|
36
|
+
end
|
37
|
+
|
38
|
+
verify_image
|
39
|
+
|
40
|
+
tmp_dir = prepare_docker_build_root
|
41
|
+
puts 'Activating image'
|
42
|
+
image = Docker::Image.build_from_dir(tmp_dir)
|
43
|
+
image.tag('repo' => @repository, 'tag' => @tag)
|
44
|
+
image.tag('repo' => @repository, 'tag' => 'latest')
|
45
|
+
ensure
|
46
|
+
FileUtils.rm_rf(tmp_dir) if tmp_dir && File.exist?(tmp_dir)
|
47
|
+
end
|
48
|
+
|
49
|
+
def prepare_docker_build_root
|
50
|
+
tmp_dir = Dir.mktmpdir("sle2docker-#{@image_name}-dockerfile")
|
51
|
+
|
52
|
+
create_dockerfile(tmp_dir)
|
53
|
+
copy_prebuilt_image(tmp_dir)
|
54
|
+
tmp_dir
|
55
|
+
end
|
56
|
+
|
57
|
+
# rubocop:disable Lint/UselessAssignment
|
58
|
+
def create_dockerfile(tmp_dir)
|
59
|
+
prebuilt_image = @image_name + '.tar.xz'
|
60
|
+
|
61
|
+
template = ERB.new(File.read(DOCKERFILE_TEMPLATE), nil, '<>')
|
62
|
+
.result(binding)
|
63
|
+
|
64
|
+
File.open(File.join(tmp_dir, 'Dockerfile'), 'w') do |file|
|
65
|
+
file.write(template)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# rubocop:enable Lint/UselessAssignment
|
69
|
+
|
70
|
+
def copy_prebuilt_image(tmp_dir)
|
71
|
+
prebuilt_image = File.join(IMAGES_DIR, "#{@image_name}.tar.xz")
|
72
|
+
destination = File.join(tmp_dir, "#{@image_name}.tar.xz")
|
73
|
+
FileUtils.cp(prebuilt_image, destination)
|
74
|
+
end
|
75
|
+
|
76
|
+
def rpm_package_name
|
77
|
+
file = File.join(IMAGES_DIR, "#{@image_name}.tar.xz")
|
78
|
+
package_name = `rpm -qf #{file}`
|
79
|
+
if $CHILD_STATUS.exitstatus != 0
|
80
|
+
fail PrebuiltImageVerificationError,
|
81
|
+
"Cannot find rpm package providing #{file}: #{package_name}"
|
82
|
+
end
|
83
|
+
package_name
|
84
|
+
end
|
85
|
+
|
86
|
+
def verify_image
|
87
|
+
puts 'Verifying integrity of the pre-built image'
|
88
|
+
package_name = rpm_package_name
|
89
|
+
verification = `rpm --verify #{package_name}`
|
90
|
+
if $CHILD_STATUS.exitstatus != 0
|
91
|
+
fail PrebuiltImageVerificationError,
|
92
|
+
"Verification of #{package_name} failed: #{verification}"
|
93
|
+
end
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def compute_repository_and_tag
|
100
|
+
# example of image name: sles12-docker.x86_64-1.0.0-Build7.2
|
101
|
+
regexp = /\A(?<name>.*)-docker\..*-(?<version>\d+\.\d+\.\d+)/
|
102
|
+
match = regexp.match(@image_name)
|
103
|
+
if match.nil?
|
104
|
+
fail DockerTagError,
|
105
|
+
"Cannot calculate the Docker tag for #{@image_name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
@repository = "suse/#{match['name']}"
|
109
|
+
@tag = match['version']
|
110
|
+
@image_id = "#{@repository}:#{@tag}"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/lib/sle2docker/version.rb
CHANGED
data/package/sle2docker.8.ronn
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
sle2docker(8) - Create SLE images for Docker
|
2
|
-
|
2
|
+
============================================
|
3
3
|
|
4
4
|
## SYNOPSIS
|
5
5
|
|
@@ -7,98 +7,139 @@ sle2docker(8) - Create SLE images for Docker
|
|
7
7
|
|
8
8
|
## DESCRIPTION
|
9
9
|
|
10
|
-
sle2docker is a convenience tool which
|
11
|
-
Docker.
|
10
|
+
sle2docker is a convenience tool which imports the pre-built SUSE Linux Enterprise
|
11
|
+
images for Docker.
|
12
12
|
|
13
|
-
The tool
|
13
|
+
The tool takes advantage of pre-built Docker images distributed by SUSE to
|
14
|
+
create the base Docker image that users can later customize using Docker's
|
15
|
+
integrated build system. The pre-built images are distributed by SUSE as RPMs.
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
Pre-built images do not have repositories configured but zypper will
|
18
|
+
automatically have access to the right repositories when the Docker host has a
|
19
|
+
SLE subscription that provides access to the product used in the image. For
|
20
|
+
more details read the "Customizing the images" section below.
|
17
21
|
|
18
|
-
|
22
|
+
Previous versions of the tool built the Docker images from KIWI templates
|
23
|
+
distributed by SUSE. This is no longer possible.
|
19
24
|
|
20
25
|
## REQUIREMENTS
|
21
26
|
|
27
|
+
Ruby is required to execute the sle2docker program.
|
28
|
+
|
22
29
|
Docker must be running on the system and the user invoking sle2docker must
|
23
30
|
have the rights to interact with it.
|
24
31
|
|
25
32
|
## USAGE
|
26
33
|
|
27
|
-
To
|
34
|
+
To list the available pre-built images use the following command:
|
28
35
|
|
29
|
-
`sle2docker
|
36
|
+
`sle2docker list`
|
30
37
|
|
31
|
-
|
38
|
+
To activate the pre-built image use the following command:
|
32
39
|
|
33
|
-
`sle2docker
|
40
|
+
`sle2docker activate IMAGE_NAME`
|
34
41
|
|
35
|
-
|
36
|
-
following command:
|
42
|
+
## Customizing the images
|
37
43
|
|
38
|
-
|
44
|
+
To create custom Docker images based on the official ones use
|
45
|
+
Docker's integrated build system.
|
39
46
|
|
40
|
-
## SUSE CUSTOMER CENTER INTEGRATION
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
The pre-built images do not have any repository configured. They
|
49
|
+
contain a zypper service(container-suseconnect) that
|
50
|
+
contacts either the SUSE Customer Center (SCC) or your Subscription
|
51
|
+
Management Tool (SMT) server according to the configuration of the SLE host
|
52
|
+
running the Docker container. The service obtains the list of repositories
|
53
|
+
available for the product used by the Docker image.
|
46
54
|
|
47
|
-
|
55
|
+
There is no need to add any credential to the Docker image because the machine
|
56
|
+
credentials are automatically injected into the container by the docker daemon.
|
57
|
+
These are injected inside of the `/run/secrets` directory. The same applies to
|
58
|
+
the `/etc/SUSEConnect` file of the host system, which is automatically injected
|
59
|
+
into the `/run/secrets`.
|
48
60
|
|
61
|
+
The contents of the `/run/secrets` directory are never committed to a Docker
|
62
|
+
image, hence there's no risk of leaking your credentials.
|
49
63
|
|
50
|
-
|
64
|
+
To obtain the list of repositories invoke:
|
51
65
|
|
52
|
-
|
53
|
-
Subscription Management Tool (SMT) instance:
|
66
|
+
`zypper ref -s`
|
54
67
|
|
55
|
-
|
68
|
+
This will automatically add all the repositories to your container. For each
|
69
|
+
repository added to the system a new file is going to be created under
|
70
|
+
`/etc/zypp/repos.d`. The URLs of these repositories include an access token
|
71
|
+
that automatically expires after 12 hours. To renew the token just call the
|
72
|
+
`zypper ref -s` command. It is totally fine, and secure, to commit these files
|
73
|
+
to a Docker image.
|
56
74
|
|
57
|
-
|
58
|
-
|
59
|
-
|
75
|
+
If you want to use a different set of credentials, place a custom
|
76
|
+
`/etc/zypp/credentials.d/SCCcredentials` with the machine credentials
|
77
|
+
having the subscription you want to use inside of the Docker image.
|
78
|
+
The same applies to the `SUSEConnect` file: if you want to override the one
|
79
|
+
available on the host system running the Docker container you have to add a
|
80
|
+
custom `/etc/SUSEConnect` file inside of the Docker image.
|
60
81
|
|
61
|
-
|
82
|
+
### Creating a custom SLE12 image
|
62
83
|
|
63
|
-
|
64
|
-
authentication. However it is possible to specify the access credentials by
|
65
|
-
using the following command:
|
84
|
+
This Dockerfile creates a simple Docker image based on SLE12:
|
66
85
|
|
67
|
-
|
86
|
+
```
|
87
|
+
FROM suse/sles12:latest
|
68
88
|
|
89
|
+
RUN zypper --gpg-auto-import-keys ref -s
|
90
|
+
RUN zypper -n in vim
|
91
|
+
```
|
69
92
|
|
70
|
-
|
71
|
-
|
93
|
+
When the Docker host machine is registered against an internal SMT
|
94
|
+
server the Docker image requires the ssl certificate used by SMT:
|
95
|
+
|
96
|
+
```
|
97
|
+
FROM suse/sles12:latest
|
98
|
+
|
99
|
+
# Import the crt file of our private SMT server
|
100
|
+
ADD http://smt.test.lan/smt.crt /etc/pki/trust/anchors/smt.crt
|
101
|
+
RUN update-ca-certificates
|
72
102
|
|
73
|
-
|
74
|
-
|
103
|
+
RUN zypper --gpg-auto-import-keys ref -s
|
104
|
+
RUN zypper -n in vim
|
105
|
+
```
|
75
106
|
|
107
|
+
### Creating a custom SLE11SP3 image
|
76
108
|
|
77
|
-
|
109
|
+
This Dockerfile creates a simple Docker image based on SLE12:
|
78
110
|
|
79
|
-
|
80
|
-
|
81
|
-
runtime.
|
111
|
+
```
|
112
|
+
FROM suse/sles11sp3:latest
|
82
113
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
`db45-utils` package to be installed on the host system; this
|
87
|
-
package is obsolete and is not available on SLE12.
|
114
|
+
RUN zypper --gpg-auto-import-keys ref -s
|
115
|
+
RUN zypper -n in vim
|
116
|
+
```
|
88
117
|
|
89
|
-
|
90
|
-
|
91
|
-
by starting from the official openSUSE image.
|
92
|
-
The `Dockerfile` used to create this image can be found inside of
|
93
|
-
the https://github.com/openSUSE/docker-containers repository.
|
118
|
+
When the Docker host machine is registered against an internal SMT
|
119
|
+
server the Docker image requires the ssl certificate used by SMT:
|
94
120
|
|
95
|
-
|
96
|
-
|
121
|
+
```
|
122
|
+
FROM suse/sles11sp3:latest
|
97
123
|
|
124
|
+
# Import the crt file of our private SMT server
|
125
|
+
ADD http://smt.test.lan/smt.crt /etc/ssl/certs/smt.pem
|
126
|
+
RUN c_rehash /etc/ssl/certs
|
127
|
+
|
128
|
+
RUN zypper --gpg-auto-import-keys ref -s
|
129
|
+
RUN zypper -n in vim
|
130
|
+
```
|
131
|
+
|
132
|
+
## EXIT CODES
|
133
|
+
sle2docker sets the following exit codes:
|
134
|
+
|
135
|
+
* 0: Success
|
136
|
+
* 1: Failure
|
98
137
|
|
99
138
|
## AUTHOR
|
100
139
|
Flavio Castelli <fcastelli@suse.com>
|
101
140
|
|
102
141
|
## LINKS
|
103
142
|
Project on GitHub: https://github.com/SUSE/sle2docker
|
104
|
-
|
143
|
+
SUSE documentation: https://www.suse.com/documentation/sles-12/dockerquick/data/dockerquick.html
|
144
|
+
Docker's integrated build system: http://docs.docker.com/reference/builder/
|
145
|
+
container-suseconnect: https://github.com/SUSE/container-suseconnect
|
data/sle2docker.gemspec
CHANGED
@@ -1,35 +1,45 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
-
require File.expand_path(
|
3
|
+
require File.expand_path('../lib/sle2docker/version', __FILE__)
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
6
|
+
s.name = 'sle2docker'
|
7
7
|
s.version = Sle2Docker::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ['Flavio Castelli']
|
10
10
|
s.email = ['fcastelli@suse.com']
|
11
|
-
s.homepage =
|
12
|
-
s.summary =
|
11
|
+
s.homepage = 'https://github.com/SUSE/sle2docker'
|
12
|
+
s.summary = 'Create SLE images for Docker'
|
13
13
|
|
14
14
|
s.description = <<EOD
|
15
|
-
sle2docker is a convenience tool which creates SUSE Linux Enterprise images
|
15
|
+
sle2docker is a convenience tool which creates SUSE Linux Enterprise images
|
16
|
+
for Docker.
|
16
17
|
|
17
18
|
The tool relies on KIWI and Docker itself to build the images.
|
18
19
|
|
19
|
-
Packages can be fetched either from Novell Customer Center (NCC) or from a
|
20
|
+
Packages can be fetched either from Novell Customer Center (NCC) or from a
|
21
|
+
local Subscription Management Tool (SMT).
|
20
22
|
|
21
23
|
Using DVD sources is currently unsupported.
|
22
24
|
EOD
|
23
25
|
s.licenses = ['MIT']
|
24
26
|
|
25
|
-
s.required_rubygems_version =
|
26
|
-
s.rubyforge_project =
|
27
|
-
|
28
|
-
s.add_runtime_dependency
|
29
|
-
s.
|
30
|
-
s.add_development_dependency
|
31
|
-
s.add_development_dependency
|
27
|
+
s.required_rubygems_version = '>= 1.3.6'
|
28
|
+
s.rubyforge_project = 'sle2docker'
|
29
|
+
|
30
|
+
s.add_runtime_dependency 'docker-api'
|
31
|
+
s.add_runtime_dependency 'thor'
|
32
|
+
s.add_development_dependency 'bundler'
|
33
|
+
s.add_development_dependency 'fakefs'
|
34
|
+
s.add_development_dependency 'minitest'
|
35
|
+
s.add_development_dependency 'mocha'
|
36
|
+
s.add_development_dependency 'rake'
|
37
|
+
s.add_development_dependency 'ronn'
|
38
|
+
s.add_development_dependency 'rubocop'
|
39
|
+
s.add_development_dependency 'yard'
|
32
40
|
s.files = `git ls-files`.split("\n")
|
33
|
-
s.executables = `git ls-files`.split("\n").map
|
41
|
+
s.executables = `git ls-files`.split("\n").map do |f|
|
42
|
+
f =~ /^bin\/(.*)/ ? $1 : nil
|
43
|
+
end.compact
|
34
44
|
s.require_path = 'lib'
|
35
45
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ClassLength, Style/Documentation, Metrics/LineLength, Style/MethodCallParentheses:
|
4
|
+
class PrebuiltImageTest < MiniTest::Test
|
5
|
+
describe 'PrebuiltImage' do
|
6
|
+
before do
|
7
|
+
@options = { password: '' }
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
FakeFS::FileSystem.clear
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'listing' do
|
15
|
+
it 'works when no pre-built image is available' do
|
16
|
+
actual = Sle2Docker::PrebuiltImage.list
|
17
|
+
expected = []
|
18
|
+
assert_equal expected, actual
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'lists the names of the available images' do
|
22
|
+
FakeFS do
|
23
|
+
expected = [
|
24
|
+
'sles11sp3-docker.x86_64-1.0.0-Build1.3',
|
25
|
+
'sles12-docker.x86_64-1.0.0-Build7.2'
|
26
|
+
]
|
27
|
+
|
28
|
+
FileUtils.mkdir_p(Sle2Docker::PrebuiltImage::IMAGES_DIR)
|
29
|
+
expected.each do |image|
|
30
|
+
FileUtils.touch(
|
31
|
+
File.join(
|
32
|
+
Sle2Docker::PrebuiltImage::IMAGES_DIR,
|
33
|
+
"#{image}.tar.xz"
|
34
|
+
)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
actual = Sle2Docker::PrebuiltImage.list
|
39
|
+
assert_equal expected, actual
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'activation' do
|
45
|
+
it 'creates a Dockerfile and builds the image' do
|
46
|
+
begin
|
47
|
+
image = 'sles12-docker.x86_64-1.0.0-Build7.2'
|
48
|
+
prebuilt_image = Sle2Docker::PrebuiltImage.new(image, @options)
|
49
|
+
expected = <<EOF
|
50
|
+
FROM scratch
|
51
|
+
MAINTAINER "Flavio Castelli <fcastelli@suse.com>"
|
52
|
+
|
53
|
+
ADD sles12-docker.x86_64-1.0.0-Build7.2.tar.xz /
|
54
|
+
EOF
|
55
|
+
|
56
|
+
tmp_dir = Dir.mktmpdir('sle2docker-test')
|
57
|
+
prebuilt_image.create_dockerfile(tmp_dir)
|
58
|
+
dockerfile = File.join(tmp_dir, 'Dockerfile')
|
59
|
+
|
60
|
+
assert File.exist?(dockerfile)
|
61
|
+
assert_equal(expected, File.read(dockerfile))
|
62
|
+
ensure
|
63
|
+
FileUtils.rm_rf(tmp_dir) if File.exist?(tmp_dir)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'triggers docker build' do
|
68
|
+
File.stubs(:exist?).returns(true)
|
69
|
+
tmp_dir = '/foo'
|
70
|
+
mocked_image = mock()
|
71
|
+
mocked_image.expects(:tag)
|
72
|
+
.with('repo' => 'suse/sles12', 'tag' => '1.0.0')
|
73
|
+
.once
|
74
|
+
mocked_image.expects(:tag)
|
75
|
+
.with('repo' => 'suse/sles12', 'tag' => 'latest')
|
76
|
+
.once
|
77
|
+
|
78
|
+
prebuilt_image = Sle2Docker::PrebuiltImage.new(
|
79
|
+
'sles12-docker.x86_64-1.0.0-Build7.2',
|
80
|
+
@options
|
81
|
+
)
|
82
|
+
prebuilt_image.expects(:prepare_docker_build_root).once.returns(tmp_dir)
|
83
|
+
prebuilt_image.expects(:verify_image).once
|
84
|
+
Docker::Image.expects(:build_from_dir).with(tmp_dir).once.returns(mocked_image)
|
85
|
+
FileUtils.expects(:rm_rf).with(tmp_dir).once
|
86
|
+
|
87
|
+
prebuilt_image.activate
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|