Bug 1383996 - Add an argument to `mach artifact toolchain` to store a manifest for chain-of-trust validation. r=gps

Chain of trust validation will require to know what the inputs for a
given build are, and mach artifact toolchain fetches such inputs.

So we make it output a manifest that the chain of trust validation
process will be able to use and correlate with other information, such
as the one from bug 1383993.

At the same time, we make the produced manifest contain information
about tooltool-downloaded packages, which will allow to track the
progress in the migration from tooltool to TC artifacts.

--HG--
extra : rebase_source : 5b3fc32a9fd641cc7edc57865d2b60aaa6ffcbed
This commit is contained in:
Mike Hommey 2017-07-20 17:52:56 +09:00
Родитель 9f479750e6
Коммит 7decc31f76
1 изменённых файлов: 25 добавлений и 1 удалений

Просмотреть файл

@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import argparse
import collections
import errno
import hashlib
import itertools
import json
import logging
@ -38,6 +39,7 @@ from mozbuild.base import (
MozconfigLoadException,
ObjdirMismatchException,
)
from mozbuild.util import ensureParentDir
from mozbuild.backend import (
backends,
@ -1691,6 +1693,8 @@ class PackageFrontend(MachCommandBase):
help='Do not unpack any downloaded file')
@CommandArgument('--retry', type=int, default=0,
help='Number of times to retry failed downloads')
@CommandArgument('--artifact-manifest', metavar='FILE',
help='Store a manifest about the downloaded taskcluster artifacts')
@CommandArgument('files', nargs='*',
help='A list of files to download, in the form path@task-id, in '
'addition to the files listed in the tooltool manifest.')
@ -1698,7 +1702,7 @@ class PackageFrontend(MachCommandBase):
skip_cache=False, from_build=(),
tooltool_manifest=None, authentication_file=None,
tooltool_url=None, no_unpack=False, retry=None,
files=()):
artifact_manifest=None, files=()):
'''Download, cache and install pre-built toolchains.
'''
from mozbuild.artifacts import ArtifactCache
@ -1916,6 +1920,8 @@ class PackageFrontend(MachCommandBase):
'Failed to download {name}')
return 1
artifacts = {} if artifact_manifest else None
for record in downloaded:
local = os.path.join(os.getcwd(), record.basename)
if os.path.exists(local):
@ -1928,6 +1934,19 @@ class PackageFrontend(MachCommandBase):
os.link(record.filename, local)
except Exception:
shutil.copy(record.filename, local)
# Keep a sha256 of each downloaded file, for the chain-of-trust
# validation.
if artifact_manifest is not None:
with open(local) as fh:
h = hashlib.sha256()
while True:
data = fh.read(1024 * 1024)
if not data:
break
h.update(data)
artifacts[record.url] = {
'sha256': h.hexdigest(),
}
if record.unpack and not no_unpack:
unpack_file(local, record.setup)
os.unlink(local)
@ -1937,6 +1956,11 @@ class PackageFrontend(MachCommandBase):
if files:
return 1
if artifacts:
ensureParentDir(artifact_manifest)
with open(artifact_manifest, 'w') as fh:
json.dump(artifacts, fh, indent=4, sort_keys=True)
return 0