diff --git a/bin/is b/bin/is index 6f40c945749328492f913f81f9b9acd33e464c3c..8be4e7526d075dd3fe1865dcdb8a037a4ac8f653 100755 --- a/bin/is +++ b/bin/is @@ -144,6 +144,14 @@ def c_del(parser, args): raise Exception("Abort") repo.delete(img.name, img.version) +def c_extract(parser, args): + ''' + Extract an image package inside a directory + ''' + repoman = load_repositories(args) + img, repo = select_image(args.image, repoman) + img.extract(args.directory, payload=args.payload, force=args.force) + def c_get(parser, args): ''' Get a remove image in current directory @@ -325,6 +333,16 @@ p_del.add_argument("-f", "--force", action="store_true", default=False, help="delete image without confirmation") p_del.set_defaults(func=c_del) +# extract command parser +p_extract = subparsers.add_parser("extract", help=c_extract.__doc__.lower()) +p_extract.add_argument("-p", action="store_true", dest="payload", default=False, + help="extract payload") +p_extract.add_argument("-f", "--force", action="store_true", default=False, + help="overwrite existing directories") +p_extract.add_argument("image", help="image to extract") +p_extract.add_argument("directory", help="directory where image will be extracted") +p_extract.set_defaults(func=c_extract) + # get command parser p_get = subparsers.add_parser("get", help=c_get.__doc__.lower()) p_get.set_defaults(func=c_get) diff --git a/installsystems/image.py b/installsystems/image.py index 621735bcf4fcd63ab3bc2e233b440e8bc3946613..9fae13be0d8d4c8d08fe0bbb8cfe6ef519e985a4 100644 --- a/installsystems/image.py +++ b/installsystems/image.py @@ -461,6 +461,25 @@ class PackageImage(Image): arrow(filename) out(self._tarball.get_str(filename)) + def extract(self, directory, force=False, payload=False): + ''' + Extract content of the image inside a repository + ''' + # check destination + if not os.path.isdir(directory): + istools.mkdir(directory) + if not force and len(os.listdir(directory)) != 0: + raise Exception("%s is not empty" % directory) + # extract content + arrow("Extracting image in %s" % directory) + self._tarball.extractall(directory) + # launch payload extract + if payload: + for payname in self.payload: + dest = os.path.join(directory, "payload", payname) + arrow("Extracting payload %s in %s" % (payname, dest)) + self.payload[payname].extract(dest, force=force) + def run_parser(self, **kwargs): ''' Run parser scripts @@ -658,7 +677,7 @@ class Payload(object): if not force and len(os.listdir(dest)) > 0: raise Exception("Directory %s is not empty (need force)" % dest) else: - os.mkdir(dest) + istools.mkdir(dest) # try to open payload file try: fo = istools.uopen(self.path) @@ -688,6 +707,9 @@ class Payload(object): # if dest is a directory try to create file inside if os.path.isdir(dest): dest = os.path.join(dest, self.name) + # try to create leading directories + elif not os.path.exists(os.path.dirname(dest)): + istools.mkdir(os.path.dirname(dest)) # check validity of dest if os.path.exists(dest): if os.path.isdir(dest): diff --git a/installsystems/tools.py b/installsystems/tools.py index e061d08cef85b5f3a734c3d541c2ea0e77b0ca27..1630dabf95d06101f9860a1c83f3342087f53bf1 100644 --- a/installsystems/tools.py +++ b/installsystems/tools.py @@ -81,7 +81,7 @@ def mkdir(path, uid=None, gid=None, mode=None): ''' Create a directory and set rights ''' - os.mkdir(path) + os.makedirs(path) chrights(path, uid, gid, mode) def chrights(path, uid=None, gid=None, mode=None, mtime=None):