123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- def create_archive(self, scm_object, **kwargs):
- """Create an OBS cpio archive of repodir in destination directory.
- """
- basename = kwargs['basename']
- dstname = kwargs['dstname']
- version = kwargs['version']
- args = kwargs['cli']
- commit = scm_object.get_current_commit()
- package_metadata = args.package_meta
- (workdir, topdir) = os.path.split(scm_object.arch_dir)
- extension = 'obscpio'
- cwd = os.getcwd()
- os.chdir(workdir)
- archivefilename = os.path.join(args.outdir, dstname + '.' + extension)
- archivefile = open(archivefilename, "w")
- # detect reproducible support
- params = ['cpio', '--create', '--format=newc', '--owner', '0:0']
- chkcmd = "cpio --create --format=newc --reproducible "
- chkcmd += "</dev/null >/dev/null 2>&1"
- if os.system(chkcmd) == 0:
- params.append('--reproducible')
- proc = subprocess.Popen(
- params,
- shell=False,
- stdin=subprocess.PIPE,
- stdout=archivefile,
- stderr=subprocess.STDOUT
- )
- # transform glob patterns to regular expressions
- includes = ''
- excludes = r'$.'
- topdir_re = '(' + topdir + '/)('
- if args.include:
- incl_arr = [fnmatch.translate(x + '*') for x in args.include]
- match_list = r'|'.join(incl_arr)
- includes = topdir_re + match_list + ')'
- if args.exclude:
- excl_arr = [fnmatch.translate(x) for x in args.exclude]
- excludes = topdir_re + r'|'.join(excl_arr) + ')'
- # add topdir without filtering for now
- cpiolist = []
- for root, dirs, files in os.walk(topdir, topdown=False):
- # excludes
- dirs[:] = [os.path.join(root, d) for d in dirs]
- dirs[:] = [d for d in dirs if not re.match(excludes, d)]
- dirs[:] = [d for d in dirs if re.match(includes, d)]
- # exclude/include files
- files = [os.path.join(root, f) for f in files]
- files = [f for f in files if not re.match(excludes, f)]
- files = [f for f in files if re.match(includes, f)]
- for name in dirs:
- if not METADATA_PATTERN.match(name) or package_metadata:
- cpiolist.append(name)
- for name in files:
- if not METADATA_PATTERN.match(name) or package_metadata:
- cpiolist.append(name)
- tstamp = self.helpers.get_timestamp(scm_object, args, topdir)
- for name in sorted(cpiolist):
- try:
- os.utime(name, (tstamp, tstamp))
- except OSError:
- pass
- # bytes() break in python2 with a TypeError as it expects only 1
- # arg
- try:
- proc.stdin.write(name.encode('UTF-8', 'surrogateescape'))
- except (TypeError, UnicodeDecodeError):
- proc.stdin.write(name)
- proc.stdin.write(b"\n")
- proc.stdin.close()
- ret_code = proc.wait()
- if ret_code != 0:
- raise SystemExit("Creating the cpio archive failed!")
- archivefile.close()
- # write meta data
- infofile = os.path.join(args.outdir, basename + '.obsinfo')
- logging.debug("Writing to obsinfo file '%s'", infofile)
- metafile = open(infofile, "w")
- metafile.write("name: " + basename + "\n")
- metafile.write("version: " + version + "\n")
- metafile.write("mtime: " + str(tstamp) + "\n")
- if commit:
- metafile.write("commit: " + commit + "\n")
- metafile.close()
- self.archivefile = archivefile.name
- self.metafile = metafile.name
- os.chdir(cwd)
|