summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pylintrc435
-rwxr-xr-xsetup.py66
-rw-r--r--src/virtBootstrap/sources.py93
-rwxr-xr-xsrc/virtBootstrap/virt_bootstrap.py48
4 files changed, 589 insertions, 53 deletions
diff --git a/pylintrc b/pylintrc
new file mode 100644
index 0000000..4788aec
--- /dev/null
+++ b/pylintrc
@@ -0,0 +1,435 @@
+[MASTER]
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code
+#extension-pkg-whitelist=
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+#ignore=CVS
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+# ignore-patterns=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Use multiple processes to speed up Pylint.
+jobs=1
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+# load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Specify a configuration file.
+#rcfile=
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+
+# R0201 - Method could be a function
+# C0320 - Unnecessary parens after 'print' keyword
+# W0703 - Catching too general exception
+# R0912 - Used when a function or method has too many branches,making it hard to follow.
+
+disable=R0201,C0325,W0703,R0912
+
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+enable=
+
+
+[REPORTS]
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio).You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis. It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=_
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=yes
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,_cb
+
+# A regular expression matching the name of dummy variables (i.e. expectedly
+# not used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,future.builtins
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+# FIXME -- something which needs fixing
+# TODO -- future plan
+# XXX -- some concern
+notes=FIXME,XXX,TODO
+
+
+[BASIC]
+
+# Naming hint for argument names
+argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Regular expression matching correct argument names
+argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Naming hint for attribute names
+attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Regular expression matching correct attribute names
+attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Naming hint for class attribute names
+class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+
+# Regular expression matching correct class attribute names
+class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+
+# Naming hint for class names
+class-name-hint=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression matching correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Naming hint for constant names
+const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression matching correct constant names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+# Naming hint for function names
+function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Regular expression matching correct function names
+function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_,virtBootstrap
+
+# Include a hint for the correct naming format with invalid-name
+include-naming-hint=yes
+
+# Naming hint for inline iteration names
+inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
+
+# Regular expression matching correct inline iteration names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Naming hint for method names
+method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Regular expression matching correct method names
+method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Naming hint for module names
+module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression matching correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+#name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_|main
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+property-classes=abc.abstractproperty
+
+# Naming hint for variable names
+variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+# Regular expression matching correct variable names
+variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=4
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+# Maximum number of characters on a single line.
+max-line-length=100
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[LOGGING]
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format
+logging-modules=logging
+
+
+[SPELLING]
+
+# Spelling dictionary name. Available dictionaries: none. To make it working
+# install python-enchant package.
+#spelling-dict=
+
+# List of comma separated words that should not be checked.
+#spelling-ignore-words=
+
+# A path to a file that contains private dictionary; one word per line.
+#spelling-private-dict-file=
+
+# Tells whether to store unknown words to indicated private dictionary in
+# --spelling-private-dict-file option instead of raising a message.
+#spelling-store-unknown-words=no
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,_fields,_replace,_source,_make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=8
+
+# Maximum number of boolean expressions in a if statement
+max-bool-expr=5
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=1
+
+
+[IMPORTS]
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,TERMIOS,Bastion,rexec
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+#ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+#int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+#known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/setup.py b/setup.py
index 3fe759f..c87d6f6 100755
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,16 @@
#!/usr/bin/env python
# -*- coding: utf-8; -*-
+"""
+Setup script used for building, testing, and installing modules
+based on setuptools.
+"""
+
import codecs
import os
+import sys
+from subprocess import call
+from setuptools import Command
from setuptools import setup
@@ -15,6 +23,52 @@ def read(fname):
return fobj.read()
+class CheckPylint(Command):
+ """
+ Check python source files with pylint and pycodestyle.
+ """
+
+ user_options = [('errors-only', 'e', 'only report errors')]
+ description = "Check code using pylint and pycodestyle"
+
+ def initialize_options(self):
+ """
+ Initialize the options to default values.
+ """
+ # pylint: disable=attribute-defined-outside-init
+ self.errors_only = False
+
+ def finalize_options(self):
+ """
+ Check final option values.
+ """
+ pass
+
+ def run(self):
+ """
+ Call pycodestyle and pylint here.
+ """
+
+ res = 0
+ files = ' '.join(["setup.py", "src/virtBootstrap/*.py"])
+ output_format = "colorized" if sys.stdout.isatty() else "text"
+
+ print(">>> Running pycodestyle ...")
+ cmd = "pycodestyle "
+ if (call(cmd + files, shell=True) != 0):
+ res = 1
+
+ print(">>> Running pylint ...")
+ args = ""
+ if self.errors_only:
+ args = "-E"
+ cmd = "pylint %s --output-format=%s " % (args, format(output_format))
+ if (call(cmd + files, shell=True) != 0):
+ res = 1
+
+ sys.exit(res)
+
+
setup(
name='virt-bootstrap',
version='0.1.0',
@@ -53,5 +107,15 @@ setup(
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6'
- ]
+
+ ],
+ cmdclass={
+ 'pylint': CheckPylint
+ },
+ extras_require={
+ 'dev': [
+ 'pylint',
+ 'pycodestyle'
+ ]
+ }
)
diff --git a/src/virtBootstrap/sources.py b/src/virtBootstrap/sources.py
index a1f8544..87278d2 100644
--- a/src/virtBootstrap/sources.py
+++ b/src/virtBootstrap/sources.py
@@ -15,6 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Class definitions which process container image or
+archive from source and unpack them in destination directory.
+"""
+
import hashlib
import json
import shutil
@@ -26,22 +31,24 @@ from subprocess import call, CalledProcessError, PIPE, Popen
# Default virtual size of qcow2 image
DEF_QCOW2_SIZE = '5G'
-# default_image_dir - Path where Docker images (tarballs) will be stored
if os.geteuid() == 0:
- virt_sandbox_connection = "lxc:///"
- default_image_dir = "/var/lib/virt-bootstrap/docker_images"
+ LIBVIRT_CONN = "lxc:///"
+ DEFAULT_IMG_DIR = "/var/lib/virt-bootstrap/docker_images"
else:
- virt_sandbox_connection = "qemu:///session"
- default_image_dir = \
- os.environ['HOME'] + "/.local/share/virt-bootstrap/docker_images"
+ LIBVIRT_CONN = "qemu:///session"
+ DEFAULT_IMG_DIR = os.environ['HOME']
+ DEFAULT_IMG_DIR += "/.local/share/virt-bootstrap/docker_images"
def checksum(path, sum_type, sum_expected):
+ """
+ Validate file using checksum.
+ """
algorithm = getattr(hashlib, sum_type)
try:
- fd = open(path, 'rb')
- content = fd.read()
- fd.close()
+ handle = open(path, 'rb')
+ content = handle.read()
+ handle.close()
actual = algorithm(content).hexdigest()
return actual == sum_expected
@@ -50,9 +57,11 @@ def checksum(path, sum_type, sum_expected):
def safe_untar(src, dest):
- # Extract tarball in LXC container for safety
+ """
+ Extract tarball within LXC container for safety.
+ """
virt_sandbox = ['virt-sandbox',
- '-c', virt_sandbox_connection,
+ '-c', LIBVIRT_CONN,
'-m', 'host-bind:/mnt=' + dest] # Bind destination folder
# Compression type is auto detected from tar
@@ -64,16 +73,22 @@ def safe_untar(src, dest):
def get_layer_info(digest, image_dir):
+ """
+ Get checksum type/value and path to corresponding tarball.
+ """
sum_type, sum_value = digest.split(':')
layer_file = "{}/{}.tar".format(image_dir, sum_value)
return (sum_type, sum_value, layer_file)
def untar_layers(layers_list, image_dir, dest_dir):
+ """
+ Untar each of layers from container image.
+ """
for layer in layers_list:
sum_type, sum_value, layer_file = get_layer_info(layer['digest'],
image_dir)
- logging.info('Untar layer file: ({}) {}'.format(sum_type, layer_file))
+ logging.info('Untar layer file: (%s) %s', sum_type, layer_file)
# Verify the checksum
if not checksum(layer_file, sum_type, sum_value):
@@ -139,6 +154,9 @@ def create_qcow2(tar_file, layer_file, backing_file=None, size=DEF_QCOW2_SIZE):
def extract_layers_in_qcow2(layers_list, image_dir, dest_dir):
+ """
+ Extract docker layers in qcow2 images with backing chains.
+ """
qcow2_backing_file = None
for index, layer in enumerate(layers_list):
@@ -146,7 +164,7 @@ def extract_layers_in_qcow2(layers_list, image_dir, dest_dir):
sum_type, sum_value, tar_file = \
get_layer_info(layer['digest'], image_dir)
- logging.info('Untar layer file: ({}) {}'.format(sum_type, tar_file))
+ logging.info('Untar layer file: (%s) %s', sum_type, tar_file)
# Verify the checksum
if not checksum(tar_file, sum_type, sum_value):
@@ -160,17 +178,20 @@ def extract_layers_in_qcow2(layers_list, image_dir, dest_dir):
qcow2_backing_file = qcow2_layer_file
-class FileSource:
- def __init__(self, url, username, password, fmt, insecure, no_cache):
+class FileSource(object):
+ """
+ Extract root filesystem from file.
+ """
+ def __init__(self, url, args):
self.path = url.path
- self.output_format = fmt
+ self.output_format = args.format
def unpack(self, dest):
- '''
+ """
Safely extract root filesystem from tarball
@param dest: Directory path where the files to be extraced
- '''
+ """
if self.output_format == 'dir':
logging.info("Extracting files into destination directory")
safe_untar(self.path, dest)
@@ -190,9 +211,13 @@ class FileSource:
logging.info("Files are stored in: " + dest)
-class DockerSource:
- def __init__(self, url, username, password, fmt, insecure, no_cache):
- '''
+class DockerSource(object):
+ """
+ Extract files from Docker image
+ """
+
+ def __init__(self, url, args):
+ """
Bootstrap root filesystem from Docker registry
@param url: Address of source registry
@@ -201,33 +226,33 @@ class DockerSource:
@param fmt: Format used to store image [dir, qcow2]
@param insecure: Do not require HTTPS and certificate verification
@param no_cache: Whether to store downloaded images or not
- '''
+ """
self.registry = url.netloc
self.image = url.path
- self.username = username
- self.password = password
- self.output_format = fmt
- self.insecure = insecure
- self.no_cache = no_cache
+ self.username = args.username
+ self.password = args.password
+ self.output_format = args.format
+ self.insecure = args.not_secure
+ self.no_cache = args.no_cache
if self.image and not self.image.startswith('/'):
self.image = '/' + self.image
self.url = "docker://" + self.registry + self.image
def unpack(self, dest):
- '''
+ """
Extract image files from Docker image
@param dest: Directory path where the files to be extraced
- '''
+ """
if self.no_cache:
tmp_dest = tempfile.mkdtemp('virt-bootstrap')
images_dir = tmp_dest
else:
- if not os.path.exists(default_image_dir):
- os.makedirs(default_image_dir)
- images_dir = default_image_dir
+ if not os.path.exists(DEFAULT_IMG_DIR):
+ os.makedirs(DEFAULT_IMG_DIR)
+ images_dir = DEFAULT_IMG_DIR
try:
# Run skopeo copy into a tmp folder
@@ -247,8 +272,8 @@ class DockerSource:
check_call(skopeo_copy)
# Get the layers list from the manifest
- mf = open(images_dir+"/manifest.json", "r")
- manifest = json.load(mf)
+ manifest_file = open(images_dir+"/manifest.json", "r")
+ manifest = json.load(manifest_file)
# Layers are in order - root layer first
# Reference:
diff --git a/src/virtBootstrap/virt_bootstrap.py b/src/virtBootstrap/virt_bootstrap.py
index 572e603..3973720 100755
--- a/src/virtBootstrap/virt_bootstrap.py
+++ b/src/virtBootstrap/virt_bootstrap.py
@@ -16,6 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Main executable file which process input arguments
+and calls corresponding methods on appropriate object.
+"""
+
import argparse
import gettext
import sys
@@ -27,7 +32,7 @@ try:
except ImportError:
from urllib.parse import urlparse
-import sources
+from virtBootstrap import sources
gettext.bindtextdomain("virt-bootstrap", "/usr/share/locale")
@@ -37,11 +42,19 @@ try:
localedir="/usr/share/locale",
codeset='utf-8')
except IOError:
- import __builtin__
- __builtin__.__dict__['_'] = unicode
+ try:
+ import __builtin__
+ # pylint: disable=undefined-variable
+ __builtin__.__dict__['_'] = unicode
+ except ImportError:
+ import builtin
+ builtin.__dict__['_'] = str
def get_source(args):
+ """
+ Get object which match the source type
+ """
url = urlparse(args.uri)
scheme = url.scheme
@@ -51,26 +64,27 @@ def get_source(args):
try:
class_name = "%sSource" % scheme.capitalize()
clazz = getattr(sources, class_name)
- return clazz(url,
- args.username,
- args.password,
- args.format,
- args.not_secure,
- args.no_cache)
+ return clazz(url, args)
except Exception:
raise Exception("Invalid image URI scheme: '%s'" % url.scheme)
def set_root_password(rootfs, password):
+ """
+ Set password on the root user in rootfs
+ """
users = 'root:%s' % password
args = ['chpasswd', '-R', rootfs]
- p = Popen(args, stdin=PIPE)
- p.communicate(input=users)
- if p.returncode != 0:
- raise CalledProcessError(p.returncode, cmd=args, output=None)
+ chpasswd = Popen(args, stdin=PIPE)
+ chpasswd.communicate(input=users)
+ if chpasswd.returncode != 0:
+ raise CalledProcessError(chpasswd.returncode, cmd=args, output=None)
def bootstrap(args):
+ """
+ Get source object and call unpack method
+ """
source = get_source(args)
if not os.path.exists(args.dest):
os.makedirs(args.dest)
@@ -123,12 +137,10 @@ def main():
bootstrap(args)
sys.exit(0)
- except KeyboardInterrupt as e:
+ except KeyboardInterrupt:
sys.exit(0)
- except ValueError as e:
- for line in e:
- for l in line:
- sys.stderr.write("%s: %s\n" % (sys.argv[0], l))
+ except ValueError as err:
+ sys.stderr.write("%s: %s\n" % (sys.argv[0], err))
sys.stderr.flush()
sys.exit(1)