2015-02-10 13:19:34 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; version 2 of the License.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Library General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2015-06-06 14:32:17 +00:00
|
|
|
|
2015-02-10 13:19:34 +00:00
|
|
|
import os
|
|
|
|
import time
|
|
|
|
|
|
|
|
import productmd.composeinfo
|
|
|
|
import productmd.treeinfo
|
2015-03-14 17:21:27 +00:00
|
|
|
from productmd.common import get_major_version
|
2015-02-10 13:19:34 +00:00
|
|
|
from kobo.shortcuts import relative_path
|
|
|
|
|
2015-03-12 21:12:38 +00:00
|
|
|
from pungi.compose_metadata.discinfo import write_discinfo as create_discinfo
|
|
|
|
from pungi.compose_metadata.discinfo import write_media_repo as create_media_repo
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_description(compose, variant, arch):
|
2015-07-09 10:58:30 +00:00
|
|
|
if "release_discinfo_description" in compose.conf:
|
|
|
|
result = compose.conf["release_discinfo_description"]
|
2015-02-10 13:19:34 +00:00
|
|
|
elif variant.type == "layered-product":
|
|
|
|
# we need to make sure the layered product behaves as it was composed separately
|
2015-07-09 10:58:30 +00:00
|
|
|
result = "%s %s for %s %s" % (variant.release_name, variant.release_version, compose.conf["release_name"], get_major_version(compose.conf["release_version"]))
|
2015-02-10 13:19:34 +00:00
|
|
|
else:
|
2015-07-09 10:58:30 +00:00
|
|
|
result = "%s %s" % (compose.conf["release_name"], compose.conf["release_version"])
|
|
|
|
if compose.conf.get("release_is_layered", False):
|
2016-05-04 13:22:23 +00:00
|
|
|
result += " for %s %s" % (compose.conf["base_product_name"], compose.conf["base_product_version"])
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
result = result % {"variant_name": variant.name, "arch": arch}
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def write_discinfo(compose, arch, variant):
|
|
|
|
if variant.type == "addon":
|
|
|
|
return
|
|
|
|
os_tree = compose.paths.compose.os_tree(arch, variant)
|
|
|
|
path = os.path.join(os_tree, ".discinfo")
|
|
|
|
# description = get_volid(compose, arch, variant)
|
|
|
|
description = get_description(compose, variant, arch)
|
|
|
|
return create_discinfo(path, description, arch)
|
|
|
|
|
|
|
|
|
|
|
|
def write_media_repo(compose, arch, variant, timestamp=None):
|
|
|
|
if variant.type == "addon":
|
|
|
|
return
|
|
|
|
os_tree = compose.paths.compose.os_tree(arch, variant)
|
|
|
|
path = os.path.join(os_tree, "media.repo")
|
|
|
|
# description = get_volid(compose, arch, variant)
|
|
|
|
description = get_description(compose, variant, arch)
|
|
|
|
return create_media_repo(path, description, timestamp)
|
|
|
|
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
def compose_to_composeinfo(compose):
|
|
|
|
ci = productmd.composeinfo.ComposeInfo()
|
|
|
|
|
|
|
|
# compose
|
|
|
|
ci.compose.id = compose.compose_id
|
|
|
|
ci.compose.type = compose.compose_type
|
|
|
|
ci.compose.date = compose.compose_date
|
|
|
|
ci.compose.respin = compose.compose_respin
|
|
|
|
ci.compose.label = compose.compose_label
|
|
|
|
|
|
|
|
# product
|
2015-07-09 10:58:30 +00:00
|
|
|
ci.release.name = compose.conf["release_name"]
|
|
|
|
ci.release.version = compose.conf["release_version"]
|
|
|
|
ci.release.short = compose.conf["release_short"]
|
|
|
|
ci.release.is_layered = compose.conf.get("release_is_layered", False)
|
2015-08-25 12:04:06 +00:00
|
|
|
ci.release.type = compose.conf.get("release_type", "ga").lower()
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
# base product
|
2015-06-06 15:52:08 +00:00
|
|
|
if ci.release.is_layered:
|
2015-06-06 14:32:17 +00:00
|
|
|
ci.base_product.name = compose.conf["base_product_name"]
|
|
|
|
ci.base_product.version = compose.conf["base_product_version"]
|
|
|
|
ci.base_product.short = compose.conf["base_product_short"]
|
2016-05-23 12:12:23 +00:00
|
|
|
ci.base_product.type = compose.conf.get("base_product_type", "ga").lower()
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
def dump_variant(variant, parent=None):
|
|
|
|
var = productmd.composeinfo.Variant(ci)
|
|
|
|
|
|
|
|
tree_arches = compose.conf.get("tree_arches", None)
|
|
|
|
if tree_arches and not (set(variant.arches) & set(tree_arches)):
|
|
|
|
return None
|
|
|
|
|
|
|
|
# variant details
|
2016-06-02 10:43:27 +00:00
|
|
|
# remove dashes from variant ID, rely on productmd verification
|
|
|
|
var.id = variant.id.replace("-", "")
|
2015-06-06 14:32:17 +00:00
|
|
|
var.uid = variant.uid
|
|
|
|
var.name = variant.name
|
|
|
|
var.type = variant.type
|
|
|
|
var.arches = set(variant.arches)
|
|
|
|
|
|
|
|
if var.type == "layered-product":
|
2015-07-09 10:58:30 +00:00
|
|
|
var.release.name = variant.release_name
|
|
|
|
var.release.short = variant.release_short
|
|
|
|
var.release.version = variant.release_version
|
2015-06-06 15:52:08 +00:00
|
|
|
var.release.is_layered = True
|
2015-08-25 12:04:06 +00:00
|
|
|
var.release.type = ci.release.type
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
for arch in variant.arches:
|
|
|
|
# paths: binaries
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.os_tree[arch] = relative_path(compose.paths.compose.os_tree(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.repository[arch] = relative_path(compose.paths.compose.repository(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.packages[arch] = relative_path(compose.paths.compose.packages(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
iso_dir = compose.paths.compose.iso_dir(arch=arch, variant=variant, create_dir=False) or ""
|
|
|
|
if iso_dir and os.path.isdir(os.path.join(compose.paths.compose.topdir(), iso_dir)):
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.isos[arch] = relative_path(iso_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
jigdo_dir = compose.paths.compose.jigdo_dir(arch=arch, variant=variant, create_dir=False) or ""
|
|
|
|
if jigdo_dir and os.path.isdir(os.path.join(compose.paths.compose.topdir(), jigdo_dir)):
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.jigdos[arch] = relative_path(jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
# paths: sources
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.source_tree[arch] = relative_path(compose.paths.compose.os_tree(arch="source", variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.source_repository[arch] = relative_path(compose.paths.compose.repository(arch="source", variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.source_packages[arch] = relative_path(compose.paths.compose.packages(arch="source", variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
source_iso_dir = compose.paths.compose.iso_dir(arch="source", variant=variant, create_dir=False) or ""
|
|
|
|
if source_iso_dir and os.path.isdir(os.path.join(compose.paths.compose.topdir(), source_iso_dir)):
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.source_isos[arch] = relative_path(source_iso_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
source_jigdo_dir = compose.paths.compose.jigdo_dir(arch="source", variant=variant, create_dir=False) or ""
|
|
|
|
if source_jigdo_dir and os.path.isdir(os.path.join(compose.paths.compose.topdir(), source_jigdo_dir)):
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.source_jigdos[arch] = relative_path(source_jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
|
|
|
|
# paths: debug
|
2015-06-06 15:52:08 +00:00
|
|
|
var.paths.debug_tree[arch] = relative_path(compose.paths.compose.debug_tree(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.debug_repository[arch] = relative_path(compose.paths.compose.debug_repository(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
var.paths.debug_packages[arch] = relative_path(compose.paths.compose.debug_packages(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
2015-06-06 14:32:17 +00:00
|
|
|
'''
|
|
|
|
# XXX: not suported (yet?)
|
|
|
|
debug_iso_dir = compose.paths.compose.debug_iso_dir(arch=arch, variant=variant) or ""
|
|
|
|
if debug_iso_dir:
|
|
|
|
var.debug_iso_dir[arch] = relative_path(debug_iso_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
debug_jigdo_dir = compose.paths.compose.debug_jigdo_dir(arch=arch, variant=variant) or ""
|
|
|
|
if debug_jigdo_dir:
|
|
|
|
var.debug_jigdo_dir[arch] = relative_path(debug_jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/").rstrip("/")
|
|
|
|
'''
|
|
|
|
|
|
|
|
for v in variant.get_variants(recursive=False):
|
|
|
|
x = dump_variant(v, parent=variant)
|
|
|
|
if x is not None:
|
|
|
|
var.add(x)
|
|
|
|
return var
|
|
|
|
|
|
|
|
for variant_id in sorted(compose.variants):
|
|
|
|
variant = compose.variants[variant_id]
|
|
|
|
v = dump_variant(variant)
|
|
|
|
if v is not None:
|
|
|
|
ci.variants.add(v)
|
|
|
|
return ci
|
|
|
|
|
|
|
|
|
2015-02-10 13:19:34 +00:00
|
|
|
def write_compose_info(compose):
|
2015-06-06 14:32:17 +00:00
|
|
|
ci = compose_to_composeinfo(compose)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
msg = "Writing composeinfo"
|
|
|
|
compose.log_info("[BEGIN] %s" % msg)
|
|
|
|
|
|
|
|
path = compose.paths.compose.metadata("composeinfo.json")
|
|
|
|
ci.dump(path)
|
|
|
|
|
|
|
|
compose.log_info("[DONE ] %s" % msg)
|
|
|
|
|
|
|
|
|
|
|
|
def write_tree_info(compose, arch, variant, timestamp=None):
|
2016-02-16 09:23:08 +00:00
|
|
|
if variant.type in ("addon", ) or variant.is_empty:
|
2015-02-10 13:19:34 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
if not timestamp:
|
|
|
|
timestamp = int(time.time())
|
|
|
|
else:
|
|
|
|
timestamp = int(timestamp)
|
|
|
|
|
|
|
|
os_tree = compose.paths.compose.os_tree(arch=arch, variant=variant).rstrip("/") + "/"
|
|
|
|
|
|
|
|
ti = productmd.treeinfo.TreeInfo()
|
|
|
|
# load from buildinstall .treeinfo
|
|
|
|
|
|
|
|
if variant.type == "layered-product":
|
|
|
|
# we need to make sure the layered product behaves as it was composed separately
|
|
|
|
|
2015-07-09 10:58:30 +00:00
|
|
|
# release
|
2015-02-10 13:19:34 +00:00
|
|
|
# TODO: read from variants.xml
|
2015-07-09 10:58:30 +00:00
|
|
|
ti.release.name = variant.release_name
|
|
|
|
ti.release.version = variant.release_version
|
|
|
|
ti.release.short = variant.release_short
|
2015-06-05 22:04:24 +00:00
|
|
|
ti.release.is_layered = True
|
2015-08-25 12:04:06 +00:00
|
|
|
ti.release.type = compose.conf.get("release_type", "ga").lower()
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
# base product
|
2015-07-09 10:58:30 +00:00
|
|
|
ti.base_product.name = compose.conf["release_name"]
|
|
|
|
if "." in compose.conf["release_version"]:
|
2015-02-10 13:19:34 +00:00
|
|
|
# remove minor version if present
|
2015-07-09 10:58:30 +00:00
|
|
|
ti.base_product.version = get_major_version(compose.conf["release_version"])
|
2015-02-10 13:19:34 +00:00
|
|
|
else:
|
2015-07-09 10:58:30 +00:00
|
|
|
ti.base_product.version = compose.conf["release_version"]
|
|
|
|
ti.base_product.short = compose.conf["release_short"]
|
2015-02-10 13:19:34 +00:00
|
|
|
else:
|
2015-07-09 10:58:30 +00:00
|
|
|
# release
|
|
|
|
ti.release.name = compose.conf["release_name"]
|
|
|
|
ti.release.version = compose.conf["release_version"]
|
|
|
|
ti.release.short = compose.conf["release_short"]
|
|
|
|
ti.release.is_layered = compose.conf.get("release_is_layered", False)
|
2015-08-25 12:04:06 +00:00
|
|
|
ti.release.type = compose.conf.get("release_type", "ga").lower()
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
# base product
|
2015-06-05 22:04:24 +00:00
|
|
|
if ti.release.is_layered:
|
2015-02-10 13:19:34 +00:00
|
|
|
ti.base_product.name = compose.conf["base_product_name"]
|
|
|
|
ti.base_product.version = compose.conf["base_product_version"]
|
|
|
|
ti.base_product.short = compose.conf["base_product_short"]
|
|
|
|
|
|
|
|
# tree
|
|
|
|
ti.tree.arch = arch
|
|
|
|
ti.tree.build_timestamp = timestamp
|
|
|
|
# ti.platforms
|
|
|
|
|
|
|
|
# main variant
|
|
|
|
var = productmd.treeinfo.Variant(ti)
|
|
|
|
if variant.type == "layered-product":
|
|
|
|
var.id = variant.parent.id
|
|
|
|
var.uid = variant.parent.uid
|
|
|
|
var.name = variant.parent.name
|
|
|
|
var.type = "variant"
|
|
|
|
else:
|
2016-06-02 10:43:27 +00:00
|
|
|
# remove dashes from variant ID, rely on productmd verification
|
|
|
|
var.id = variant.id.replace("-", "")
|
2015-02-10 13:19:34 +00:00
|
|
|
var.uid = variant.uid
|
|
|
|
var.name = variant.name
|
|
|
|
var.type = variant.type
|
|
|
|
|
|
|
|
var.packages = relative_path(compose.paths.compose.packages(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", os_tree).rstrip("/") or "."
|
|
|
|
var.repository = relative_path(compose.paths.compose.repository(arch=arch, variant=variant, create_dir=False).rstrip("/") + "/", os_tree).rstrip("/") or "."
|
|
|
|
|
|
|
|
ti.variants.add(var)
|
|
|
|
|
|
|
|
repomd_path = os.path.join(var.repository, "repodata", "repomd.xml")
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(repomd_path, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
for i in variant.get_variants(types=["addon"], arch=arch):
|
|
|
|
addon = productmd.treeinfo.Variant(ti)
|
|
|
|
addon.id = i.id
|
|
|
|
addon.uid = i.uid
|
|
|
|
addon.name = i.name
|
|
|
|
addon.type = i.type
|
|
|
|
|
|
|
|
os_tree = compose.paths.compose.os_tree(arch=arch, variant=i).rstrip("/") + "/"
|
|
|
|
addon.packages = relative_path(compose.paths.compose.packages(arch=arch, variant=i, create_dir=False).rstrip("/") + "/", os_tree).rstrip("/") or "."
|
|
|
|
addon.repository = relative_path(compose.paths.compose.repository(arch=arch, variant=i, create_dir=False).rstrip("/") + "/", os_tree).rstrip("/") or "."
|
|
|
|
var.add(addon)
|
|
|
|
|
|
|
|
repomd_path = os.path.join(addon.repository, "repodata", "repomd.xml")
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(repomd_path, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
2015-06-05 22:04:24 +00:00
|
|
|
class LoraxProduct(productmd.treeinfo.Release):
|
2015-02-10 13:19:34 +00:00
|
|
|
def _check_short(self):
|
|
|
|
# HACK: set self.short so .treeinfo produced by lorax can be read
|
|
|
|
if not self.short:
|
2015-07-09 10:58:30 +00:00
|
|
|
self.short = compose.conf["release_short"]
|
2015-02-10 13:19:34 +00:00
|
|
|
|
2015-06-06 14:27:02 +00:00
|
|
|
class LoraxTreeInfo(productmd.treeinfo.TreeInfo):
|
2015-02-10 13:19:34 +00:00
|
|
|
def clear(self):
|
2015-06-06 14:27:02 +00:00
|
|
|
super(LoraxTreeInfo, self).clear()
|
2015-02-10 13:19:34 +00:00
|
|
|
self.product = LoraxProduct(self)
|
|
|
|
|
|
|
|
# images
|
|
|
|
if variant.type == "variant":
|
|
|
|
os_tree = compose.paths.compose.os_tree(arch, variant)
|
|
|
|
|
|
|
|
# clone all but 'general' sections from buildinstall .treeinfo
|
2016-01-06 12:35:01 +00:00
|
|
|
bi_treeinfo = os.path.join(compose.paths.work.buildinstall_dir(arch), variant.uid, ".treeinfo")
|
2015-02-10 13:19:34 +00:00
|
|
|
if os.path.exists(bi_treeinfo):
|
|
|
|
bi_ti = LoraxTreeInfo()
|
|
|
|
bi_ti.load(bi_treeinfo)
|
|
|
|
|
|
|
|
# stage2 - mainimage
|
|
|
|
if bi_ti.stage2.mainimage:
|
|
|
|
ti.stage2.mainimage = bi_ti.stage2.mainimage
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(ti.stage2.mainimage, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
# stage2 - instimage
|
|
|
|
if bi_ti.stage2.instimage:
|
|
|
|
ti.stage2.instimage = bi_ti.stage2.instimage
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(ti.stage2.instimage, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
# images
|
|
|
|
for platform in bi_ti.images.images:
|
|
|
|
ti.images.images[platform] = {}
|
|
|
|
ti.tree.platforms.add(platform)
|
|
|
|
for image, path in bi_ti.images.images[platform].items():
|
2016-03-16 14:24:37 +00:00
|
|
|
if not path:
|
|
|
|
# The .treeinfo file contains an image without a path.
|
|
|
|
# We can't add that.
|
|
|
|
continue
|
2015-02-10 13:19:34 +00:00
|
|
|
ti.images.images[platform][image] = path
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(path, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
# add product.img to images-$arch
|
|
|
|
product_img = os.path.join(os_tree, "images", "product.img")
|
|
|
|
product_img_relpath = relative_path(product_img, os_tree.rstrip("/") + "/")
|
|
|
|
if os.path.isfile(product_img):
|
|
|
|
for platform in ti.images.images:
|
|
|
|
ti.images.images[platform]["product.img"] = product_img_relpath
|
2015-07-24 14:49:28 +00:00
|
|
|
ti.checksums.add(product_img_relpath, "sha256", root_dir=os_tree)
|
2015-02-10 13:19:34 +00:00
|
|
|
|
|
|
|
path = os.path.join(compose.paths.compose.os_tree(arch=arch, variant=variant), ".treeinfo")
|
|
|
|
compose.log_info("Writing treeinfo: %s" % path)
|
|
|
|
ti.dump(path)
|