docker-support revision 7116
5e04de9e3fcd596c02021034cc887b2dd589594dTimo Sirainen#!/usr/bin/python2.7
107bb6e31708e960d652e77339325f2cdd912934Timo Sirainen#
107bb6e31708e960d652e77339325f2cdd912934Timo Sirainen# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
107bb6e31708e960d652e77339325f2cdd912934Timo Sirainen#
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainen
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainenimport argparse
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainenimport os
57f4445a46726a17bfe78b0964dd301a6ccb40ecTimo Sirainenimport shutil
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenfrom subprocess import Popen, PIPE
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenimport sys
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainenimport tempfile
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
b9a94db495dd924f4743f43e5cb28d5201ab9206Timo SirainenROOTFS_ARCHIVE = "rootfs.tar.gz"
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenDOCKERFILE = """FROM scratch
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenADD %(archive)s /
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenLABEL vendor="Oracle USA"
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenLABEL com.oracle.solaris.version.release="beta"
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenLABEL com.oracle.solaris.version.branch="%(osversion)s"
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo SirainenCMD /bin/bash
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen"""
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainenclass DockerSupportCmd(object):
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen def __init__(self, cmd, verbose=False):
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen self.cmd = cmd
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen self.verbose = verbose
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen def run(self, expect_nonzero=None):
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen if self.verbose:
800ce5df11647686f4fc33e8dffb2d22a10f5394Timo Sirainen out = None
else:
out = PIPE
p = Popen(self.cmd, stdout=out, stderr=PIPE)
output, error = p.communicate()
if not expect_nonzero and p.returncode != 0:
raise RuntimeError(error)
return output
def docker_is_online():
try:
return DockerSupportCmd(['/usr/bin/svcs', '-Ho', 'state',
'docker']).run().strip() == 'online'
except Exception as err:
raise RuntimeError("Unable to determine version: %s" % err)
def get_os_version():
try:
output = DockerSupportCmd(['/usr/bin/pkg', 'info', '-r',
'osnet/osnet-incorporation']).run()
for line in map(str.strip, output.splitlines()):
if line.startswith("Branch"):
return line.split(":")[1].strip()
except Exception as err:
raise RuntimeError("Unable to determine version: %s" % err)
def create_rootfs_archive(args):
cmd = ['/usr/lib/brand/solaris-oci/mkimage-solaris']
if args.devbuild:
cmd.append('-D')
if args.profile:
if not os.path.exists(args.profile):
raise RuntimeError("'%s' not found" % args.profile)
cmd.extend(['-c', args.profile])
try:
# build rootfs, send output to stdout
DockerSupportCmd(cmd, verbose=True).run()
except Exception as err:
raise RuntimeError("mkimage-solaris failure: %s" % err)
def create_base_image(args):
if not docker_is_online():
raise SystemExit("Docker service not online, is Docker configured?")
try:
temp_dir = tempfile.mkdtemp(dir="/system/volatile")
except Exception as err:
raise SystemExit("Could not create build directory: %s" % err)
try:
print "Creating container rootfs from host publishers..."
create_rootfs_archive(args)
except Exception as err:
raise SystemExit("Failed to create rootfs: %s" % err)
shutil.move(ROOTFS_ARCHIVE, temp_dir)
prev_dir = os.getcwd()
os.chdir(temp_dir)
try:
osversion = get_os_version()
with open("Dockerfile", "w") as dockerfile:
dockerfile.write(DOCKERFILE %
{"archive": ROOTFS_ARCHIVE, "osversion": osversion})
tag = "solaris:%s" % osversion
print "Creating Docker base image '%s'..." % tag
DockerSupportCmd(
["/usr/bin/docker", "build", "-t", tag, "."], verbose=True).run()
DockerSupportCmd(
["/usr/bin/docker", "tag", tag, "solaris:latest"]).run()
print "Build complete."
except Exception as err:
raise SystemExit("Failed image build: %s" % err)
finally:
os.chdir(prev_dir)
assert os.path.exists(temp_dir)
shutil.rmtree(temp_dir)
def build_parser():
parser_main = argparse.ArgumentParser()
parser_main.add_argument("-v", "--version", action="version",
version="%(prog)s 0.1")
subparsers = parser_main.add_subparsers(title="sub-commands", metavar="")
parser_create = subparsers.add_parser("create-base-image",
help="create a base image from host publisher content",
usage=argparse.SUPPRESS)
parser_create.add_argument("-D", "--devbuild", action="store_true",
help="use development build options for the package image")
parser_create.add_argument("-p", "--profile",
help="TEMPORARY: optional syconfig profile")
parser_create.set_defaults(func=create_base_image)
return parser_main
def main():
parser = build_parser()
args = parser.parse_args()
if not vars(args):
raise SystemExit(parser.print_help())
return args.func(args)
if __name__ == "__main__":
sys.exit(main())