mirror of
https://github.com/openSUSE/osc.git
synced 2025-01-16 10:36:13 +01:00
Merge pull request #501 from adrianschroeter/master
osc shell/chroot is now handled via build script (working for chroot …
This commit is contained in:
commit
348787d47b
4
NEWS
4
NEWS
@ -1,3 +1,7 @@
|
|||||||
|
0.167
|
||||||
|
- osc shell/chroot/wipe is now handled via build script (working for chroot and KVM only atm)
|
||||||
|
- osc build --vm-type=qemu support for cross architecture builds
|
||||||
|
|
||||||
0.166.2
|
0.166.2
|
||||||
- Don't enforce password reuse (boo#1156501)
|
- Don't enforce password reuse (boo#1156501)
|
||||||
- Config option check_for_requests_on_action is now
|
- Config option check_for_requests_on_action is now
|
||||||
|
19
osc/build.py
19
osc/build.py
@ -46,15 +46,6 @@ change_personality = {
|
|||||||
'sparcv8': 'linux32',
|
'sparcv8': 'linux32',
|
||||||
}
|
}
|
||||||
|
|
||||||
# FIXME: qemu_can_build should not be needed anymore since OBS 2.3
|
|
||||||
qemu_can_build = [ 'armv4l', 'armv5el', 'armv5l', 'armv6l', 'armv7l', 'armv6el', 'armv6hl', 'armv7el', 'armv7hl', 'armv8el',
|
|
||||||
'sh4', 'mips', 'mipsel',
|
|
||||||
'ppc', 'ppc64',
|
|
||||||
's390', 's390x',
|
|
||||||
'sparc64v', 'sparcv9v', 'sparcv9', 'sparcv8', 'sparc',
|
|
||||||
'hppa',
|
|
||||||
]
|
|
||||||
|
|
||||||
can_also_build = {
|
can_also_build = {
|
||||||
'aarch64': ['aarch64'], # only needed due to used heuristics in build parameter evaluation
|
'aarch64': ['aarch64'], # only needed due to used heuristics in build parameter evaluation
|
||||||
'armv6l': [ 'armv4l', 'armv5l', 'armv6l', 'armv5el', 'armv6el' ],
|
'armv6l': [ 'armv4l', 'armv5l', 'armv6l', 'armv5el', 'armv6el' ],
|
||||||
@ -649,6 +640,8 @@ def main(apiurl, opts, argv):
|
|||||||
pac = pac + ":" + opts.multibuild_package
|
pac = pac + ":" + opts.multibuild_package
|
||||||
if opts.shell:
|
if opts.shell:
|
||||||
buildargs.append("--shell")
|
buildargs.append("--shell")
|
||||||
|
if opts.wipe:
|
||||||
|
buildargs.append("--wipe")
|
||||||
|
|
||||||
orig_build_root = config['build-root']
|
orig_build_root = config['build-root']
|
||||||
# make it possible to override configuration of the rc file
|
# make it possible to override configuration of the rc file
|
||||||
@ -877,13 +870,9 @@ def main(apiurl, opts, argv):
|
|||||||
if hostarch != bi.hostarch and not bi.hostarch in can_also_build.get(hostarch, []):
|
if hostarch != bi.hostarch and not bi.hostarch in can_also_build.get(hostarch, []):
|
||||||
print('Error: hostarch \'%s\' is required.' % (bi.hostarch), file=sys.stderr)
|
print('Error: hostarch \'%s\' is required.' % (bi.hostarch), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
elif hostarch != bi.buildarch:
|
elif hostarch != bi.buildarch and vm_type != "emulator" and vm_type != "qemu":
|
||||||
if not bi.buildarch in can_also_build.get(hostarch, []):
|
if not bi.buildarch in can_also_build.get(hostarch, []):
|
||||||
# OBSOLETE: qemu_can_build should not be needed anymore since OBS 2.3
|
print('WARNING: It is guessed to build on hostarch \'%s\' for \'%s\' via QEMU user emulation.' % (hostarch, bi.buildarch), file=sys.stderr)
|
||||||
if vm_type != "emulator" and not bi.buildarch in qemu_can_build:
|
|
||||||
print('Error: hostarch \'%s\' cannot build \'%s\'.' % (hostarch, bi.buildarch), file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
print('WARNING: It is guessed to build on hostarch \'%s\' for \'%s\' via QEMU.' % (hostarch, bi.buildarch), file=sys.stderr)
|
|
||||||
|
|
||||||
rpmlist_prefers = []
|
rpmlist_prefers = []
|
||||||
if prefer_pkgs:
|
if prefer_pkgs:
|
||||||
|
@ -6292,7 +6292,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
@cmdln.option('--build-opt', metavar='OPT', action='append',
|
@cmdln.option('--build-opt', metavar='OPT', action='append',
|
||||||
help='pass option OPT to the build command')
|
help='pass option OPT to the build command')
|
||||||
@cmdln.option('--userootforbuild', action='store_true',
|
@cmdln.option('--userootforbuild', action='store_true',
|
||||||
help='Run build as root. The default is to build as '
|
help='Run build or shell as root. The default is to build as '
|
||||||
'unprivileged user. Note that a line "# norootforbuild" '
|
'unprivileged user. Note that a line "# norootforbuild" '
|
||||||
'in the spec file will invalidate this option.')
|
'in the spec file will invalidate this option.')
|
||||||
@cmdln.option('--build-uid', metavar='uid:gid|"caller"',
|
@cmdln.option('--build-uid', metavar='uid:gid|"caller"',
|
||||||
@ -6328,14 +6328,21 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
help='only fetch packages from the api')
|
help='only fetch packages from the api')
|
||||||
@cmdln.option('--oldpackages', metavar='DIR',
|
@cmdln.option('--oldpackages', metavar='DIR',
|
||||||
help='take previous build from DIR (special values: _self, _link)')
|
help='take previous build from DIR (special values: _self, _link)')
|
||||||
|
@cmdln.option('--wipe', action='store_true',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
@cmdln.option('--shell', action='store_true',
|
@cmdln.option('--shell', action='store_true',
|
||||||
help=SUPPRESS_HELP)
|
help=SUPPRESS_HELP)
|
||||||
|
@cmdln.option('--shell-cmd', metavar='COMMAND',
|
||||||
|
help='run specified command instead of bash')
|
||||||
@cmdln.option('--host', metavar='HOST',
|
@cmdln.option('--host', metavar='HOST',
|
||||||
help='perform the build on a remote server - user@server:~/remote/directory')
|
help='perform the build on a remote server - user@server:~/remote/directory')
|
||||||
@cmdln.option('--trust-all-projects', action='store_true',
|
@cmdln.option('--trust-all-projects', action='store_true',
|
||||||
help='trust packages from all projects')
|
help='trust packages from all projects')
|
||||||
@cmdln.option('--nopreinstallimage', '--no-preinstallimage', action='store_true',
|
@cmdln.option('--nopreinstallimage', '--no-preinstallimage', action='store_true',
|
||||||
help='Do not use preinstall images for creating the build root.')
|
help='Do not use preinstall images for creating the build root.')
|
||||||
|
@cmdln.alias('chroot')
|
||||||
|
@cmdln.alias('shell')
|
||||||
|
@cmdln.alias('wipe')
|
||||||
def do_build(self, subcmd, opts, *args):
|
def do_build(self, subcmd, opts, *args):
|
||||||
"""${cmd_name}: Build a package on your local machine
|
"""${cmd_name}: Build a package on your local machine
|
||||||
|
|
||||||
@ -6362,6 +6369,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
osc build [OPTS] --alternative-project openSUSE:10.3 standard i586 BUILD_DESCR
|
osc build [OPTS] --alternative-project openSUSE:10.3 standard i586 BUILD_DESCR
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
|
osc build [OPTS] # will try to guess a build environement
|
||||||
osc build [OPTS] REPOSITORY ARCH BUILD_DESCR
|
osc build [OPTS] REPOSITORY ARCH BUILD_DESCR
|
||||||
osc build [OPTS] REPOSITORY ARCH
|
osc build [OPTS] REPOSITORY ARCH
|
||||||
osc build [OPTS] REPOSITORY (ARCH = hostarch, BUILD_DESCR is detected automatically)
|
osc build [OPTS] REPOSITORY (ARCH = hostarch, BUILD_DESCR is detected automatically)
|
||||||
@ -6369,6 +6377,28 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
osc build [OPTS] BUILD_DESCR (REPOSITORY = build_repository (config option), ARCH = hostarch)
|
osc build [OPTS] BUILD_DESCR (REPOSITORY = build_repository (config option), ARCH = hostarch)
|
||||||
osc build [OPTS] (REPOSITORY = build_repository (config option), ARCH = hostarch, BUILD_DESCR is detected automatically)
|
osc build [OPTS] (REPOSITORY = build_repository (config option), ARCH = hostarch, BUILD_DESCR is detected automatically)
|
||||||
|
|
||||||
|
For debugging purposes you can run after a build the following to jump inside of of
|
||||||
|
the build environemnt:
|
||||||
|
|
||||||
|
osc shell [OPTS] REPOSITORY ARCH
|
||||||
|
|
||||||
|
OPTS may be
|
||||||
|
|
||||||
|
--noinit # for faster run
|
||||||
|
--shell-cmd=COMMAND
|
||||||
|
|
||||||
|
To clean up the build environment run
|
||||||
|
|
||||||
|
osc wipe [OPTS]
|
||||||
|
osc wipe [OPTS] REPOSITORY ARCH
|
||||||
|
|
||||||
|
You may set the used VM type in oscrc already, but you can also overwrite it for example
|
||||||
|
with
|
||||||
|
|
||||||
|
--vm-type=chroot # for faster, but uncleaner and unsecure build
|
||||||
|
--vm-type=kvm # for clean and secure build
|
||||||
|
--vm-type=qemu # for slow cross architecture build using system emulator
|
||||||
|
|
||||||
# Note:
|
# Note:
|
||||||
# Configuration can be overridden by envvars, e.g.
|
# Configuration can be overridden by envvars, e.g.
|
||||||
# OSC_SU_WRAPPER overrides the setting of su-wrapper.
|
# OSC_SU_WRAPPER overrides the setting of su-wrapper.
|
||||||
@ -6388,6 +6418,12 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
if opts.debuginfo and opts.disable_debuginfo:
|
if opts.debuginfo and opts.disable_debuginfo:
|
||||||
raise oscerr.WrongOptions('osc: --debuginfo and --disable-debuginfo are mutual exclusive')
|
raise oscerr.WrongOptions('osc: --debuginfo and --disable-debuginfo are mutual exclusive')
|
||||||
|
|
||||||
|
if subcmd == 'chroot' or subcmd == 'shell':
|
||||||
|
opts.shell = True
|
||||||
|
|
||||||
|
if subcmd == 'wipe':
|
||||||
|
opts.wipe = True
|
||||||
|
|
||||||
if len(args) > 3:
|
if len(args) > 3:
|
||||||
raise oscerr.WrongArgs('Too many arguments')
|
raise oscerr.WrongArgs('Too many arguments')
|
||||||
|
|
||||||
@ -6585,148 +6621,6 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
return build_ret
|
return build_ret
|
||||||
|
|
||||||
|
|
||||||
@cmdln.option('--local-package', action='store_true',
|
|
||||||
help='package doesn\'t exist on the server')
|
|
||||||
@cmdln.option('--alternative-project', metavar='PROJECT',
|
|
||||||
help='specify the used build target project')
|
|
||||||
@cmdln.option('--noinit', '--no-init', action='store_true',
|
|
||||||
help='do not guess/verify specified repository')
|
|
||||||
@cmdln.option('-r', '--login-as-root', action='store_true',
|
|
||||||
help='login as root instead of abuild')
|
|
||||||
@cmdln.option('--root', metavar='ROOT',
|
|
||||||
help='Path to the buildroot')
|
|
||||||
@cmdln.option('-o', '--offline', action='store_true',
|
|
||||||
help='Use cached data without contacting the api server')
|
|
||||||
@cmdln.option('--wipe', action='store_true',
|
|
||||||
help='Delete the build root instead of chrooting into it')
|
|
||||||
@cmdln.option('-f', '--force', action='store_true',
|
|
||||||
help='Do not ask confirmation for wipe')
|
|
||||||
def do_chroot(self, subcmd, opts, *args):
|
|
||||||
"""${cmd_name}: opens a shell inside of the build root
|
|
||||||
|
|
||||||
chroot into the build root for the given repository, arch and build description
|
|
||||||
(NOTE: this command does not work if a VM is used)
|
|
||||||
|
|
||||||
usage:
|
|
||||||
osc chroot [OPTS] REPOSITORY ARCH BUILD_DESCR
|
|
||||||
osc chroot [OPTS] REPOSITORY (ARCH = hostarch, BUILD_DESCR is detected automatically)
|
|
||||||
osc chroot [OPTS] ARCH (REPOSITORY = build_repository (config option), BUILD_DESCR is detected automatically)
|
|
||||||
osc chroot [OPTS] BUILD_DESCR (REPOSITORY = build_repository (config option), ARCH = hostarch)
|
|
||||||
osc chroot [OPTS] (REPOSITORY = build_repository (config option), ARCH = hostarch, BUILD_DESCR is detected automatically)
|
|
||||||
${cmd_option_list}
|
|
||||||
"""
|
|
||||||
|
|
||||||
if len(args) > 3:
|
|
||||||
raise oscerr.WrongArgs('Too many arguments')
|
|
||||||
if conf.config['build-type'] and conf.config['build-type'] != "lxc":
|
|
||||||
print('Not implemented for VMs', file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
user = 'abuild'
|
|
||||||
if opts.login_as_root:
|
|
||||||
user = 'root'
|
|
||||||
buildroot = opts.root
|
|
||||||
if buildroot is None:
|
|
||||||
repository, arch, descr = self.parse_repoarchdescr(args, opts.noinit or opts.offline, opts.alternative_project)
|
|
||||||
project = opts.alternative_project or store_read_project('.')
|
|
||||||
if opts.local_package:
|
|
||||||
package = os.path.splitext(os.path.basename(descr))[0]
|
|
||||||
else:
|
|
||||||
package = store_read_package('.')
|
|
||||||
apihost = urlsplit(self.get_api_url())[1]
|
|
||||||
if buildroot is None:
|
|
||||||
buildroot = os.environ.get('OSC_BUILD_ROOT', conf.config['build-root']) \
|
|
||||||
% {'repo': repository, 'arch': arch, 'project': project, 'package': package, 'apihost': apihost}
|
|
||||||
if not os.path.isdir(buildroot):
|
|
||||||
raise oscerr.OscIOError(None, '\'%s\' is not a directory' % buildroot)
|
|
||||||
|
|
||||||
suwrapper = os.environ.get('OSC_SU_WRAPPER', conf.config['su-wrapper'])
|
|
||||||
|
|
||||||
# Wipe build root if --wipe was given
|
|
||||||
if opts.wipe:
|
|
||||||
sucmd = suwrapper.split()
|
|
||||||
cmd = [ conf.config['build-cmd'], '--root='+buildroot, '--wipe' ]
|
|
||||||
if sucmd[0] == 'su':
|
|
||||||
if sucmd[-1] == '-c':
|
|
||||||
sucmd.pop()
|
|
||||||
cmd = sucmd + ['-s', cmd[0], 'root', '--' ] + cmd[1:]
|
|
||||||
else:
|
|
||||||
cmd = sucmd + cmd
|
|
||||||
|
|
||||||
if opts.force:
|
|
||||||
sys.exit(run_external(cmd[0], *cmd[1:]))
|
|
||||||
else:
|
|
||||||
# Confirm delete
|
|
||||||
print("Really wipe '%s'? [y/N]: " % buildroot)
|
|
||||||
choice = raw_input().lower()
|
|
||||||
if choice == 'y':
|
|
||||||
sys.exit(run_external(cmd[0], *cmd[1:]))
|
|
||||||
else:
|
|
||||||
print('Aborting')
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# Normal chroot
|
|
||||||
sucmd = suwrapper.split()[0]
|
|
||||||
suargs = ' '.join(suwrapper.split()[1:])
|
|
||||||
if suwrapper.startswith('su '):
|
|
||||||
mntproc = [sucmd, '%s mount -n -tproc none %s/proc' % (suargs, buildroot)]
|
|
||||||
mntsys = [sucmd, '%s mount -n -tsysfs none %s/sys' % (suargs, buildroot)]
|
|
||||||
mntdevpts = [sucmd, '%s mount -n -tdevpts -omode=0620,gid=5 none %s/dev/pts' % (suargs, buildroot)]
|
|
||||||
umntproc = [sucmd, '%s umount %s/proc' % (suargs, buildroot)]
|
|
||||||
umntsys = [sucmd, '%s umount %s/sys' % (suargs, buildroot)]
|
|
||||||
umntdevpts = [sucmd, '%s umount %s/devpts' % (suargs, buildroot)]
|
|
||||||
cmd = [sucmd, '%s chroot "%s" su - %s' % (suargs, buildroot, user)]
|
|
||||||
else:
|
|
||||||
mntproc = [sucmd, 'mount', '-n', '-tproc' , 'none', '%s/proc' % buildroot]
|
|
||||||
mntsys = [sucmd, 'mount', '-n', '-tsysfs' , 'none', '%s/sys' % buildroot]
|
|
||||||
mntdevpts = [sucmd, 'mount', '-n', '-tdevpts' , '-omode=0620,gid=5', 'none', '%s/dev/pts' % buildroot]
|
|
||||||
umntproc = [sucmd, 'umount', '%s/proc' % buildroot]
|
|
||||||
umntsys = [sucmd, 'umount', '%s/sys' % buildroot]
|
|
||||||
umntdevpts = [sucmd, 'umount', '%s/dev/pts' % buildroot]
|
|
||||||
cmd = [sucmd, 'chroot', buildroot, 'su', '-', user]
|
|
||||||
if suargs:
|
|
||||||
mntproc[1:1] = suargs.split()
|
|
||||||
mntsys[1:1] = suargs.split()
|
|
||||||
mntdevpts[1:1] = suargs.split()
|
|
||||||
umntproc[1:1] = suargs.split()
|
|
||||||
umntsys[1:1] = suargs.split()
|
|
||||||
umntdevpts[1:1] = suargs.split()
|
|
||||||
cmd[1:1] = suargs.split()
|
|
||||||
|
|
||||||
#signal handler for chroot procfs umount
|
|
||||||
def umount_handle(signum = None, frame = None, ret=1):
|
|
||||||
subprocess.call(umntproc)
|
|
||||||
subprocess.call(umntsys)
|
|
||||||
subprocess.call(umntdevpts)
|
|
||||||
sys.exit(ret)
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
|
|
||||||
signal.signal(sig, umount_handle)
|
|
||||||
|
|
||||||
print('mounting proc: %s' % ' '.join(mntproc))
|
|
||||||
print('mounting sys: %s' % ' '.join(mntsys))
|
|
||||||
print('mounting devpts: %s' % ' '.join(mntdevpts))
|
|
||||||
mount_err = -1
|
|
||||||
proc_mount_err = subprocess.call(mntproc)
|
|
||||||
sys_mount_err = subprocess.call(mntsys)
|
|
||||||
devpts_mount_err = subprocess.call(mntdevpts)
|
|
||||||
if proc_mount_err > 0:
|
|
||||||
print('There was an error mounting proc. Please check mountpoints in chroot')
|
|
||||||
if sys_mount_err > 0:
|
|
||||||
print('There was an error mounting sys. Please check mountpoints in chroot')
|
|
||||||
if devpts_mount_err > 0:
|
|
||||||
print('There was an error mounting devpts. Please check mountpoints in chroot')
|
|
||||||
print('running: %s' % ' '.join(cmd))
|
|
||||||
retval = 0
|
|
||||||
try:
|
|
||||||
retval = subprocess.call(cmd)
|
|
||||||
finally:
|
|
||||||
if ((not proc_mount_err or proc_mount_err == 32) and
|
|
||||||
(not sys_mount_err or sys_mount_err == 32) and
|
|
||||||
(not devpts_mount_err or devpts_mount_err == 32)):
|
|
||||||
print('unmounting %s/proc and %s/sys and %s/dev/pts ...' % (buildroot, buildroot, buildroot))
|
|
||||||
umount_handle(ret=retval)
|
|
||||||
|
|
||||||
|
|
||||||
@cmdln.option('', '--csv', action='store_true',
|
@cmdln.option('', '--csv', action='store_true',
|
||||||
help='generate output in CSV (separated by |)')
|
help='generate output in CSV (separated by |)')
|
||||||
@cmdln.option('-l', '--limit', metavar='limit',
|
@cmdln.option('-l', '--limit', metavar='limit',
|
||||||
|
Loading…
Reference in New Issue
Block a user