/
build_source_container.py
102 lines (80 loc) · 3.76 KB
/
build_source_container.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""
Copyright (c) 2019 Red Hat, Inc
All rights reserved.
This software may be modified and distributed under the terms
of the BSD license. See the LICENSE file for details.
"""
import os
import subprocess
import tempfile
from atomic_reactor.build import BuildResult
from atomic_reactor.constants import (PLUGIN_SOURCE_CONTAINER_KEY, EXPORTED_SQUASHED_IMAGE_NAME,
IMAGE_TYPE_DOCKER_ARCHIVE, PLUGIN_FETCH_SOURCES_KEY)
from atomic_reactor.plugin import BuildStepPlugin
from atomic_reactor.util import get_exported_image_metadata
class SourceContainerPlugin(BuildStepPlugin):
"""
Build source container image using
https://github.com/containers/BuildSourceImage
"""
key = PLUGIN_SOURCE_CONTAINER_KEY
def export_image(self, image_output_dir):
output_path = os.path.join(tempfile.mkdtemp(), EXPORTED_SQUASHED_IMAGE_NAME)
cmd = ['skopeo', 'copy']
source_img = 'oci:{}'.format(image_output_dir)
dest_img = 'docker-archive:{}'.format(output_path)
cmd += [source_img, dest_img]
self.log.info("Calling: %s", ' '.join(cmd))
try:
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
self.log.error("failed to save docker-archive :\n%s", e.output)
raise
img_metadata = get_exported_image_metadata(output_path, IMAGE_TYPE_DOCKER_ARCHIVE)
self.workflow.exported_image_sequence.append(img_metadata)
def run(self):
"""Build image inside current environment.
Returns:
BuildResult
"""
fetch_sources_result = self.workflow.prebuild_results.get(PLUGIN_FETCH_SOURCES_KEY, {})
source_data_dir = fetch_sources_result.get('image_sources_dir')
remote_source_data_dir = fetch_sources_result.get('remote_sources_dir')
source_exists = source_data_dir and os.path.isdir(source_data_dir)
remote_source_exists = remote_source_data_dir and os.path.isdir(remote_source_data_dir)
if not source_exists and not remote_source_exists:
err_msg = "No SRPMs directory '{}' available".format(source_data_dir)
err_msg += "\nNo Remote source directory '{}' available".format(remote_source_data_dir)
self.log.error(err_msg)
return BuildResult(logs=err_msg, fail_reason=err_msg)
if source_exists and not os.listdir(source_data_dir):
self.log.warning("SRPMs directory '%s' is empty", source_data_dir)
if remote_source_exists and not os.listdir(remote_source_data_dir):
self.log.warning("Remote source directory '%s' is empty", remote_source_data_dir)
image_output_dir = tempfile.mkdtemp()
cmd = ['bsi', '-d']
drivers = []
if source_exists:
drivers.append('sourcedriver_rpm_dir')
cmd.append('-s')
cmd.append('{}'.format(source_data_dir))
if remote_source_exists:
drivers.append('sourcedriver_extra_src_dir')
cmd.append('-e')
cmd.append('{}'.format(remote_source_data_dir))
driver_str = ','.join(drivers)
cmd.insert(2, driver_str)
cmd.append('-o')
cmd.append('{}'.format(image_output_dir))
try:
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
self.log.error("BSI failed with output:\n%s", e.output)
return BuildResult(logs=e.output, fail_reason='BSI utility failed build source image')
self.log.debug("Build log:\n%s\n", output)
self.export_image(image_output_dir)
return BuildResult(
logs=output,
oci_image_path=image_output_dir,
skip_layer_squash=True
)