Support specifying upload options for image builds
The upload options are expected to be provided as a JSON file. The same options will be used for all image type and architecture combinations, similarly as it is done for ostree options. Extend unit tests to cover the newly added functionality.
This commit is contained in:
parent
4e32ae5439
commit
c76e97ddc9
4 changed files with 151 additions and 0 deletions
|
|
@ -116,6 +116,7 @@ class ImageRequest:
|
|||
self.image_type = image_type
|
||||
self.repositories = repos
|
||||
self.ostree: Optional[OSTreeOptions] = None
|
||||
self.upload_options: Optional[Dict] = None
|
||||
|
||||
def as_dict(self):
|
||||
arch = self.architecture
|
||||
|
|
@ -128,6 +129,8 @@ class ImageRequest:
|
|||
}
|
||||
if self.ostree:
|
||||
res["ostree"] = self.ostree.as_dict(self.architecture)
|
||||
if self.upload_options:
|
||||
res["upload_options"] = self.upload_options
|
||||
|
||||
return res
|
||||
|
||||
|
|
@ -688,6 +691,12 @@ class OSBuildImage(BaseTaskHandler):
|
|||
for ireq in ireqs:
|
||||
ireq.ostree = ostree
|
||||
|
||||
# Cloud upload options
|
||||
upload_options = opts.get("upload_options")
|
||||
if upload_options:
|
||||
for ireq in ireqs:
|
||||
ireq.upload_options = upload_options
|
||||
|
||||
self.logger.debug("Creating compose: %s (%s)\n koji: %s\n images: %s",
|
||||
nvr, distro, self.koji_url,
|
||||
str([i.as_dict() for i in ireqs]))
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ def parse_args(argv):
|
|||
|
||||
parser.add_option("--customizations", type=str, default=None, dest="customizations",
|
||||
help="Additional customizations to pass to Composer (json file)")
|
||||
parser.add_option("--upload-options", type=str, default=None, dest="upload_options",
|
||||
help="Cloud target upload options (json file)")
|
||||
parser.add_option("--nowait", action="store_false", dest="wait",
|
||||
help="Don't wait on image creation")
|
||||
parser.add_option("--ostree-parent", type=str, dest="ostree_parent",
|
||||
|
|
@ -140,6 +142,11 @@ def handle_osbuild_image(options, session, argv):
|
|||
with open(args.customizations, "r", encoding="utf-8") as f:
|
||||
opts["customizations"] = json.load(f)
|
||||
|
||||
# cloud upload options handling
|
||||
if args.upload_options:
|
||||
with open(args.upload_options, "r", encoding="utf-8") as f:
|
||||
opts["upload_options"] = json.load(f)
|
||||
|
||||
# Do some early checks to be able to give quick feedback
|
||||
check_target(session, target)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,15 @@ OSBUILD_IMAGE_SCHEMA = {
|
|||
"type": "object",
|
||||
"$ref": "#/definitions/ostree"
|
||||
},
|
||||
"upload_options": {
|
||||
"oneOf": [
|
||||
{"$ref": "#/definitions/AWSEC2UploadOptions"},
|
||||
{"$ref": "#/definitions/AWSS3UploadOptions"},
|
||||
{"$ref": "#/definitions/GCPUploadOptions"},
|
||||
{"$ref": "#/definitions/AzureUploadOptions"},
|
||||
{"$ref": "#/definitions/ContainerUploadOptions"}
|
||||
],
|
||||
},
|
||||
"repo": {
|
||||
"type": "array",
|
||||
"description": "Repositories",
|
||||
|
|
@ -113,6 +122,91 @@ OSBUILD_IMAGE_SCHEMA = {
|
|||
"description": "Omit tagging the result"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AWSEC2UploadOptions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["region", "share_with_accounts"],
|
||||
"properties": {
|
||||
"region": {
|
||||
"type": "string",
|
||||
},
|
||||
"snapshot_name": {
|
||||
"type": "string",
|
||||
},
|
||||
"share_with_accounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"AWSS3UploadOptions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["region"],
|
||||
"properties": {
|
||||
"region": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AzureUploadOptions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["tenant_id", "subscription_id", "resource_group", "location"],
|
||||
"properties": {
|
||||
"tenant_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"subscription_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"resource_group": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"image_name": {
|
||||
"type": "string",
|
||||
}
|
||||
}
|
||||
},
|
||||
"GCPUploadOptions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["region", "bucket"],
|
||||
"properties": {
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"bucket": {
|
||||
"type": "string"
|
||||
},
|
||||
"image_name": {
|
||||
"type": "string",
|
||||
},
|
||||
"share_with_accounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ContainerUploadOptions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1199,6 +1199,9 @@ class TestBuilderPlugin(PluginTest): # pylint: disable=too-many-public-methods
|
|||
|
||||
for ir in ireqs:
|
||||
arch = ir["architecture"]
|
||||
# Piggyback on this test case to test that no upload_options
|
||||
# are set, if they were not provided in the args.
|
||||
self.assertIsNone(ir.get("upload_options"))
|
||||
repos = ir["repositories"]
|
||||
assert len(repos) == 3
|
||||
|
||||
|
|
@ -1209,6 +1212,44 @@ class TestBuilderPlugin(PluginTest): # pylint: disable=too-many-public-methods
|
|||
ps = r.get("package_sets")
|
||||
assert ps and ps == ["a", "b", "c", "d"]
|
||||
|
||||
@httpretty.activate
|
||||
def test_compose_upload_options_global(self):
|
||||
# Check we properly handle compose requests with global upload options
|
||||
session = self.mock_session()
|
||||
handler = self.make_handler(session=session)
|
||||
|
||||
arches = ["x86_64", "aarch64"]
|
||||
upload_options = {
|
||||
"region": "us-east-1",
|
||||
"share_with_accounts": ["123456789"]
|
||||
}
|
||||
args = ["name", "version", "distro",
|
||||
"image_type",
|
||||
"fedora-candidate",
|
||||
arches,
|
||||
{"upload_options": upload_options}]
|
||||
|
||||
url = self.plugin.DEFAULT_COMPOSER_URL
|
||||
composer = MockComposer(url, architectures=arches)
|
||||
composer.httpretty_register()
|
||||
|
||||
res = handler.handler(*args)
|
||||
assert res, "invalid compose result"
|
||||
compose_id = res["composer"]["id"]
|
||||
compose = composer.composes.get(compose_id)
|
||||
self.assertIsNotNone(compose)
|
||||
|
||||
ireqs = compose["request"]["image_requests"]
|
||||
|
||||
# Check we got all the requested architectures
|
||||
ireq_arches = [i["architecture"] for i in ireqs]
|
||||
diff = set(arches) ^ set(ireq_arches)
|
||||
self.assertEqual(diff, set())
|
||||
|
||||
for ir in ireqs:
|
||||
uo = ir["upload_options"]
|
||||
self.assertEqual(uo, upload_options)
|
||||
|
||||
@httpretty.activate
|
||||
def test_compose_status_retry(self):
|
||||
compose_id = "43e57e63-ab32-4a8d-854d-3bbc117fdce3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue