2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 sys
.path
.insert(1, os
.path
.dirname(sys
.path
[0]))
11 from mozharness
.base
.script
import BaseScript
12 from mozharness
.mozilla
.bouncer
.submitter
import BouncerSubmitterMixin
13 from mozharness
.mozilla
.buildbot
import BuildbotMixin
14 from mozharness
.mozilla
.purge
import PurgeMixin
17 class BouncerSubmitter(BaseScript
, PurgeMixin
, BouncerSubmitterMixin
, BuildbotMixin
):
21 "help": "Specify source repo, e.g. releases/mozilla-beta",
25 "help": "Source revision/tag used to fetch shipped-locales",
29 "help": "Current version",
31 [["--previous-version"], {
32 "dest": "prev_versions",
34 "help": "Previous version(s)",
36 [["--build-number"], {
37 "dest": "build_number",
38 "help": "Build number of version",
40 [["--bouncer-api-prefix"], {
41 "dest": "bouncer-api-prefix",
42 "help": "Bouncer admin API URL prefix",
44 [["--credentials-file"], {
45 "dest": "credentials_file",
46 "help": "File containing Bouncer credentials",
50 def __init__(self
, require_config_file
=True):
51 BaseScript
.__init
__(self
,
52 config_options
=self
.config_options
,
53 require_config_file
=require_config_file
,
57 'download-shipped-locales',
62 'download-shipped-locales',
66 'buildbot_json_path' : 'buildprops.json'
70 self
.credentials
= None
72 def _pre_config_lock(self
, rw_config
):
73 super(BouncerSubmitter
, self
)._pre
_config
_lock
(rw_config
)
75 #override properties from buildbot properties here as defined by taskcluster properties
76 self
.read_buildbot_config()
78 #check if release promotion is true first before overwriting these properties
79 if self
.buildbot_config
["properties"].get("release_promotion"):
80 for prop
in ['product', 'version', 'build_number', 'revision', 'bouncer_submitter_config', ]:
81 if self
.buildbot_config
["properties"].get(prop
):
82 self
.info("Overriding %s with %s" % (prop
, self
.buildbot_config
["properties"].get(prop
)))
83 self
.config
[prop
] = self
.buildbot_config
["properties"].get(prop
)
84 if self
.buildbot_config
["properties"].get("partial_versions"):
85 self
.config
["prev_versions"] = self
.buildbot_config
["properties"].get("partial_versions").split(", ")
87 for opt
in ["version", "credentials_file", "bouncer-api-prefix"]:
88 if opt
not in self
.config
:
89 self
.fatal("%s must be specified" % opt
)
90 if self
.need_shipped_locales():
91 for opt
in ["shipped-locales-url", "repo", "revision"]:
92 if opt
not in self
.config
:
93 self
.fatal("%s must be specified" % opt
)
95 def need_shipped_locales(self
):
96 return any(e
.get("add-locales") for e
in
97 self
.config
["products"].values())
99 def query_shipped_locales_path(self
):
100 dirs
= self
.query_abs_dirs()
101 return os
.path
.join(dirs
["abs_work_dir"], "shipped-locales")
103 def download_shipped_locales(self
):
104 if not self
.need_shipped_locales():
105 self
.info("No need to download shipped-locales")
108 replace_dict
= {"revision": self
.config
["revision"],
109 "repo": self
.config
["repo"]}
110 url
= self
.config
["shipped-locales-url"] % replace_dict
111 dirs
= self
.query_abs_dirs()
112 self
.mkdir_p(dirs
["abs_work_dir"])
113 if not self
.download_file(url
=url
,
114 file_name
=self
.query_shipped_locales_path()):
115 self
.fatal("Unable to fetch shipped-locales from %s" % url
)
117 self
.load_shipped_locales()
119 def load_shipped_locales(self
):
122 content
= self
.read_from_file(self
.query_shipped_locales_path())
124 for line
in content
.splitlines():
125 locale
= line
.split()[0]
127 locales
.append(locale
)
128 self
.locales
= locales
133 "version": self
.config
["version"]
135 if self
.config
.get("build_number"):
136 subs
["build_number"] = self
.config
["build_number"]
138 for product
, pr_config
in sorted(self
.config
["products"].items()):
139 product_name
= pr_config
["product-name"] % subs
140 if self
.product_exists(product_name
):
141 self
.warning("Product %s already exists. Skipping..." %
144 self
.info("Adding %s..." % product
)
145 self
.api_add_product(
146 product_name
=product_name
,
147 add_locales
=pr_config
.get("add-locales"),
148 ssl_only
=pr_config
.get("ssl-only"))
149 self
.info("Adding paths...")
150 for platform
, pl_config
in sorted(pr_config
["paths"].items()):
151 bouncer_platform
= pl_config
["bouncer-platform"]
152 path
= pl_config
["path"] % subs
153 self
.info("%s (%s): %s" % (platform
, bouncer_platform
, path
))
154 self
.api_add_location(product_name
, bouncer_platform
, path
)
156 # Add partial updates
157 if "partials" in self
.config
and self
.config
.get("prev_versions"):
158 self
.submit_partials()
160 def submit_partials(self
):
162 "version": self
.config
["version"]
164 if self
.config
.get("build_number"):
165 subs
["build_number"] = self
.config
["build_number"]
166 prev_versions
= self
.config
.get("prev_versions")
167 for product
, part_config
in sorted(self
.config
["partials"].items()):
168 product_name_tmpl
= part_config
["product-name"]
169 for prev_version
in prev_versions
:
170 prev_version
, prev_build_number
= prev_version
.split("build")
171 subs
["prev_version"] = prev_version
172 subs
["prev_build_number"] = prev_build_number
173 product_name
= product_name_tmpl
% subs
174 if self
.product_exists(product_name
):
175 self
.warning("Product %s already exists. Skipping..." %
178 self
.info("Adding partial updates for %s" % product_name
)
179 self
.api_add_product(
180 product_name
=product_name
,
181 add_locales
=part_config
.get("add-locales"),
182 ssl_only
=part_config
.get("ssl-only"))
183 for platform
, pl_config
in sorted(part_config
["paths"].items()):
184 bouncer_platform
= pl_config
["bouncer-platform"]
185 path
= pl_config
["path"] % subs
186 self
.info("%s (%s): %s" % (platform
, bouncer_platform
, path
))
187 self
.api_add_location(product_name
, bouncer_platform
, path
)
190 if __name__
== '__main__':
191 myScript
= BouncerSubmitter()
192 myScript
.run_and_exit()