2015-07-03 19:04:58 +03:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
|
|
|
|
sys.path.insert(1, os.path.dirname(sys.path[0]))
|
|
|
|
|
|
|
|
from mozharness.base.script import BaseScript
|
|
|
|
from mozharness.mozilla.bouncer.submitter import BouncerSubmitterMixin
|
2016-01-14 23:38:20 +03:00
|
|
|
from mozharness.mozilla.buildbot import BuildbotMixin
|
2015-07-03 19:04:58 +03:00
|
|
|
from mozharness.mozilla.purge import PurgeMixin
|
|
|
|
|
|
|
|
|
2016-01-14 23:38:20 +03:00
|
|
|
class BouncerSubmitter(BaseScript, PurgeMixin, BouncerSubmitterMixin, BuildbotMixin):
|
2015-07-03 19:04:58 +03:00
|
|
|
config_options = [
|
|
|
|
[["--repo"], {
|
|
|
|
"dest": "repo",
|
|
|
|
"help": "Specify source repo, e.g. releases/mozilla-beta",
|
|
|
|
}],
|
|
|
|
[["--revision"], {
|
|
|
|
"dest": "revision",
|
|
|
|
"help": "Source revision/tag used to fetch shipped-locales",
|
|
|
|
}],
|
|
|
|
[["--version"], {
|
|
|
|
"dest": "version",
|
|
|
|
"help": "Current version",
|
|
|
|
}],
|
|
|
|
[["--previous-version"], {
|
|
|
|
"dest": "prev_versions",
|
|
|
|
"action": "extend",
|
|
|
|
"help": "Previous version(s)",
|
|
|
|
}],
|
|
|
|
[["--build-number"], {
|
|
|
|
"dest": "build_number",
|
|
|
|
"help": "Build number of version",
|
|
|
|
}],
|
|
|
|
[["--bouncer-api-prefix"], {
|
|
|
|
"dest": "bouncer-api-prefix",
|
|
|
|
"help": "Bouncer admin API URL prefix",
|
|
|
|
}],
|
|
|
|
[["--credentials-file"], {
|
|
|
|
"dest": "credentials_file",
|
|
|
|
"help": "File containing Bouncer credentials",
|
|
|
|
}],
|
|
|
|
]
|
|
|
|
|
|
|
|
def __init__(self, require_config_file=True):
|
|
|
|
BaseScript.__init__(self,
|
|
|
|
config_options=self.config_options,
|
|
|
|
require_config_file=require_config_file,
|
|
|
|
# other stuff
|
|
|
|
all_actions=[
|
|
|
|
'clobber',
|
|
|
|
'download-shipped-locales',
|
|
|
|
'submit',
|
|
|
|
],
|
|
|
|
default_actions=[
|
|
|
|
'clobber',
|
|
|
|
'download-shipped-locales',
|
|
|
|
'submit',
|
|
|
|
],
|
2016-01-14 23:38:20 +03:00
|
|
|
config={
|
2017-10-25 03:21:41 +03:00
|
|
|
'buildbot_json_path': 'buildprops.json'
|
2016-01-14 23:38:20 +03:00
|
|
|
}
|
2015-07-03 19:04:58 +03:00
|
|
|
)
|
|
|
|
self.locales = None
|
|
|
|
self.credentials = None
|
|
|
|
|
|
|
|
def _pre_config_lock(self, rw_config):
|
|
|
|
super(BouncerSubmitter, self)._pre_config_lock(rw_config)
|
|
|
|
|
2017-10-25 03:21:41 +03:00
|
|
|
# override properties from buildbot properties here as defined by taskcluster properties
|
2016-01-14 23:38:20 +03:00
|
|
|
self.read_buildbot_config()
|
|
|
|
|
2017-10-25 03:21:41 +03:00
|
|
|
# check if release promotion is true first before overwriting these properties
|
2016-01-14 23:38:20 +03:00
|
|
|
if self.buildbot_config["properties"].get("release_promotion"):
|
2017-10-25 03:21:41 +03:00
|
|
|
for prop in \
|
|
|
|
['product', 'version', 'build_number', 'revision',
|
|
|
|
'bouncer_submitter_config', ]:
|
2016-01-14 23:38:20 +03:00
|
|
|
if self.buildbot_config["properties"].get(prop):
|
2017-10-25 03:21:41 +03:00
|
|
|
self.info("Overriding %s with %s" %
|
|
|
|
(prop, self.buildbot_config["properties"].get(prop)))
|
2016-01-14 23:38:20 +03:00
|
|
|
self.config[prop] = self.buildbot_config["properties"].get(prop)
|
|
|
|
if self.buildbot_config["properties"].get("partial_versions"):
|
2017-10-25 03:21:41 +03:00
|
|
|
self.config["prev_versions"] = \
|
|
|
|
self.buildbot_config["properties"].get("partial_versions").split(", ")
|
2016-01-14 23:38:20 +03:00
|
|
|
|
2015-07-03 19:04:58 +03:00
|
|
|
for opt in ["version", "credentials_file", "bouncer-api-prefix"]:
|
|
|
|
if opt not in self.config:
|
|
|
|
self.fatal("%s must be specified" % opt)
|
|
|
|
if self.need_shipped_locales():
|
|
|
|
for opt in ["shipped-locales-url", "repo", "revision"]:
|
|
|
|
if opt not in self.config:
|
|
|
|
self.fatal("%s must be specified" % opt)
|
|
|
|
|
|
|
|
def need_shipped_locales(self):
|
|
|
|
return any(e.get("add-locales") for e in
|
|
|
|
self.config["products"].values())
|
|
|
|
|
|
|
|
def query_shipped_locales_path(self):
|
|
|
|
dirs = self.query_abs_dirs()
|
|
|
|
return os.path.join(dirs["abs_work_dir"], "shipped-locales")
|
|
|
|
|
|
|
|
def download_shipped_locales(self):
|
|
|
|
if not self.need_shipped_locales():
|
|
|
|
self.info("No need to download shipped-locales")
|
|
|
|
return
|
|
|
|
|
|
|
|
replace_dict = {"revision": self.config["revision"],
|
|
|
|
"repo": self.config["repo"]}
|
|
|
|
url = self.config["shipped-locales-url"] % replace_dict
|
|
|
|
dirs = self.query_abs_dirs()
|
|
|
|
self.mkdir_p(dirs["abs_work_dir"])
|
|
|
|
if not self.download_file(url=url,
|
|
|
|
file_name=self.query_shipped_locales_path()):
|
|
|
|
self.fatal("Unable to fetch shipped-locales from %s" % url)
|
|
|
|
# populate the list
|
|
|
|
self.load_shipped_locales()
|
|
|
|
|
|
|
|
def load_shipped_locales(self):
|
|
|
|
if self.locales:
|
|
|
|
return self.locales
|
|
|
|
content = self.read_from_file(self.query_shipped_locales_path())
|
|
|
|
locales = []
|
|
|
|
for line in content.splitlines():
|
|
|
|
locale = line.split()[0]
|
|
|
|
if locale:
|
|
|
|
locales.append(locale)
|
|
|
|
self.locales = locales
|
|
|
|
return self.locales
|
|
|
|
|
|
|
|
def submit(self):
|
|
|
|
subs = {
|
|
|
|
"version": self.config["version"]
|
|
|
|
}
|
|
|
|
if self.config.get("build_number"):
|
|
|
|
subs["build_number"] = self.config["build_number"]
|
|
|
|
|
|
|
|
for product, pr_config in sorted(self.config["products"].items()):
|
|
|
|
product_name = pr_config["product-name"] % subs
|
|
|
|
if self.product_exists(product_name):
|
|
|
|
self.warning("Product %s already exists. Skipping..." %
|
|
|
|
product_name)
|
|
|
|
continue
|
|
|
|
self.info("Adding %s..." % product)
|
|
|
|
self.api_add_product(
|
|
|
|
product_name=product_name,
|
|
|
|
add_locales=pr_config.get("add-locales"),
|
|
|
|
ssl_only=pr_config.get("ssl-only"))
|
|
|
|
self.info("Adding paths...")
|
|
|
|
for platform, pl_config in sorted(pr_config["paths"].items()):
|
|
|
|
bouncer_platform = pl_config["bouncer-platform"]
|
|
|
|
path = pl_config["path"] % subs
|
|
|
|
self.info("%s (%s): %s" % (platform, bouncer_platform, path))
|
|
|
|
self.api_add_location(product_name, bouncer_platform, path)
|
|
|
|
|
|
|
|
# Add partial updates
|
|
|
|
if "partials" in self.config and self.config.get("prev_versions"):
|
|
|
|
self.submit_partials()
|
|
|
|
|
|
|
|
def submit_partials(self):
|
|
|
|
subs = {
|
|
|
|
"version": self.config["version"]
|
|
|
|
}
|
|
|
|
if self.config.get("build_number"):
|
|
|
|
subs["build_number"] = self.config["build_number"]
|
|
|
|
prev_versions = self.config.get("prev_versions")
|
|
|
|
for product, part_config in sorted(self.config["partials"].items()):
|
|
|
|
product_name_tmpl = part_config["product-name"]
|
|
|
|
for prev_version in prev_versions:
|
|
|
|
prev_version, prev_build_number = prev_version.split("build")
|
|
|
|
subs["prev_version"] = prev_version
|
|
|
|
subs["prev_build_number"] = prev_build_number
|
|
|
|
product_name = product_name_tmpl % subs
|
|
|
|
if self.product_exists(product_name):
|
|
|
|
self.warning("Product %s already exists. Skipping..." %
|
2016-01-14 23:38:20 +03:00
|
|
|
product_name)
|
2015-07-03 19:04:58 +03:00
|
|
|
continue
|
|
|
|
self.info("Adding partial updates for %s" % product_name)
|
|
|
|
self.api_add_product(
|
|
|
|
product_name=product_name,
|
|
|
|
add_locales=part_config.get("add-locales"),
|
|
|
|
ssl_only=part_config.get("ssl-only"))
|
|
|
|
for platform, pl_config in sorted(part_config["paths"].items()):
|
|
|
|
bouncer_platform = pl_config["bouncer-platform"]
|
|
|
|
path = pl_config["path"] % subs
|
|
|
|
self.info("%s (%s): %s" % (platform, bouncer_platform, path))
|
|
|
|
self.api_add_location(product_name, bouncer_platform, path)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
myScript = BouncerSubmitter()
|
|
|
|
myScript.run_and_exit()
|