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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# Copyright 2015-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
from __future__ import print_function
__metaclass__ = type
import json
import os
import shutil
import sys
from lpbuildd.debian import (
DebianBuildManager,
DebianBuildState,
get_build_path,
)
RETCODE_SUCCESS = 0
RETCODE_FAILURE_INSTALL = 200
RETCODE_FAILURE_BUILD = 201
class SnapBuildState(DebianBuildState):
BUILD_SNAP = "BUILD_SNAP"
class SnapBuildManager(DebianBuildManager):
"""Build a snap."""
initial_build_state = SnapBuildState.BUILD_SNAP
def __init__(self, slave, buildid, **kwargs):
super(SnapBuildManager, self).__init__(slave, buildid, **kwargs)
self.build_snap_path = os.path.join(self._slavebin, "buildsnap")
@property
def needs_sanitized_logs(self):
return True
def initiate(self, files, chroot, extra_args):
"""Initiate a build with a given set of files and chroot."""
self.build_path = get_build_path(
self.home, self._buildid, "chroot-autobuild", "build")
if os.path.isdir(self.build_path):
shutil.rmtree(self.build_path)
self.name = extra_args["name"]
self.branch = extra_args.get("branch")
self.git_repository = extra_args.get("git_repository")
self.git_path = extra_args.get("git_path")
self.proxy_url = extra_args.get("proxy_url")
self.revocation_endpoint = extra_args.get("revocation_endpoint")
super(SnapBuildManager, self).initiate(files, chroot, extra_args)
def status(self):
status_path = get_build_path(self.home, self._buildid, "status")
try:
with open(status_path) as status_file:
return json.load(status_file)
except IOError:
pass
except Exception as e:
print(
"Error deserialising status from buildsnap: %s" % e,
file=sys.stderr)
return {}
def doRunBuild(self):
"""Run the process to build the snap."""
args = [
"buildsnap",
"--build-id", self._buildid,
"--arch", self.arch_tag,
]
if self.proxy_url:
args.extend(["--proxy-url", self.proxy_url])
if self.revocation_endpoint:
args.extend(["--revocation-endpoint", self.revocation_endpoint])
if self.branch is not None:
args.extend(["--branch", self.branch])
if self.git_repository is not None:
args.extend(["--git-repository", self.git_repository])
if self.git_path is not None:
args.extend(["--git-path", self.git_path])
args.append(self.name)
self.runSubProcess(self.build_snap_path, args)
def iterate_BUILD_SNAP(self, retcode):
"""Finished building the snap."""
if retcode == RETCODE_SUCCESS:
self.gatherResults()
print("Returning build status: OK")
elif (retcode >= RETCODE_FAILURE_INSTALL and
retcode <= RETCODE_FAILURE_BUILD):
if not self.alreadyfailed:
self._slave.buildFail()
print("Returning build status: Build failed.")
self.alreadyfailed = True
else:
if not self.alreadyfailed:
self._slave.builderFail()
print("Returning build status: Builder failed.")
self.alreadyfailed = True
self.doReapProcesses(self._state)
def iterateReap_BUILD_SNAP(self, retcode):
"""Finished reaping after building the snap."""
self._state = DebianBuildState.UMOUNT
self.doUnmounting()
def gatherResults(self):
"""Gather the results of the build and add them to the file cache."""
output_path = os.path.join(self.build_path, self.name)
if not os.path.exists(output_path):
return
for entry in sorted(os.listdir(output_path)):
path = os.path.join(output_path, entry)
if os.path.islink(path):
continue
if entry.endswith(".snap") or entry.endswith(".manifest"):
self._slave.addWaitingFile(path)
|