예제 #1
0
    def testDoesntUnescapeVal(self):
        key, val = helpers.SplitNameValuePairAtSeparator('abc=x\\=yz\\', '=')

        self.assertEqual(key, 'abc')

        # the val doesn't get unescaped at all
        self.assertEqual(val, 'x\\=yz\\')
예제 #2
0
    def testUnescapesNonsepCharsToo(self):
        key, val = helpers.SplitNameValuePairAtSeparator(
            'na\\xffme=value', '=')

        # this behaviour is surprising
        self.assertEqual(key, 'naxffme')
        self.assertEqual(val, 'value')
예제 #3
0
 def testStopsAtFirstSep(self):
     key, val = helpers.SplitNameValuePairAtSeparator('a=b=c', '=')
     self.assertEqual(key, 'a')
     self.assertEqual(val, 'b=c')
예제 #4
0
 def testHappyCaseWithEscapes(self):
     key, val = helpers.SplitNameValuePairAtSeparator(
         'a\\=\\=b\\=c=xyz', '=')
     self.assertEqual(key, 'a==b=c')
     self.assertEqual(val, 'xyz')
예제 #5
0
 def testHappyCase(self):
     key, val = helpers.SplitNameValuePairAtSeparator('abc=xyz', '=')
     self.assertEqual(key, 'abc')
     self.assertEqual(val, 'xyz')
예제 #6
0
 def testNoSepWithDanglingEscape(self):
     key, val = helpers.SplitNameValuePairAtSeparator('abc\\', '=')
     self.assertEqual(key, 'abc')
     self.assertEqual(val, '')
예제 #7
0
 def testNoSepWithEscape(self):
     key, val = helpers.SplitNameValuePairAtSeparator('a\\=bc', '=')
     self.assertEqual(key, 'a=bc')
     self.assertEqual(val, '')
예제 #8
0
def main():
    parser = argparse.ArgumentParser(
        description='Helper for building tar packages',
        fromfile_prefix_chars='@')
    parser.add_argument('--output',
                        required=True,
                        help='The output file, mandatory.')
    parser.add_argument('--file',
                        action='append',
                        help='A file to add to the layer.')
    parser.add_argument('--manifest',
                        help='JSON manifest of contents to add to the layer.')
    parser.add_argument('--mode',
                        help='Force the mode on the added files (in octal).')
    parser.add_argument(
        '--mtime',
        help='Set mtime on tar file entries. May be an integer or the'
        ' value "portable", to get the value 2000-01-01, which is'
        ' is usable with non *nix OSes.')
    parser.add_argument('--empty_file',
                        action='append',
                        help='An empty file to add to the layer.')
    parser.add_argument('--empty_dir',
                        action='append',
                        help='An empty dir to add to the layer.')
    parser.add_argument('--empty_root_dir',
                        action='append',
                        help='An empty dir to add to the layer.')
    parser.add_argument('--tar',
                        action='append',
                        help='A tar file to add to the layer')
    parser.add_argument('--deb',
                        action='append',
                        help='A debian package to add to the layer')
    parser.add_argument(
        '--link',
        action='append',
        help=
        'Add a symlink a inside the layer pointing to b if a:b is specified')
    # TODO(aiuto): Add back in the validation
    # flags.register_validator(
    #   'link',
    #   lambda l: all(value.find(':') > 0 for value in l),
    #   message='--link value should contains a : separator')
    parser.add_argument(
        '--directory',
        help='Directory in which to store the file inside the layer')
    parser.add_argument('--compression',
                        help='Compression (`gz` or `bz2`), default is none.')
    parser.add_argument(
        '--modes',
        action='append',
        help='Specific mode to apply to specific file (from the file argument),'
        ' e.g., path/to/file=0455.')
    parser.add_argument('--owners',
                        action='append',
                        help='Specify the numeric owners of individual files, '
                        'e.g. path/to/file=0.0.')
    parser.add_argument('--owner',
                        default='0.0',
                        help='Specify the numeric default owner of all files,'
                        ' e.g., 0.0')
    parser.add_argument(
        '--owner_name',
        help='Specify the owner name of all files, e.g. root.root.')
    parser.add_argument(
        '--owner_names',
        action='append',
        help='Specify the owner names of individual files, e.g. '
        'path/to/file=root.root.')
    parser.add_argument('--root_directory',
                        default='./',
                        help='Default root directory is named "."')
    options = parser.parse_args()

    # Parse modes arguments
    default_mode = None
    if options.mode:
        # Convert from octal
        default_mode = int(options.mode, 8)

    mode_map = {}
    if options.modes:
        for filemode in options.modes:
            (f, mode) = helpers.SplitNameValuePairAtSeparator(filemode, '=')
            if f[0] == '/':
                f = f[1:]
            mode_map[f] = int(mode, 8)

    default_ownername = ('', '')
    if options.owner_name:
        default_ownername = options.owner_name.split('.', 1)
    names_map = {}
    if options.owner_names:
        for file_owner in options.owner_names:
            (f, owner) = helpers.SplitNameValuePairAtSeparator(file_owner, '=')
            (user, group) = owner.split('.', 1)
            if f[0] == '/':
                f = f[1:]
            names_map[f] = (user, group)

    default_ids = options.owner.split('.', 1)
    default_ids = (int(default_ids[0]), int(default_ids[1]))
    ids_map = {}
    if options.owners:
        for file_owner in options.owners:
            (f, owner) = helpers.SplitNameValuePairAtSeparator(file_owner, '=')
            (user, group) = owner.split('.', 1)
            if f[0] == '/':
                f = f[1:]
            ids_map[f] = (int(user), int(group))

    # Add objects to the tar file
    with TarFile(options.output, helpers.GetFlagValue(options.directory),
                 options.compression, options.root_directory,
                 options.mtime) as output:

        def file_attributes(filename):
            if filename.startswith('/'):
                filename = filename[1:]
            return {
                'mode': mode_map.get(filename, default_mode),
                'ids': ids_map.get(filename, default_ids),
                'names': names_map.get(filename, default_ownername),
            }

        if options.manifest:
            with open(options.manifest, 'r') as manifest_fp:
                manifest = json.load(manifest_fp)
                for f in manifest.get('files', []):
                    output.add_file(f['src'], f['dst'],
                                    **file_attributes(f['dst']))
                for f in manifest.get('empty_files', []):
                    output.add_empty_file(f, **file_attributes(f))
                for d in manifest.get('empty_dirs', []):
                    output.add_empty_dir(d, **file_attributes(d))
                for d in manifest.get('empty_root_dirs', []):
                    output.add_empty_root_dir(d, **file_attributes(d))
                for f in manifest.get('symlinks', []):
                    output.add_link(f['linkname'], f['target'])
                for tar in manifest.get('tars', []):
                    output.add_tar(tar)
                for deb in manifest.get('debs', []):
                    output.add_deb(deb)

        for f in options.file or []:
            (inf, tof) = helpers.SplitNameValuePairAtSeparator(f, '=')
            output.add_file(inf, tof, **file_attributes(tof))
        for f in options.empty_file or []:
            output.add_empty_file(f, **file_attributes(f))
        for f in options.empty_dir or []:
            output.add_empty_dir(f, **file_attributes(f))
        for f in options.empty_root_dir or []:
            output.add_empty_root_dir(f, **file_attributes(f))
        for tar in options.tar or []:
            output.add_tar(tar)
        for deb in options.deb or []:
            output.add_deb(deb)
        for link in options.link or []:
            l = helpers.SplitNameValuePairAtSeparator(link, ':')
            output.add_link(l[0], l[1])