Murano-dashboard now shows warnings if glance v1 is unavailable
Murano-dashboard currently does not fully support glance v2. This commit removes restriction to use murano-dashboard with v2-enabled horizon. All the relevant places now attempt to create a v1 client instead of v2. In case v1 is unavailable an error message is shown. Co-authored-by: Kirill Zaitsev <k.zaitsev@me.com> Closes-bug: #1624423 Change-Id: I4cbadd125043cdefd12aac02ec2035005f2a6bc9
This commit is contained in:
parent
8da1613edc
commit
a9dfbc4903
@ -100,14 +100,13 @@ class MarkImageForm(horizon_forms.SelfHandlingForm):
|
|||||||
image_id = data['image']
|
image_id = data['image']
|
||||||
image_type = data['type'] if data['type'] != 'custom' else \
|
image_type = data['type'] if data['type'] != 'custom' else \
|
||||||
data['custom_type']
|
data['custom_type']
|
||||||
properties = glance.image_get(request, image_id).properties
|
kwargs = {}
|
||||||
properties['murano_image_info'] = json.dumps({
|
kwargs['murano_image_info'] = json.dumps({
|
||||||
'title': data['title'],
|
'title': data['title'],
|
||||||
'type': image_type
|
'type': image_type
|
||||||
})
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
img = glance.image_update(request, image_id, properties=properties)
|
img = glance.image_update_properties(request, image_id, **kwargs)
|
||||||
messages.success(request, _('Image successfully marked'))
|
messages.success(request, _('Image successfully marked'))
|
||||||
return img
|
return img
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -61,9 +61,28 @@ class MarkedImagesView(horizon_tables.DataTableView):
|
|||||||
images = []
|
images = []
|
||||||
self._prev = False
|
self._prev = False
|
||||||
self._more = False
|
self._more = False
|
||||||
|
|
||||||
|
# TODO(kzaitsev) add v2 client support for marking images
|
||||||
try:
|
try:
|
||||||
images_iter = glance.glanceclient(self.request).images.list(
|
glance_v1_client = glance.glanceclient(self.request, "1")
|
||||||
|
except Exception:
|
||||||
|
# Horizon seems to raise ImportError which doesn't look
|
||||||
|
# specific enough. Let's catch any exceptions.
|
||||||
|
msg = _('Unable to create v1 glance client. Marking images '
|
||||||
|
'from murano-dashboard will be unavailable.')
|
||||||
|
uri = reverse('horizon:app-catalog:catalog:index')
|
||||||
|
|
||||||
|
exceptions.handle(self.request, msg, redirect=uri)
|
||||||
|
|
||||||
|
try:
|
||||||
|
images_iter = glance_v1_client.images.list(
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve list of images')
|
||||||
|
uri = reverse('horizon:app-catalog:catalog:index')
|
||||||
|
|
||||||
|
exceptions.handle(self.request, msg, redirect=uri)
|
||||||
|
|
||||||
marked_images_iter = forms.filter_murano_images(
|
marked_images_iter = forms.filter_murano_images(
|
||||||
images_iter,
|
images_iter,
|
||||||
request=self.request)
|
request=self.request)
|
||||||
@ -83,11 +102,6 @@ class MarkedImagesView(horizon_tables.DataTableView):
|
|||||||
self._prev = True
|
self._prev = True
|
||||||
if prev_marker is not None:
|
if prev_marker is not None:
|
||||||
images.reverse()
|
images.reverse()
|
||||||
except Exception:
|
|
||||||
msg = _('Unable to retrieve list of images')
|
|
||||||
uri = reverse('horizon:app-catalog:images:index')
|
|
||||||
|
|
||||||
exceptions.handle(self.request, msg, redirect=uri)
|
|
||||||
return images
|
return images
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +30,3 @@ SESSION_ENGINE = 'django.contrib.sessions.backends.db'
|
|||||||
|
|
||||||
# from openstack_dashboard.settings import POLICY_FILES
|
# from openstack_dashboard.settings import POLICY_FILES
|
||||||
POLICY_FILES.update({'murano': 'murano_policy.json',})
|
POLICY_FILES.update({'murano': 'murano_policy.json',})
|
||||||
|
|
||||||
OPENSTACK_API_VERSIONS = {
|
|
||||||
"identity": 3,
|
|
||||||
"image": 1,
|
|
||||||
}
|
|
||||||
|
@ -70,6 +70,61 @@ def is_app(wizard):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_images(name, package, request, step_data=None):
|
||||||
|
try:
|
||||||
|
glance_client = glance.glanceclient(
|
||||||
|
request, version='1')
|
||||||
|
except Exception:
|
||||||
|
glance_client = None
|
||||||
|
|
||||||
|
base_url = packages_consts.MURANO_REPO_URL
|
||||||
|
image_specs = package.images()
|
||||||
|
if not glance_client and len(image_specs):
|
||||||
|
# NOTE(kzaitsev): no glance_client. Probably v1 client
|
||||||
|
# is not available. Add warning, to let user know that
|
||||||
|
# we were unable to load images automagically
|
||||||
|
# since v2 does not have copy_from
|
||||||
|
download_urls = []
|
||||||
|
for image_spec in image_specs:
|
||||||
|
download_url = muranoclient_utils.to_url(
|
||||||
|
image_spec.get("Url", image_spec['Name']),
|
||||||
|
base_url=base_url,
|
||||||
|
path='images/',
|
||||||
|
)
|
||||||
|
download_urls.append(download_url)
|
||||||
|
msg = _("Couldn't initialise glance v1 client, "
|
||||||
|
"therefore could not download images for "
|
||||||
|
"'{0}' package. You may need to download them "
|
||||||
|
"manually from these locations: {1}").format(
|
||||||
|
name, ' '.join(download_urls))
|
||||||
|
messages.error(request, msg)
|
||||||
|
LOG.error(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
imgs = muranoclient_utils.ensure_images(
|
||||||
|
glance_client=glance_client,
|
||||||
|
image_specs=package.images(),
|
||||||
|
base_url=base_url)
|
||||||
|
for img in imgs:
|
||||||
|
msg = _("Trying to add {0} image to glance. "
|
||||||
|
"Image will be ready for deployment after "
|
||||||
|
"successful upload").format(img['name'],)
|
||||||
|
messages.warning(request, msg)
|
||||||
|
log_msg = _("Trying to add {0}, {1} image to "
|
||||||
|
"glance. Image will be ready for "
|
||||||
|
"deployment after successful upload")\
|
||||||
|
.format(img['name'], img['id'],)
|
||||||
|
LOG.info(log_msg)
|
||||||
|
if step_data:
|
||||||
|
step_data['images'].append(img)
|
||||||
|
except Exception as e:
|
||||||
|
msg = _("Error {0} occurred while installing "
|
||||||
|
"images for {1}").format(e, name)
|
||||||
|
messages.error(request, msg)
|
||||||
|
LOG.exception(msg)
|
||||||
|
|
||||||
|
|
||||||
class PackageDefinitionsView(horizon_tables.DataTableView):
|
class PackageDefinitionsView(horizon_tables.DataTableView):
|
||||||
table_class = tables.PackageDefinitionsTable
|
table_class = tables.PackageDefinitionsTable
|
||||||
template_name = 'packages/index.html'
|
template_name = 'packages/index.html'
|
||||||
@ -219,10 +274,7 @@ class ImportBundleWizard(horizon_views.PageTitleMixin, views.ModalFormMixin,
|
|||||||
raise exceptions.Http302(
|
raise exceptions.Http302(
|
||||||
reverse('horizon:app-catalog:packages:index'))
|
reverse('horizon:app-catalog:packages:index'))
|
||||||
|
|
||||||
glance_client = glance.glanceclient(self.request, version='1')
|
|
||||||
|
|
||||||
for package_spec in bundle.package_specs():
|
for package_spec in bundle.package_specs():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
package = muranoclient_utils.Package.from_location(
|
package = muranoclient_utils.Package.from_location(
|
||||||
package_spec['Name'],
|
package_spec['Name'],
|
||||||
@ -240,26 +292,9 @@ class ImportBundleWizard(horizon_views.PageTitleMixin, views.ModalFormMixin,
|
|||||||
|
|
||||||
reqs = package.requirements(base_url=base_url)
|
reqs = package.requirements(base_url=base_url)
|
||||||
for dep_name, dep_package in six.iteritems(reqs):
|
for dep_name, dep_package in six.iteritems(reqs):
|
||||||
try:
|
_ensure_images(dep_name, dep_package,
|
||||||
imgs = muranoclient_utils.ensure_images(
|
self.request)
|
||||||
glance_client=glance_client,
|
|
||||||
image_specs=dep_package.images(),
|
|
||||||
base_url=base_url)
|
|
||||||
for img in imgs:
|
|
||||||
msg = _("Trying to add {0} image to glance. "
|
|
||||||
"Image will be ready for deployment after"
|
|
||||||
" successful upload").format(img['name'],)
|
|
||||||
messages.warning(self.request, msg)
|
|
||||||
log_msg = _("Trying to add {0}, {1} image to "
|
|
||||||
"glance. Image will be ready for "
|
|
||||||
"deployment after successful upload")\
|
|
||||||
.format(img['name'], img['id'],)
|
|
||||||
LOG.info(log_msg)
|
|
||||||
except Exception as e:
|
|
||||||
msg = _("Error {0} occurred while installing "
|
|
||||||
"images for {1}").format(e, dep_name)
|
|
||||||
messages.error(self.request, msg)
|
|
||||||
LOG.exception(msg)
|
|
||||||
try:
|
try:
|
||||||
files = {dep_name: dep_package.file()}
|
files = {dep_name: dep_package.file()}
|
||||||
package = api.muranoclient(
|
package = api.muranoclient(
|
||||||
@ -354,16 +389,29 @@ class ImportPackageWizard(horizon_views.PageTitleMixin, views.ModalFormMixin,
|
|||||||
# Images have been imported as private images during the 'upload' step
|
# Images have been imported as private images during the 'upload' step
|
||||||
# If the package is public, make the required images public
|
# If the package is public, make the required images public
|
||||||
if data['is_public']:
|
if data['is_public']:
|
||||||
glance_client = glance.glanceclient(self.request, version='1')
|
try:
|
||||||
|
glance_client = glance.glanceclient(self.request, '1')
|
||||||
|
except Exception:
|
||||||
|
glance_client = None
|
||||||
|
|
||||||
|
if glance_client:
|
||||||
for img in installed_images:
|
for img in installed_images:
|
||||||
try:
|
try:
|
||||||
glance_client.images.update(img['id'], is_public=True)
|
glance_client.images.update(img['id'], is_public=True)
|
||||||
LOG.debug('Success update for image {0}'.format(img['id']))
|
LOG.debug(
|
||||||
|
'Success update for image {0}'.format(img['id']))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = _("Error {0} occurred while setting image {1}, {2} "
|
msg = _("Error {0} occurred while setting image {1}, "
|
||||||
"public").format(e, img['name'], img['id'])
|
"{2} public").format(e, img['name'], img['id'])
|
||||||
messages.error(self.request, msg)
|
messages.error(self.request, msg)
|
||||||
LOG.exception(msg)
|
LOG.exception(msg)
|
||||||
|
elif len(installed_images):
|
||||||
|
msg = _("Couldn't initialise glance v1 client, "
|
||||||
|
"therefore could not make the following images "
|
||||||
|
"public: {0}").format(' '.join(
|
||||||
|
[img['name'] for img in installed_images]))
|
||||||
|
messages.warning(self.request, msg)
|
||||||
|
LOG.warning(msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data['tags'] = [t.strip() for t in data['tags'].split(',')]
|
data['tags'] = [t.strip() for t in data['tags'].split(',')]
|
||||||
@ -447,36 +495,13 @@ class ImportPackageWizard(horizon_views.PageTitleMixin, views.ModalFormMixin,
|
|||||||
raise exceptions.Http302(
|
raise exceptions.Http302(
|
||||||
reverse('horizon:app-catalog:packages:index'))
|
reverse('horizon:app-catalog:packages:index'))
|
||||||
|
|
||||||
def _ensure_images(name, package):
|
|
||||||
try:
|
|
||||||
imgs = muranoclient_utils.ensure_images(
|
|
||||||
glance_client=glance_client,
|
|
||||||
image_specs=package.images(),
|
|
||||||
base_url=base_url)
|
|
||||||
for img in imgs:
|
|
||||||
msg = _("Trying to add {0} image to glance. "
|
|
||||||
"Image will be ready for deployment after "
|
|
||||||
"successful upload").format(img['name'],)
|
|
||||||
messages.warning(self.request, msg)
|
|
||||||
log_msg = _("Trying to add {0}, {1} image to "
|
|
||||||
"glance. Image will be ready for "
|
|
||||||
"deployment after successful upload")\
|
|
||||||
.format(img['name'], img['id'],)
|
|
||||||
LOG.info(log_msg)
|
|
||||||
step_data['images'].append(img)
|
|
||||||
except Exception as e:
|
|
||||||
msg = _("Error {0} occurred while installing "
|
|
||||||
"images for {1}").format(e, name)
|
|
||||||
messages.error(self.request, msg)
|
|
||||||
LOG.exception(msg)
|
|
||||||
|
|
||||||
reqs = package.requirements(base_url=base_url)
|
reqs = package.requirements(base_url=base_url)
|
||||||
glance_client = glance.glanceclient(self.request, version='1')
|
|
||||||
original_package = reqs.pop(name)
|
original_package = reqs.pop(name)
|
||||||
step_data['dependencies'] = []
|
step_data['dependencies'] = []
|
||||||
step_data['images'] = []
|
step_data['images'] = []
|
||||||
for dep_name, dep_package in six.iteritems(reqs):
|
for dep_name, dep_package in six.iteritems(reqs):
|
||||||
_ensure_images(dep_name, dep_package)
|
_ensure_images(dep_name, dep_package, self.request, step_data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
files = {dep_name: dep_package.file()}
|
files = {dep_name: dep_package.file()}
|
||||||
package = api.muranoclient(self.request).packages.create(
|
package = api.muranoclient(self.request).packages.create(
|
||||||
@ -501,7 +526,7 @@ class ImportPackageWizard(horizon_views.PageTitleMixin, views.ModalFormMixin,
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# add main packages images
|
# add main packages images
|
||||||
_ensure_images(name, original_package)
|
_ensure_images(name, original_package, self.request, step_data)
|
||||||
|
|
||||||
# import main package itself
|
# import main package itself
|
||||||
try:
|
try:
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
other:
|
||||||
|
- Murano Dashboard relies on Glance v1 API for image uploads.
|
||||||
|
In case it is not available an error will be shown and all the
|
||||||
|
image-related functionality will be unavailable.
|
Loading…
Reference in New Issue
Block a user