mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-24 16:57:02 +00:00
fixes for buildroot config, added onlbuilder and docker_shell
This commit is contained in:
159
docker_shell
Normal file
159
docker_shell
Normal file
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import datetime
|
||||
import subprocess
|
||||
import pwd
|
||||
import logging
|
||||
import re
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger('docker_shell')
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
g_dry = False
|
||||
|
||||
def fatal(msg, rc=1):
|
||||
logger.critical(msg)
|
||||
sys.exit(rc)
|
||||
|
||||
def execute(cmd, msg=None):
|
||||
logger.debug('+ %s ...' % cmd)
|
||||
rc = 0
|
||||
if not g_dry:
|
||||
rc = os.system(cmd)
|
||||
if rc == 0:
|
||||
logger.debug('+ %s [OK]' % cmd)
|
||||
else:
|
||||
logger.debug('+ %s [FAILED (%d)]' % (cmd, rc))
|
||||
if msg:
|
||||
fatal(msg)
|
||||
else:
|
||||
logger.debug('+ %s [DRY]' % cmd)
|
||||
return rc
|
||||
|
||||
class User(object):
|
||||
|
||||
default_shell="/bin/bash"
|
||||
default_user="root:0"
|
||||
|
||||
def __init__(self, uspec):
|
||||
|
||||
(self.name, c, rest) = uspec.partition(':')
|
||||
self.validate_name()
|
||||
|
||||
(self.uid, c, rest) = rest.partition(':')
|
||||
self.validate_uid()
|
||||
|
||||
(self.shell, c, rest) = rest.partition(':')
|
||||
if self.shell == '':
|
||||
self.shell = User.default_shell
|
||||
if not os.path.exists(self.shell):
|
||||
fatal("Requested shell '%s' does not exist." % self.shell)
|
||||
|
||||
(self.home, c, rest) = rest.partition(':')
|
||||
|
||||
logger.debug("User(%s) initialized." % self)
|
||||
|
||||
def __str__(self):
|
||||
return "%s:%s:%s" % (self.name, self.uid, self.shell)
|
||||
|
||||
def validate_name(self):
|
||||
NAME_REGEX=r"[a-z][-a-z0-9]*"
|
||||
if re.match(NAME_REGEX, self.name) is None:
|
||||
fatal("'%s' is not a valid username." % self.name)
|
||||
logger.debug("username %s is validated." % self.name)
|
||||
|
||||
def validate_uid(self):
|
||||
try:
|
||||
self.uid = int(self.uid)
|
||||
logger.debug("uid %d is validated." % self.uid)
|
||||
except:
|
||||
if self.uid == '':
|
||||
if self.name == 'root':
|
||||
self.uid = 0
|
||||
else:
|
||||
fatal("A user id is required for user '%s'" % self.name)
|
||||
else:
|
||||
fatal("'%s' is not a valid user id." % self.uid)
|
||||
|
||||
|
||||
def add(self):
|
||||
logger.debug("Process user %s ..." % self)
|
||||
existing_user = None
|
||||
try:
|
||||
existing_user = pwd.getpwnam(self.name)
|
||||
if existing_user and existing_user.pw_uid != self.uid:
|
||||
fatal("User %s already exists with a different uid (%d).\n" % (self.name, existing_user.pw_uid))
|
||||
except KeyError:
|
||||
logger.debug("User %s does not exist." % self.name)
|
||||
|
||||
try:
|
||||
existing_uid = pwd.getpwuid(self.uid)
|
||||
if existing_uid and existing_uid.pw_name != self.name:
|
||||
fatal("UID %d already exists with a different user (%s).\n" % (self.uid, existing_uid.pw_name))
|
||||
except KeyError:
|
||||
logger.debug("UID %d does not exist." % self.uid)
|
||||
|
||||
if existing_user:
|
||||
logger.debug("User %s already exists." % self)
|
||||
else:
|
||||
logger.debug("Creating user %s ..." % (self))
|
||||
cmd = "useradd %s --uid %s --shell %s" % (self.name, self.uid, self.shell)
|
||||
if self.home not in [ None, '' ]:
|
||||
cmd += " -d %s" % (self.home)
|
||||
execute(cmd, "User creation failed for user %s" % self)
|
||||
|
||||
if not g_dry and self.name != 'root':
|
||||
with open("/etc/sudoers.d/%s" % self.name, "w") as f:
|
||||
f.write("%s ALL=(ALL:ALL) NOPASSWD:ALL\n" % self.name)
|
||||
|
||||
|
||||
############################################################
|
||||
|
||||
ap = argparse.ArgumentParser("ONL Docker Shell Build and Development Container Init Script.")
|
||||
|
||||
ap.add_argument("--user", "-u",
|
||||
help="Run as the given user:uid. The user is created if necessary. The default is %s" % User.default_user,
|
||||
default=User.default_user,
|
||||
metavar="USERNAME:UID[:SHELL]")
|
||||
ap.add_argument("--addusers", "-a",
|
||||
help="Add additional users.",
|
||||
nargs='+',
|
||||
metavar="USERNAME:UID[:SHELL]",
|
||||
default=[])
|
||||
ap.add_argument("--verbose", "-v",
|
||||
help="Set verbose logging.",
|
||||
action='store_true')
|
||||
ap.add_argument("--start-cacher",
|
||||
help="Start apt-cacher-ng in the container. It does not run by default.",
|
||||
action='store_true')
|
||||
ap.add_argument("--dry",
|
||||
help="Dry run.",
|
||||
action='store_true')
|
||||
ap.add_argument('--command', '-c',
|
||||
help="The command to run. All arguments after this option are considered part of the command.",
|
||||
nargs='+',
|
||||
default=["/bin/bash"])
|
||||
|
||||
ops = ap.parse_args()
|
||||
opsdict = vars(ops)
|
||||
g_dry = ops.dry
|
||||
|
||||
if ops.verbose or ops.dry:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
g_user = User(ops.user)
|
||||
g_user.add()
|
||||
|
||||
for u in ops.addusers:
|
||||
User(u).add()
|
||||
|
||||
if ops.start_cacher:
|
||||
execute("/etc/init.d/apt-cacher-ng start", "The apt-cacher-ng service could not be started.")
|
||||
|
||||
# Fixme: change this to os.execvp()
|
||||
c = "/usr/bin/sudo -E -u %s %s" % (g_user.name, " ".join(ops.command))
|
||||
execute(c)
|
||||
145
onlbuilder
Executable file
145
onlbuilder
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import datetime
|
||||
import getpass
|
||||
import subprocess
|
||||
import logging
|
||||
import pwd
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger('onlbuilder')
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
g_current_user = getpass.getuser()
|
||||
g_current_uid = os.getuid()
|
||||
g_timestamp = datetime.datetime.now().strftime("%Y-%m-%d.%H%M%S")
|
||||
|
||||
g_default_image_name="opennetworklinux/builder7:1.0"
|
||||
g_default_container_name = "%s_%s" % (g_current_user, g_timestamp)
|
||||
g_default_user="%s:%s" % (g_current_user, g_current_uid)
|
||||
|
||||
ap = argparse.ArgumentParser("ONL Docker Build")
|
||||
|
||||
ap.add_argument("--dry",
|
||||
help="Dry run.",
|
||||
action='store_true')
|
||||
|
||||
ap.add_argument("--verbose", "-v",
|
||||
help="Verbose logging.",
|
||||
action='store_true')
|
||||
|
||||
ap.add_argument("--image", "-i",
|
||||
help="The docker image to use. The default is %s." % g_default_image_name,
|
||||
default=g_default_image_name)
|
||||
|
||||
ap.add_argument("--exec", "-e",
|
||||
help="Execute in running container instead of starting a new one.",
|
||||
metavar='CONTAINER|NAME',
|
||||
dest='exec_')
|
||||
|
||||
ap.add_argument("--user", "-u",
|
||||
help="Run as the given user:uid. Create if necessary. The default is you (%s)" % g_default_user,
|
||||
default=g_default_user,
|
||||
metavar='USERNAME:UID')
|
||||
|
||||
ap.add_argument("--adduser", "-a",
|
||||
help="Add additional user(s). These users will only be added to the container.",
|
||||
nargs="+",
|
||||
metavar='USENAME:UID')
|
||||
|
||||
ap.add_argument("--name", "-n",
|
||||
help="Set the container name. The default will be your username concatenated with the current timestamp (%s)." % g_default_container_name,
|
||||
default=g_default_container_name)
|
||||
|
||||
ap.add_argument("--workdir", "-w",
|
||||
help="Set the working directory. The default will be the current working directory.",
|
||||
default=os.getcwd())
|
||||
|
||||
ap.add_argument("--no-ssh",
|
||||
help="Do not include current SSH Agent credentials. The default is to include them if present.",
|
||||
action='store_true')
|
||||
|
||||
ap.add_argument("--use-running", "-r",
|
||||
help="Use an existing, matching, running container instead of starting a new one (if available).",
|
||||
action='store_true'),
|
||||
|
||||
ap.add_argument("--isolate",
|
||||
help="Build isolation mode. Only the isolate directories are mounted, and a new network namespace is used. The --hostname becomes active in this mode.",
|
||||
nargs='*')
|
||||
|
||||
ap.add_argument("--hostname",
|
||||
help="Change hostname in isolation mode.")
|
||||
ap.add_argument("--non-interactive",
|
||||
help="Non-interactive mode.",
|
||||
action='store_true')
|
||||
|
||||
ap.add_argument("--command", "-c",
|
||||
help="Explicit command to run. All arguments after -c are considered to be part of the command.",
|
||||
nargs='+',
|
||||
default=['bash'])
|
||||
|
||||
ops = ap.parse_args()
|
||||
|
||||
if ops.verbose or ops.dry:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
logger.debug('arguments: %s\n' % vars(ops))
|
||||
|
||||
if ops.use_running:
|
||||
sys.stderr.write("The --r option is not yet implemented.")
|
||||
# Todo -- query running containers that match and set ops.exec_cid
|
||||
sys.exit(1)
|
||||
|
||||
g_ssh_options = ''
|
||||
g_ssh_auth_sock = os.getenv('SSH_AUTH_SOCK')
|
||||
if g_ssh_auth_sock and not ops.no_ssh:
|
||||
g_ssh_dir = os.path.dirname(g_ssh_auth_sock)
|
||||
g_ssh_options = '-v %s:%s -e SSH_AUTH_SOCK=%s' % (g_ssh_dir, g_ssh_dir, g_ssh_auth_sock)
|
||||
|
||||
g_arg_d=vars(ops)
|
||||
|
||||
g_arg_d['username'] = g_arg_d['user'].split(':')[0]
|
||||
g_arg_d['ssh_options'] = g_ssh_options
|
||||
g_arg_d['interactive'] = " " if ops.non_interactive else " -i "
|
||||
g_arg_d['commands'] = " ".join(ops.command)
|
||||
|
||||
# Get the home directory of the requested user.
|
||||
try:
|
||||
passwd = pwd.getpwnam(g_arg_d['username'])
|
||||
g_arg_d['home'] = passwd.pw_dir
|
||||
except KeyError:
|
||||
# Not a local user. Just skip setting $HOME
|
||||
pass
|
||||
|
||||
if ops.exec_:
|
||||
g_docker_arguments = "docker exec %(interactive)s -t %(exec_)s ~/OpenNetworkLinux/docker_shell --user %(user)s" % g_arg_d
|
||||
else:
|
||||
g_docker_arguments = "docker run --privileged %(interactive)s -t -e DOCKER_IMAGE=%(image)s --name %(name)s %(ssh_options)s -v /lib/modules:/lib/modules " % g_arg_d
|
||||
|
||||
if ops.isolate is not None:
|
||||
if len(ops.isolate) is 0:
|
||||
ops.isolate.append(os.getcwd())
|
||||
|
||||
isolates = [ os.path.abspath(i) for i in ops.isolate ]
|
||||
g_docker_arguments += " -e HOME=%s -w %s " % (isolates[0], isolates[0])
|
||||
for d in isolates:
|
||||
g_docker_arguments += " -v %s:%s " % (d,d)
|
||||
|
||||
if ops.hostname:
|
||||
g_docker_arguments += " -h %s" % ops.hostname
|
||||
|
||||
else:
|
||||
# Development host mode
|
||||
g_docker_arguments += "-e USER=%(username)s --net host -w %(workdir)s " % g_arg_d
|
||||
if 'home' in g_arg_d:
|
||||
g_docker_arguments += " -e HOME=%(home)s -v %(home)s:%(home)s" % g_arg_d
|
||||
|
||||
g_docker_arguments += " %(image)s /bin/docker_shell --user %(user)s -c %(commands)s" % g_arg_d
|
||||
|
||||
g_docker_arguments = " ".join(g_docker_arguments.split())
|
||||
logger.debug("running: %s" % g_docker_arguments)
|
||||
if not ops.dry:
|
||||
sys.exit(os.system(g_docker_arguments))
|
||||
@@ -85,7 +85,7 @@ BR2_HOST_DIR="$(BASE_DIR)/host"
|
||||
# Mirrors and Download locations
|
||||
#
|
||||
BR2_PRIMARY_SITE="http://switch-nfs/export/buildroot-download-cache/dl"
|
||||
BR2_PRIMARY_SITE_ONLY=y
|
||||
BR2_PRIMARY_SITE_ONLY=n
|
||||
BR2_BACKUP_SITE="http://sources.buildroot.net/"
|
||||
BR2_KERNEL_MIRROR="http://www.kernel.org/pub/"
|
||||
BR2_GNU_MIRROR="http://ftp.gnu.org/pub/gnu"
|
||||
|
||||
Reference in New Issue
Block a user