def gpg_verify(args): """verify a signed package""" # TODO: Support the package format Spack creates. signature = args.signature if signature is None: signature = args.package + '.asc' Gpg.verify(signature, args.package)
def extract_tarball(spec, filename, yes_to_all=False, force=False): """ extract binary tarball for given package into install area """ installpath = spec.prefix if os.path.exists(installpath): if force: shutil.rmtree(installpath) else: raise NoOverwriteException(str(installpath)) stagepath = os.path.dirname(filename) spackfile_name = tarball_name(spec, '.spack') spackfile_path = os.path.join(stagepath, spackfile_name) tarfile_name = tarball_name(spec, '.tar.gz') tarfile_path = os.path.join(stagepath, tarfile_name) specfile_name = tarball_name(spec, '.spec.yaml') specfile_path = os.path.join(stagepath, specfile_name) with closing(tarfile.open(spackfile_path, 'r')) as tar: tar.extractall(stagepath) if not yes_to_all: if os.path.exists('%s.asc' % specfile_path): Gpg.verify('%s.asc' % specfile_path, specfile_path) os.remove(specfile_path + '.asc') else: raise NoVerifyException() # get the sha256 checksum of the tarball checksum = checksum_tarball(tarfile_path) # get the sha256 checksum recorded at creation spec_dict = {} with open(specfile_path, 'r') as inputfile: content = inputfile.read() spec_dict = yaml.load(content) bchecksum = spec_dict['binary_cache_checksum'] # if the checksums don't match don't install if bchecksum['hash'] != checksum: raise NoChecksumException() # delay creating installpath until verification is complete mkdirp(installpath) with closing(tarfile.open(tarfile_path, 'r')) as tar: tar.extractall(path=join_path(installpath, '..')) os.remove(tarfile_path) os.remove(specfile_path) relocate_package(installpath)
def extract_tarball(spec, filename, allow_root=False, unsigned=False, force=False): """ extract binary tarball for given package into install area """ if os.path.exists(spec.prefix): if force: shutil.rmtree(spec.prefix) else: raise NoOverwriteException(str(spec.prefix)) tmpdir = tempfile.mkdtemp() stagepath = os.path.dirname(filename) spackfile_name = tarball_name(spec, '.spack') spackfile_path = os.path.join(stagepath, spackfile_name) tarfile_name = tarball_name(spec, '.tar.gz') tarfile_path = os.path.join(tmpdir, tarfile_name) specfile_name = tarball_name(spec, '.spec.yaml') specfile_path = os.path.join(tmpdir, specfile_name) with closing(tarfile.open(spackfile_path, 'r')) as tar: tar.extractall(tmpdir) if not unsigned: if os.path.exists('%s.asc' % specfile_path): try: Gpg.verify('%s.asc' % specfile_path, specfile_path) except Exception as e: shutil.rmtree(tmpdir) tty.die(str(e)) else: shutil.rmtree(tmpdir) raise NoVerifyException( "Package spec file failed signature verification.\n" "Use spack buildcache keys to download " "and install a key for verification from the mirror.") # get the sha256 checksum of the tarball checksum = checksum_tarball(tarfile_path) # get the sha256 checksum recorded at creation spec_dict = {} with open(specfile_path, 'r') as inputfile: content = inputfile.read() spec_dict = syaml.load(content) bchecksum = spec_dict['binary_cache_checksum'] # if the checksums don't match don't install if bchecksum['hash'] != checksum: shutil.rmtree(tmpdir) raise NoChecksumException( "Package tarball failed checksum verification.\n" "It cannot be installed.") new_relative_prefix = str(os.path.relpath(spec.prefix, spack.store.layout.root)) # if the original relative prefix is in the spec file use it buildinfo = spec_dict.get('buildinfo', {}) old_relative_prefix = buildinfo.get('relative_prefix', new_relative_prefix) # if the original relative prefix and new relative prefix differ the # directory layout has changed and the buildcache cannot be installed if old_relative_prefix != new_relative_prefix: shutil.rmtree(tmpdir) msg = "Package tarball was created from an install " msg += "prefix with a different directory layout.\n" msg += "It cannot be relocated." raise NewLayoutException(msg) # extract the tarball in a temp directory with closing(tarfile.open(tarfile_path, 'r')) as tar: tar.extractall(path=tmpdir) # the base of the install prefix is used when creating the tarball # so the pathname should be the same now that the directory layout # is confirmed workdir = os.path.join(tmpdir, os.path.basename(spec.prefix)) # cleanup os.remove(tarfile_path) os.remove(specfile_path) try: relocate_package(workdir, allow_root) except Exception as e: shutil.rmtree(workdir) tty.die(str(e)) # Delay creating spec.prefix until verification is complete # and any relocation has been done. else: install_tree(workdir, spec.prefix, symlinks=True) finally: shutil.rmtree(tmpdir)
def extract_tarball(spec, filename, allow_root=False, unsigned=False, force=False): """ extract binary tarball for given package into install area """ if os.path.exists(spec.prefix): if force: shutil.rmtree(spec.prefix) else: raise NoOverwriteException(str(spec.prefix)) tmpdir = tempfile.mkdtemp() stagepath = os.path.dirname(filename) spackfile_name = tarball_name(spec, '.spack') spackfile_path = os.path.join(stagepath, spackfile_name) tarfile_name = tarball_name(spec, '.tar.gz') tarfile_path = os.path.join(tmpdir, tarfile_name) specfile_name = tarball_name(spec, '.spec.yaml') specfile_path = os.path.join(tmpdir, specfile_name) with closing(tarfile.open(spackfile_path, 'r')) as tar: tar.extractall(tmpdir) # some buildcache tarfiles use bzip2 compression if not os.path.exists(tarfile_path): tarfile_name = tarball_name(spec, '.tar.bz2') tarfile_path = os.path.join(tmpdir, tarfile_name) if not unsigned: if os.path.exists('%s.asc' % specfile_path): try: suppress = config.get('config:suppress_gpg_warnings', False) Gpg.verify('%s.asc' % specfile_path, specfile_path, suppress) except Exception as e: shutil.rmtree(tmpdir) raise e else: shutil.rmtree(tmpdir) raise NoVerifyException( "Package spec file failed signature verification.\n" "Use spack buildcache keys to download " "and install a key for verification from the mirror.") # get the sha256 checksum of the tarball checksum = checksum_tarball(tarfile_path) # get the sha256 checksum recorded at creation spec_dict = {} with open(specfile_path, 'r') as inputfile: content = inputfile.read() spec_dict = syaml.load(content) bchecksum = spec_dict['binary_cache_checksum'] # if the checksums don't match don't install if bchecksum['hash'] != checksum: shutil.rmtree(tmpdir) raise NoChecksumException( "Package tarball failed checksum verification.\n" "It cannot be installed.") new_relative_prefix = str( os.path.relpath(spec.prefix, spack.store.layout.root)) # if the original relative prefix is in the spec file use it buildinfo = spec_dict.get('buildinfo', {}) old_relative_prefix = buildinfo.get('relative_prefix', new_relative_prefix) rel = buildinfo.get('relative_rpaths') # if the original relative prefix and new relative prefix differ the # directory layout has changed and the buildcache cannot be installed # if it was created with relative rpaths info = 'old relative prefix %s\nnew relative prefix %s\nrelative rpaths %s' tty.debug(info % (old_relative_prefix, new_relative_prefix, rel)) # if (old_relative_prefix != new_relative_prefix and (rel)): # shutil.rmtree(tmpdir) # msg = "Package tarball was created from an install " # msg += "prefix with a different directory layout. " # msg += "It cannot be relocated because it " # msg += "uses relative rpaths." # raise NewLayoutException(msg) # extract the tarball in a temp directory with closing(tarfile.open(tarfile_path, 'r')) as tar: tar.extractall(path=tmpdir) # get the parent directory of the file .spack/binary_distribution # this should the directory unpacked from the tarball whose # name is unknown because the prefix naming is unknown bindist_file = glob.glob('%s/*/.spack/binary_distribution' % tmpdir)[0] workdir = re.sub('/.spack/binary_distribution$', '', bindist_file) tty.debug('workdir %s' % workdir) # install_tree copies hardlinks # create a temporary tarfile from prefix and exract it to workdir # tarfile preserves hardlinks temp_tarfile_name = tarball_name(spec, '.tar') temp_tarfile_path = os.path.join(tmpdir, temp_tarfile_name) with closing(tarfile.open(temp_tarfile_path, 'w')) as tar: tar.add(name='%s' % workdir, arcname='.') with closing(tarfile.open(temp_tarfile_path, 'r')) as tar: tar.extractall(spec.prefix) os.remove(temp_tarfile_path) # cleanup os.remove(tarfile_path) os.remove(specfile_path) try: relocate_package(spec, allow_root) except Exception as e: shutil.rmtree(spec.prefix) raise e else: manifest_file = os.path.join(spec.prefix, spack.store.layout.metadata_dir, spack.store.layout.manifest_file_name) if not os.path.exists(manifest_file): spec_id = spec.format('{name}/{hash:7}') tty.warn('No manifest file in tarball for spec %s' % spec_id) finally: shutil.rmtree(tmpdir) if os.path.exists(filename): os.remove(filename)
def extract_tarball(spec, filename, allow_root=False, unsigned=False, force=False): """ extract binary tarball for given package into install area """ if os.path.exists(spec.prefix): if force: shutil.rmtree(spec.prefix) else: raise NoOverwriteException(str(spec.prefix)) tmpdir = tempfile.mkdtemp() stagepath = os.path.dirname(filename) spackfile_name = tarball_name(spec, '.spack') spackfile_path = os.path.join(stagepath, spackfile_name) tarfile_name = tarball_name(spec, '.tar.bz2') tarfile_path = os.path.join(tmpdir, tarfile_name) specfile_name = tarball_name(spec, '.spec.yaml') specfile_path = os.path.join(tmpdir, specfile_name) with closing(tarfile.open(spackfile_path, 'r')) as tar: tar.extractall(tmpdir) # older buildcache tarfiles use gzip compression if not os.path.exists(tarfile_path): tarfile_name = tarball_name(spec, '.tar.gz') tarfile_path = os.path.join(tmpdir, tarfile_name) if not unsigned: if os.path.exists('%s.asc' % specfile_path): try: suppress = config.get('config:suppress_gpg_warnings', False) Gpg.verify('%s.asc' % specfile_path, specfile_path, suppress) except Exception as e: shutil.rmtree(tmpdir) tty.die(e) else: shutil.rmtree(tmpdir) raise NoVerifyException( "Package spec file failed signature verification.\n" "Use spack buildcache keys to download " "and install a key for verification from the mirror.") # get the sha256 checksum of the tarball checksum = checksum_tarball(tarfile_path) # get the sha256 checksum recorded at creation spec_dict = {} with open(specfile_path, 'r') as inputfile: content = inputfile.read() spec_dict = syaml.load(content) bchecksum = spec_dict['binary_cache_checksum'] # if the checksums don't match don't install if bchecksum['hash'] != checksum: shutil.rmtree(tmpdir) raise NoChecksumException( "Package tarball failed checksum verification.\n" "It cannot be installed.") new_relative_prefix = str( os.path.relpath(spec.prefix, spack.store.layout.root)) # if the original relative prefix is in the spec file use it buildinfo = spec_dict.get('buildinfo', {}) old_relative_prefix = buildinfo.get('relative_prefix', new_relative_prefix) # if the original relative prefix and new relative prefix differ the # directory layout has changed and the buildcache cannot be installed if old_relative_prefix != new_relative_prefix: shutil.rmtree(tmpdir) msg = "Package tarball was created from an install " msg += "prefix with a different directory layout.\n" msg += "It cannot be relocated." raise NewLayoutException(msg) # extract the tarball in a temp directory with closing(tarfile.open(tarfile_path, 'r')) as tar: tar.extractall(path=tmpdir) # the base of the install prefix is used when creating the tarball # so the pathname should be the same now that the directory layout # is confirmed workdir = os.path.join(tmpdir, os.path.basename(spec.prefix)) # install_tree copies hardlinks # create a temporary tarfile from prefix and exract it to workdir # tarfile preserves hardlinks temp_tarfile_name = tarball_name(spec, '.tar') temp_tarfile_path = os.path.join(tmpdir, temp_tarfile_name) with closing(tarfile.open(temp_tarfile_path, 'w')) as tar: tar.add(name='%s' % workdir, arcname='.') with closing(tarfile.open(temp_tarfile_path, 'r')) as tar: tar.extractall(spec.prefix) os.remove(temp_tarfile_path) # cleanup os.remove(tarfile_path) os.remove(specfile_path) try: relocate_package(spec.prefix, spec, allow_root) except Exception as e: shutil.rmtree(spec.prefix) tty.die(e) else: manifest_file = os.path.join(spec.prefix, spack.store.layout.metadata_dir, spack.store.layout.manifest_file_name) if not os.path.exists(manifest_file): spec_id = spec.format('{name}/{hash:7}') tty.warn('No manifest file in tarball for spec %s' % spec_id) finally: shutil.rmtree(tmpdir)
def extract_tarball(spec, filename, allow_root=False, unsigned=False, force=False): """ extract binary tarball for given package into install area """ if os.path.exists(spec.prefix): if force: shutil.rmtree(spec.prefix) else: raise NoOverwriteException(str(spec.prefix)) tmpdir = tempfile.mkdtemp() stagepath = os.path.dirname(filename) spackfile_name = tarball_name(spec, '.spack') spackfile_path = os.path.join(stagepath, spackfile_name) tarfile_name = tarball_name(spec, '.tar.gz') tarfile_path = os.path.join(tmpdir, tarfile_name) specfile_name = tarball_name(spec, '.spec.yaml') specfile_path = os.path.join(tmpdir, specfile_name) with closing(tarfile.open(spackfile_path, 'r')) as tar: tar.extractall(tmpdir) if not unsigned: if os.path.exists('%s.asc' % specfile_path): try: Gpg.verify('%s.asc' % specfile_path, specfile_path) except Exception as e: shutil.rmtree(tmpdir) tty.die(str(e)) else: shutil.rmtree(tmpdir) raise NoVerifyException( "Package spec file failed signature verification.\n" "Use spack buildcache keys to download " "and install a key for verification from the mirror.") # get the sha256 checksum of the tarball checksum = checksum_tarball(tarfile_path) # get the sha256 checksum recorded at creation spec_dict = {} with open(specfile_path, 'r') as inputfile: content = inputfile.read() spec_dict = yaml.load(content) bchecksum = spec_dict['binary_cache_checksum'] # if the checksums don't match don't install if bchecksum['hash'] != checksum: shutil.rmtree(tmpdir) raise NoChecksumException( "Package tarball failed checksum verification.\n" "It cannot be installed.") new_relative_prefix = str(os.path.relpath(spec.prefix, spack.store.layout.root)) # if the original relative prefix is in the spec file use it buildinfo = spec_dict.get('buildinfo', {}) old_relative_prefix = buildinfo.get('relative_prefix', new_relative_prefix) # if the original relative prefix and new relative prefix differ the # directory layout has changed and the buildcache cannot be installed if old_relative_prefix != new_relative_prefix: shutil.rmtree(tmpdir) msg = "Package tarball was created from an install " msg += "prefix with a different directory layout.\n" msg += "It cannot be relocated." raise NewLayoutException(msg) # extract the tarball in a temp directory with closing(tarfile.open(tarfile_path, 'r')) as tar: tar.extractall(path=tmpdir) # the base of the install prefix is used when creating the tarball # so the pathname should be the same now that the directory layout # is confirmed workdir = os.path.join(tmpdir, os.path.basename(spec.prefix)) # cleanup os.remove(tarfile_path) os.remove(specfile_path) try: relocate_package(workdir, allow_root) except Exception as e: shutil.rmtree(workdir) tty.die(str(e)) # Delay creating spec.prefix until verification is complete # and any relocation has been done. else: install_tree(workdir, spec.prefix, symlinks=True) finally: shutil.rmtree(tmpdir)