ostbuild: Flesh out chroot build to use ostbuild-user-chroot
One thing that made this take significantly longer than it might have otherwise is that we have to keep PWD "up to date" - otherwise we hit bugs in glibc's getcwd() implementation.
This commit is contained in:
parent
28a5714abd
commit
5f3b029638
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
bin_SCRIPTS += src/ostbuild/ostbuild-compile-one \
|
bin_SCRIPTS += src/ostbuild/ostbuild-compile-one \
|
||||||
src/ostbuild/ostbuild-compile-one-impl \
|
src/ostbuild/ostbuild-compile-one-impl \
|
||||||
|
src/ostbuild/ostbuild-chroot-compile-one \
|
||||||
|
src/ostbuild/ostbuild-chroot-compile-one-impl \
|
||||||
src/ostbuild/ostbuild-nice-and-log-output \
|
src/ostbuild/ostbuild-nice-and-log-output \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,4 +54,3 @@ ostree_pull_SOURCES = src/ostree/ot-main.h \
|
||||||
ostree_pull_CFLAGS = $(ostree_bin_shared_cflags) $(OT_DEP_SOUP_CFLAGS)
|
ostree_pull_CFLAGS = $(ostree_bin_shared_cflags) $(OT_DEP_SOUP_CFLAGS)
|
||||||
ostree_pull_LDADD = $(ostree_bin_shared_ldadd) $(OT_DEP_SOUP_LIBS)
|
ostree_pull_LDADD = $(ostree_bin_shared_ldadd) $(OT_DEP_SOUP_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,37 +17,79 @@
|
||||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
# Boston, MA 02111-1307, USA.
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
import os,sys,re,subprocess
|
import os,sys,re,subprocess,tempfile,shutil
|
||||||
|
import argparse
|
||||||
|
|
||||||
i=1
|
def get_build_env():
|
||||||
repo=sys.argv[i]
|
return {'HOME' : '/',
|
||||||
i += 1
|
'HOSTNAME' : 'ostbuild',
|
||||||
chroot_path=sys.argv[i]
|
'LANG': 'C',
|
||||||
i += 1
|
'PATH' : '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||||
args=sys.argv[i:]
|
'SHELL' : '/bin/bash',
|
||||||
|
'TERM' : 'vt100',
|
||||||
if os.getuid() != 0:
|
'TMPDIR' : '/tmp',
|
||||||
print "This program must be run as root."
|
'TZ': 'EST5EDT'
|
||||||
sys.exit(1)
|
}
|
||||||
|
|
||||||
rootdir=os.path.join(chroot_path, 'root')
|
|
||||||
|
|
||||||
if not os.path.isdir(rootdir):
|
|
||||||
print "Not a directory: %s" % (rootdir, )
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
builddir = os.path.join(rootdir, 'ostree-build')
|
|
||||||
if not os.path.isdir(builddir):
|
|
||||||
os.mkdir(builddir)
|
|
||||||
|
|
||||||
|
|
||||||
def run_in_chroot(args):
|
parser = argparse.ArgumentParser(description="Build a module in a given root")
|
||||||
proc_path=os.path.join(chroot_path, 'proc')
|
parser.add_argument('--repo')
|
||||||
subprocess.check_call(['mount', '-t', 'proc', 'proc', proc_path])
|
parser.add_argument('--resultdir')
|
||||||
|
parser.add_argument('--branch')
|
||||||
|
parser.add_argument('--debug-shell', type=bool)
|
||||||
|
|
||||||
try:
|
args = parser.parse_args()
|
||||||
subprocess.check_call(['chroot', chroot_path])
|
|
||||||
finally:
|
def log(m):
|
||||||
subprocess.call(['umount', proc_path])
|
sys.stdout.write(m)
|
||||||
|
sys.stdout.write('\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
tmpdir = tempfile.mkdtemp(prefix='ostree-chroot-compile-')
|
||||||
|
log("Using temporary directory: %s" % (tmpdir, ))
|
||||||
|
|
||||||
|
child_tmpdir=os.path.join(tmpdir, 'tmp')
|
||||||
|
os.mkdir(child_tmpdir)
|
||||||
|
|
||||||
|
rev = subprocess.check_output(['ostree', '--repo=' + args.repo, 'rev-parse', args.branch])
|
||||||
|
rev=rev.strip()
|
||||||
|
|
||||||
|
rootdir = os.path.join(tmpdir, 'root-' + rev)
|
||||||
|
subprocess.check_call(['ostree', '--repo=' + args.repo, 'checkout', '-U', rev, rootdir])
|
||||||
|
log("Checked out root: %s" % (rootdir, ))
|
||||||
|
|
||||||
|
builddir = os.path.join(rootdir, 'ostbuild');
|
||||||
|
os.mkdir(builddir)
|
||||||
|
os.mkdir(os.path.join(builddir, 'source'))
|
||||||
|
os.mkdir(os.path.join(builddir, 'results'))
|
||||||
|
|
||||||
|
# We need to search PATH here manually so we correctly pick up an
|
||||||
|
# ostree install in e.g. ~/bin even though we're going to set PATH
|
||||||
|
# below for our children inside the chroot.
|
||||||
|
ostbuild_user_chroot_path = None
|
||||||
|
for dirname in os.environ['PATH'].split(':'):
|
||||||
|
path = os.path.join(dirname, 'ostbuild-user-chroot')
|
||||||
|
if os.access(path, os.X_OK):
|
||||||
|
ostbuild_user_chroot_path = path
|
||||||
|
break
|
||||||
|
if ostbuild_user_chroot_path is None:
|
||||||
|
ostbuild_user_chroot_path = 'ostbuild-user-chroot'
|
||||||
|
|
||||||
|
child_args = [ostbuild_user_chroot_path, '--unshare-pid', '--unshare-net', '--unshare-ipc',
|
||||||
|
'--mount-readonly', '/',
|
||||||
|
'--mount-proc', '/proc',
|
||||||
|
'--mount-bind', '/dev', '/dev',
|
||||||
|
'--mount-bind', child_tmpdir, '/tmp',
|
||||||
|
'--mount-bind', os.getcwd(), '/ostbuild/source',
|
||||||
|
'--mount-bind', args.resultdir, '/ostbuild/results',
|
||||||
|
rootdir,
|
||||||
|
'/bin/sh']
|
||||||
|
if not args.debug_shell:
|
||||||
|
child_args += ['-c',
|
||||||
|
'cd /ostbuild/source && ostbuild-compile-one-impl OSTBUILD_RESULTDIR=/ostbuild/results'
|
||||||
|
]
|
||||||
|
log("Running: %r" % (child_args, ))
|
||||||
|
subprocess.check_call(child_args, env=get_build_env())
|
||||||
|
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
run_in_chroot(args)
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ ostbuild_resultdir=top_srcdir
|
||||||
|
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg.startswith('OSTBUILD_RESULTDIR='):
|
if arg.startswith('OSTBUILD_RESULTDIR='):
|
||||||
ostbuild_resultdir=arg[20:]
|
ostbuild_resultdir=arg[len('OSTBUILD_RESULTDIR='):]
|
||||||
elif arg.startswith('--'):
|
elif arg.startswith('--'):
|
||||||
configargs.append(arg)
|
configargs.append(arg)
|
||||||
else:
|
else:
|
||||||
|
|
@ -87,8 +87,22 @@ def fatal(msg):
|
||||||
def run_sync(args, cwd=None, env=None):
|
def run_sync(args, cwd=None, env=None):
|
||||||
log("running: %r" % (args,))
|
log("running: %r" % (args,))
|
||||||
f = open('/dev/null', 'r')
|
f = open('/dev/null', 'r')
|
||||||
|
# This dance is necessary because we want to keep the PWD
|
||||||
|
# environment variable up to date. Not doing so is a recipie
|
||||||
|
# for triggering edge conditions in pwd lookup.
|
||||||
|
if (cwd is not None) and (env is None or ('PWD' in env)):
|
||||||
|
if env is None:
|
||||||
|
env_copy = os.environ.copy()
|
||||||
|
else:
|
||||||
|
env_copy = env.copy()
|
||||||
|
if ('PWD' in env_copy) and (not cwd.startswith('/')):
|
||||||
|
env_copy['PWD'] = os.path.join(env_copy['PWD'], cwd)
|
||||||
|
else:
|
||||||
|
env_copy['PWD'] = cwd
|
||||||
|
else:
|
||||||
|
env_copy = env
|
||||||
proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
|
proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
|
||||||
close_fds=True, cwd=cwd, env=env)
|
close_fds=True, cwd=cwd, env=env_copy)
|
||||||
f.close()
|
f.close()
|
||||||
returncode = proc.wait()
|
returncode = proc.wait()
|
||||||
log("pid %d exited with code %d" % (proc.pid, returncode))
|
log("pid %d exited with code %d" % (proc.pid, returncode))
|
||||||
|
|
@ -167,7 +181,6 @@ def phase_bootstrap():
|
||||||
if bootstrap:
|
if bootstrap:
|
||||||
log("Detected bootstrap script: %s, using it" % (bootstrap, ))
|
log("Detected bootstrap script: %s, using it" % (bootstrap, ))
|
||||||
args = [bootstrap]
|
args = [bootstrap]
|
||||||
args.extend(configargs)
|
|
||||||
# Add NOCONFIGURE; GNOME style scripts use this
|
# Add NOCONFIGURE; GNOME style scripts use this
|
||||||
env = dict(os.environ)
|
env = dict(os.environ)
|
||||||
env['NOCONFIGURE'] = '1'
|
env['NOCONFIGURE'] = '1'
|
||||||
|
|
@ -187,24 +200,24 @@ def phase_configure():
|
||||||
shutil.copytree('.', '_build', symlinks=True,
|
shutil.copytree('.', '_build', symlinks=True,
|
||||||
ignore=shutil.ignore_patterns('_build'))
|
ignore=shutil.ignore_patterns('_build'))
|
||||||
use_builddir = False
|
use_builddir = False
|
||||||
builddir = '.'
|
|
||||||
else:
|
|
||||||
builddir = '_build'
|
|
||||||
|
|
||||||
if not use_builddir:
|
if use_builddir:
|
||||||
configdir = './'
|
builddir = '_build'
|
||||||
else:
|
|
||||||
configdir = os.getcwd()
|
|
||||||
builddir = builddir
|
|
||||||
log("Using build directory %r" % (builddir, ))
|
log("Using build directory %r" % (builddir, ))
|
||||||
if not os.path.isdir(builddir):
|
if not os.path.isdir(builddir):
|
||||||
os.mkdir(builddir)
|
os.mkdir(builddir)
|
||||||
|
|
||||||
configstatus = 'config.status'
|
configstatus = 'config.status'
|
||||||
if not os.path.exists(configstatus):
|
if not os.path.exists(configstatus):
|
||||||
args = [os.path.join(configdir, 'configure')]
|
if use_builddir:
|
||||||
|
args = ['../configure']
|
||||||
|
else:
|
||||||
|
args = ['./configure']
|
||||||
args.extend(configargs)
|
args.extend(configargs)
|
||||||
run_sync(args, cwd=builddir)
|
if use_builddir:
|
||||||
|
run_sync(args, cwd=builddir)
|
||||||
|
else:
|
||||||
|
run_sync(args)
|
||||||
else:
|
else:
|
||||||
log("Found %s, skipping configure" % (configstatus, ))
|
log("Found %s, skipping configure" % (configstatus, ))
|
||||||
phase_build(builddir=builddir)
|
phase_build(builddir=builddir)
|
||||||
|
|
@ -231,7 +244,7 @@ def phase_build(builddir=None):
|
||||||
|
|
||||||
phase_make_artifacts(builddir=builddir)
|
phase_make_artifacts(builddir=builddir)
|
||||||
|
|
||||||
def make_artifact(name, from_files, fakeroot_temp=None, tempdir=None, resultdir=None):
|
def make_artifact(name, from_files, tempdir=None, resultdir=None):
|
||||||
targz_name = name + '.tar.gz'
|
targz_name = name + '.tar.gz'
|
||||||
(fd,filelist_temp)=tempfile.mkstemp(prefix='ostree-filelist-%s' % (name, ))
|
(fd,filelist_temp)=tempfile.mkstemp(prefix='ostree-filelist-%s' % (name, ))
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
|
@ -242,15 +255,11 @@ def make_artifact(name, from_files, fakeroot_temp=None, tempdir=None, resultdir=
|
||||||
f.write(filename)
|
f.write(filename)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
f.close()
|
f.close()
|
||||||
if fakeroot_temp:
|
|
||||||
args = ['fakeroot', '-i', fakeroot_temp]
|
|
||||||
else:
|
|
||||||
args = []
|
|
||||||
if resultdir:
|
if resultdir:
|
||||||
result_path = os.path.join(resultdir, targz_name)
|
result_path = os.path.join(resultdir, targz_name)
|
||||||
else:
|
else:
|
||||||
result_path = targz_name
|
result_path = targz_name
|
||||||
args.extend(['tar', '-c', '-z', '-C', tempdir, '-f', result_path, '-T', filelist_temp])
|
args = ['tar', '-c', '-z', '-C', tempdir, '-f', result_path, '-T', filelist_temp]
|
||||||
run_sync(args)
|
run_sync(args)
|
||||||
log("created: %s" % (os.path.abspath (result_path), ))
|
log("created: %s" % (os.path.abspath (result_path), ))
|
||||||
|
|
||||||
|
|
@ -267,19 +276,9 @@ def phase_make_artifacts(builddir=None):
|
||||||
|
|
||||||
artifact_prefix='artifact-%s-%s,%s' % (build_target, basename, version)
|
artifact_prefix='artifact-%s-%s,%s' % (build_target, basename, version)
|
||||||
|
|
||||||
if os.getuid() != 0:
|
|
||||||
(fd,fakeroot_temp)=tempfile.mkstemp(prefix='ostree-fakeroot-%s-' % (basename,))
|
|
||||||
os.close(fd)
|
|
||||||
tempfiles.append(fakeroot_temp)
|
|
||||||
else:
|
|
||||||
fakeroot_temp = None
|
|
||||||
tempdir = tempfile.mkdtemp(prefix='ostree-build-%s-' % (basename,))
|
tempdir = tempfile.mkdtemp(prefix='ostree-build-%s-' % (basename,))
|
||||||
tempfiles.append(tempdir)
|
tempfiles.append(tempdir)
|
||||||
if fakeroot_temp is not None:
|
args = ['make', 'install', 'DESTDIR=' + tempdir]
|
||||||
args = ['fakeroot', '-s', fakeroot_temp]
|
|
||||||
else:
|
|
||||||
args = []
|
|
||||||
args.extend(['make', 'install', 'DESTDIR=' + tempdir])
|
|
||||||
run_sync(args, cwd=builddir)
|
run_sync(args, cwd=builddir)
|
||||||
|
|
||||||
devel_files = set()
|
devel_files = set()
|
||||||
|
|
@ -302,8 +301,8 @@ def phase_make_artifacts(builddir=None):
|
||||||
os.chdir(oldpwd)
|
os.chdir(oldpwd)
|
||||||
|
|
||||||
if devel_files:
|
if devel_files:
|
||||||
make_artifact(artifact_prefix + '-devel', devel_files, fakeroot_temp=fakeroot_temp, tempdir=tempdir, resultdir=ostbuild_resultdir)
|
make_artifact(artifact_prefix + '-devel', devel_files, tempdir=tempdir, resultdir=ostbuild_resultdir)
|
||||||
make_artifact(artifact_prefix + '-runtime', runtime_files, fakeroot_temp=fakeroot_temp, tempdir=tempdir, resultdir=ostbuild_resultdir)
|
make_artifact(artifact_prefix + '-runtime', runtime_files, tempdir=tempdir, resultdir=ostbuild_resultdir)
|
||||||
|
|
||||||
def phase_complete():
|
def phase_complete():
|
||||||
for tmpname in tempfiles:
|
for tmpname in tempfiles:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue