blob: 5a4683df56e61d1cd526c6af6a078536b73315c2 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import datetime
import hashlib
import json
import os
import shutil
import sys
index_template = {
'format': 'index:1.0',
'index': {
'images': {
'path': 'streams/v1/images.json',
'datatype': 'image-downloads',
'products': [
],
}
}
}
images_template = {
'datatype': 'image-downloads',
'format': 'products:1.0',
'content_id': 'images',
'products': {}
}
def sha256sum(paths):
sha256 = hashlib.sha256()
for path in paths:
with open(path, 'rb') as f:
page = f.read(4096)
while page != b"":
sha256.update(page)
page = f.read(4096)
return sha256.hexdigest()
def image_path(distro, release, arch, image_type, version):
return 'images/{0}/{1}/{2}/{3}/{4}'.format(distro, release, arch, image_type, version)
def create_product(distro, arch, os_desc, release, image_type, version, rootfs_squash, lxd_tarball):
img_path = image_path(distro, release, arch, image_type, version)
rootfs_squash_stat = os.stat(rootfs_squash)
rootfs_squash_sha256 = sha256sum([rootfs_squash])
rootfs_squash_item = {
'size': rootfs_squash_stat.st_size,
'path': '{}/rootfs.squashfs'.format(img_path),
'sha256': rootfs_squash_sha256,
'ftype': 'squashfs'
}
lxd_stat = os.stat(lxd_tarball)
lxd_sha256 = sha256sum([lxd_tarball])
combined_squash_sha256 = sha256sum([lxd_tarball, rootfs_squash])
lxd_item = {
'size': lxd_stat.st_size,
'path': '{}/lxd.tar.xz'.format(img_path),
'combined_squashfs_sha256': combined_squash_sha256,
'sha256': lxd_sha256,
'ftype': 'lxd.tar.xz'
}
product = {
'aliases': '{0}/{1}/{2},{0}/{1}/{2}/{3}'.format(distro, release, image_type, arch),
'arch': arch,
'os': os_desc,
'release_title': release,
'release': release,
'versions': {}
}
if image_type == 'default':
product['aliases'] += ',{0}/{1},{0}/{1}/{2}'.format(distro, release, arch)
product['versions'][version] = {
'items': {
'rootfs.squashfs': rootfs_squash_item,
'lxd.tar.xz': lxd_item
}
}
return product
def main():
parser = argparse.ArgumentParser(description='Create simplestreams .json files.')
parser.add_argument('in_dir', help='input directory tree of container rootfs tarballs')
parser.add_argument('out_dir', help='output directory')
args = parser.parse_args()
try:
os.makedirs(args.out_dir)
except:
print('Failed to create out directory')
sys.exit(1)
date = datetime.datetime.utcnow().strftime('%Y%m%d_%H:%M')
index = index_template.copy()
images = images_template.copy()
expected_files = {'lxd.tar.xz', 'rootfs.squashfs'}
for root, dirs, files in os.walk(args.in_dir):
files_set = set(files)
if len(expected_files.intersection(files_set)) != len(expected_files):
continue
split_dirs = root.split('/')
if len(split_dirs) < 4:
continue
# Format is /path/to/in_dir/distro/release/arch/image_type.
distro = split_dirs[-4]
release = split_dirs[-3]
arch = split_dirs[-2]
image_type = split_dirs[-1]
rootfs_squash_source_path = os.path.join(root, 'rootfs.squashfs')
lxd_source_path = os.path.join(root, 'lxd.tar.xz')
product_name = '{}:{}:{}:{}'.format(distro, release, arch, image_type)
index['index']['images']['products'].append(product_name)
product = create_product(distro,
arch,
"Debian",
release,
image_type,
date,
rootfs_squash_source_path,
lxd_source_path)
images['products'][product_name] = product
out_images_path = os.path.join(args.out_dir,
image_path(distro, release, arch, image_type, date))
lxd_path = os.path.join(out_images_path, "lxd.tar.xz")
rootfs_squash_path = os.path.join(out_images_path, "rootfs.squashfs")
try:
print(out_images_path)
os.makedirs(out_images_path)
except:
print('Failed to create images directory')
sys.exit(1)
shutil.copy(lxd_source_path, lxd_path)
shutil.copy(rootfs_squash_source_path, rootfs_squash_path)
stream_path = os.path.join(args.out_dir, 'streams/v1')
try:
os.makedirs(stream_path)
except:
print('Failed to create streams directory')
sys.exit(1)
index_path = os.path.join(stream_path, 'index.json')
images_path = os.path.join(stream_path, 'images.json')
with open(index_path, 'w') as index_file:
json.dump(index, index_file)
with open(images_path, 'w') as images_file:
json.dump(images, images_file)
if __name__ == '__main__':
main()