| |
@@ -37,6 +37,7 @@
|
| |
self.conn = SSHConnection(user=self.opts.build_user, host=self.hostname, config_file=self.opts.ssh.builder_config)
|
| |
|
| |
self.module_dist_tag = self._load_module_dist_tag()
|
| |
+ self._build_pid = None
|
| |
|
| |
def _load_module_dist_tag(self):
|
| |
module_md_filepath = os.path.join(self.job.destdir, self.job.chroot, "module_md.yaml")
|
| |
@@ -65,9 +66,12 @@
|
| |
if self._remote_tempdir:
|
| |
return self._remote_tempdir
|
| |
|
| |
- tempdir_path = "{0}/{1}-{2}".format(
|
| |
- self._remote_basedir, "mockremote", self.job.task_id)
|
| |
- self._run_ssh_cmd("/bin/mkdir -m 755 -p {0}".format(tempdir_path))
|
| |
+ if self.opts.standalone_builder:
|
| |
+ tempdir_path = "/var/lib/copr-builder"
|
| |
+ else:
|
| |
+ tempdir_path = "{0}/{1}-{2}".format(
|
| |
+ self._remote_basedir, "mockremote", self.job.task_id)
|
| |
+ self._run_ssh_cmd("/bin/mkdir -m 755 -p {0}".format(tempdir_path))
|
| |
|
| |
self._remote_tempdir = tempdir_path
|
| |
return self._remote_tempdir
|
| |
@@ -98,6 +102,9 @@
|
| |
return out, err
|
| |
|
| |
def _get_remote_results_dir(self):
|
| |
+ if self.opts.standalone_builder:
|
| |
+ return os.path.join(self.tempdir, 'results')
|
| |
+
|
| |
if any(x is None for x in [self.remote_build_dir,
|
| |
self.remote_pkg_name,
|
| |
self.job.chroot]):
|
| |
@@ -232,9 +239,18 @@
|
| |
|
| |
@property
|
| |
def livelog_name(self):
|
| |
+ if self.opts.standalone_builder:
|
| |
+ return "/var/lib/copr-builder/live-log"
|
| |
return pipes.quote('/tmp/{}.log'.format(self.job.task_id))
|
| |
|
| |
- def run_mockchain_async(self):
|
| |
+ def run_async_build(self):
|
| |
+ if self.opts.standalone_builder:
|
| |
+ cmd = self._copr_builder_cmd()
|
| |
+ pid, _ = self._run_ssh_cmd(cmd)
|
| |
+ self._build_pid =int(pid.strip())
|
| |
+ return
|
| |
+
|
| |
+
|
| |
buildcmd = "timeout {} {} -r {} -l {} ".format(
|
| |
self.timeout, mockchain, pipes.quote(self.get_chroot_config_path(self.job.chroot)),
|
| |
pipes.quote(self.remote_build_dir))
|
| |
@@ -260,10 +276,10 @@
|
| |
# on std{out,err} which means that it's output are not line-buffered
|
| |
# (which wouldn't be very useful live-log), so let's use `unbuffer`
|
| |
# from expect.rpm to allocate _persistent_ server-side pseudo-terminal
|
| |
- buildcmd_async = 'trap "" SIGHUP; unbuffer {buildcmd} &>{livelog} &'.format(
|
| |
+ buildcmd_async = 'trap "" SIGHUP; unbuffer {buildcmd} &>{livelog} & echo !$'.format(
|
| |
livelog=self.livelog_name, buildcmd=buildcmd)
|
| |
-
|
| |
- self._run_ssh_cmd(buildcmd_async)
|
| |
+ pid, _ = self._run_ssh_cmd(buildcmd_async)
|
| |
+ self._build_pid =int(pid.strip())
|
| |
|
| |
def setup_pubsub_handler(self):
|
| |
|
| |
@@ -298,20 +314,56 @@
|
| |
# buildcmd = self.gen_mockchain_command(dest)
|
| |
#
|
| |
|
| |
- def attach_to_build(self):
|
| |
+ @property
|
| |
+ def build_pid(self):
|
| |
+ if self._build_pid:
|
| |
+ return self._build_pid
|
| |
try:
|
| |
pidof_cmd = "/usr/bin/pgrep -o -u {user} {command}".format(
|
| |
user=self.opts.build_user, command="mockchain")
|
| |
+
|
| |
+ if self.opts.standalone_builder:
|
| |
+ pidof_cmd = "cat /var/lib/copr-builder/pid"
|
| |
+
|
| |
out, _ = self._run_ssh_cmd(pidof_cmd)
|
| |
- except RemoteCmdError:
|
| |
+ except:
|
| |
+ return None
|
| |
+
|
| |
+ return int(out.strip())
|
| |
+
|
| |
+
|
| |
+ def _copr_builder_cmd(self):
|
| |
+ template = 'copr-builder --config {config} --copr {copr} ' \
|
| |
+ + '--package {package} --revision {revision} ' \
|
| |
+ + '--host-resolv {net} --timeout {timeout} ' \
|
| |
+ + '--chroot {chroot} --detached '
|
| |
+
|
| |
+ # Repo name like <user/group>/<copr>/<package>
|
| |
+ git_repo_path = self.job.git_repo.split('/')
|
| |
+
|
| |
+ copr = '{0}/{1}'.format(git_repo_path[0], git_repo_path[1])
|
| |
+ package = git_repo_path[2]
|
| |
+
|
| |
+ return template.format(
|
| |
+ config=self.opts.standalone_builder_config,
|
| |
+ copr=copr,
|
| |
+ package=package,
|
| |
+ revision=self.job.git_hash,
|
| |
+ net="True" if self.job.enable_net else "False",
|
| |
+ chroot=self.job.chroot,
|
| |
+ timeout=self.timeout,
|
| |
+ )
|
| |
+
|
| |
+ def attach_to_build(self):
|
| |
+ if not self.build_pid:
|
| |
self.log.info("Build is not running. Continuing...")
|
| |
return
|
| |
|
| |
ensure_dir_exists(self.job.results_dir, self.log)
|
| |
live_log = os.path.join(self.job.results_dir, 'mockchain-live.log')
|
| |
|
| |
- live_cmd = '/usr/bin/tail -f --pid={pid} {log}'.format(
|
| |
- pid=out.strip(), log=self.livelog_name)
|
| |
+ live_cmd = '/usr/bin/tail -n +0 -f --pid={pid} {log}'.format(
|
| |
+ pid=self.build_pid, log=self.livelog_name)
|
| |
|
| |
self.log.info("Attaching to live build log: " + live_cmd)
|
| |
with open(live_log, 'w') as logfile:
|
| |
@@ -320,14 +372,15 @@
|
| |
|
| |
|
| |
def build(self):
|
| |
- # make mock config
|
| |
- self.setup_mock_chroot_config()
|
| |
+ if not self.opts.standalone_builder:
|
| |
+ # make mock config
|
| |
+ self.setup_mock_chroot_config()
|
| |
|
| |
- # download the package to the builder
|
| |
- self.download_job_pkg_to_builder()
|
| |
+ # download the package to the builder
|
| |
+ self.download_job_pkg_to_builder()
|
| |
|
| |
# run the build
|
| |
- self.run_mockchain_async()
|
| |
+ self.run_async_build()
|
| |
|
| |
# attach to building output
|
| |
self.attach_to_build()
|
| |
@@ -375,6 +428,11 @@
|
| |
self.rsync_call(self._get_remote_config_dir(), target_path)
|
| |
|
| |
def check(self):
|
| |
+ if self.opts.standalone_builder:
|
| |
+ # We simply expect that 'copr-builder' package is installed on the
|
| |
+ # builder machine.
|
| |
+ return
|
| |
+
|
| |
# do check of host
|
| |
try:
|
| |
# requires name resolve facility
|
| |
When copr-be.conf contains this snippet ..
.. then instead of controlling all the build peculiarities
manually from backend, the build is fully controlled builder-side,
while the build process logic is concentrated in one, easily
reproducible command:
This extremely simplifies debugging when something goes wrong, but
it is also the first step towards "heterogeneous sets of builders"
feature https://bugzilla.redhat.com/show_bug.cgi?id=1334701
The builder VMs just need to have installed package 'copr-builder'.