mirror of
https://github.com/projectatomic/atomic.git
synced 2026-02-06 12:45:57 +01:00
_get_backend_index_from_string returned a wrong index as it considers
all the backends supported, not the current ones available.
Take rid of the function and lookup directly into the available backends
list.
Fix this exception:
Namespace(_class=<class 'Atomic.uninstall.Uninstall'>, args=[], assumeyes=False, debug=True, display=False, force=False, func='uninstall', ignore=False, image='etcd', name=None, opt1=None, opt2=None, opt3=None, profile=False, storage='ostree')
list assignment index out of range
Traceback (most recent call last):
File "./atomic", line 185, in <module>
sys.exit(_func())
File "atomic/Atomic/uninstall.py", line 54, in uninstall
be, img_obj = beu.get_backend_and_image_obj(self.args.image, str_preferred_backend=self.args.storage)
File "atomic/Atomic/backendutils.py", line 88, in get_backend_and_image_obj
del backends[self._get_backend_index_from_string(str_preferred_backend)]
IndexError: list assignment index out of range
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: #1182
Approved by: ashcrow
167 lines
6.9 KiB
Python
167 lines
6.9 KiB
Python
from Atomic.backends._docker import DockerBackend
|
|
from Atomic.backends._docker_errors import NoDockerDaemon
|
|
from Atomic.backends._ostree import OSTreeBackend
|
|
from Atomic.backends._containers_storage import ContainersStorageBackend
|
|
from Atomic.util import write_out, get_atomic_config
|
|
|
|
ATOMIC_CONFIG = get_atomic_config()
|
|
default_storage = ATOMIC_CONFIG.get('default_storage', "docker")
|
|
|
|
class BackendUtils(object):
|
|
"""
|
|
Given an image, returns the back end that owns that image
|
|
"""
|
|
|
|
BACKENDS = [DockerBackend, OSTreeBackend, ContainersStorageBackend]
|
|
|
|
@property
|
|
def available_backends(self):
|
|
return self._set_available_backends()
|
|
|
|
def _set_available_backends(self):
|
|
bes = []
|
|
for x in self.BACKENDS:
|
|
try:
|
|
be = x()
|
|
if be.available:
|
|
bes.append(x)
|
|
except NoDockerDaemon:
|
|
pass
|
|
if len(bes) < 1:
|
|
raise ValueError("No backends are enabled for Atomic.")
|
|
return bes
|
|
|
|
def dump_backends(self):
|
|
backends = ''
|
|
for i in self.available_backends:
|
|
be = i()
|
|
backends += "{}: Active, ".format(be.backend)
|
|
write_out("Backends({})\n".format(backends))
|
|
|
|
def get_backend_from_string(self, str_backend, init=True):
|
|
for _backend in self.BACKENDS:
|
|
backend = _backend
|
|
backend_obj = _backend()
|
|
if backend_obj.backend == str_backend:
|
|
if init:
|
|
return backend_obj
|
|
return backend
|
|
raise ValueError("Unable to associate string '{}' with backend".format(str_backend))
|
|
|
|
def _get_backend(self, backend):
|
|
return self.get_backend_from_string(backend, init=False)
|
|
|
|
@staticmethod
|
|
def backend_has_image(backend, img):
|
|
return True if backend.has_image(img) else False
|
|
|
|
@staticmethod
|
|
def backend_has_container(backend, container):
|
|
return True if backend.has_container(container) else False
|
|
|
|
def get_backend_and_image_obj(self, img, str_preferred_backend=None, required=False):
|
|
"""
|
|
Given an image name (str) and optionally a str reference to a backend,
|
|
this method looks for the image firstly on the preferred backend and
|
|
then on the alternate backends. It returns a backend object and an
|
|
image object.
|
|
:param img: name of image to look for
|
|
:param str_preferred_backend: i.e. 'docker'
|
|
:return: backend object and image object
|
|
"""
|
|
backends = list(self.available_backends)
|
|
|
|
if str_preferred_backend and self._get_backend(str_preferred_backend) not in self.available_backends and required:
|
|
raise ValueError("The '{}' backend appears unavailable/inactive".format(str_preferred_backend))
|
|
# Check preferred backend first
|
|
if str_preferred_backend and self._get_backend(str_preferred_backend) in self.available_backends:
|
|
be = self.get_backend_from_string(str_preferred_backend)
|
|
img_obj = be.has_image(img)
|
|
if img_obj:
|
|
return be, img_obj
|
|
if required:
|
|
raise ValueError("Unable to find {} in the {} backend".format(img, str_preferred_backend))
|
|
# Didnt find in preferred, need to remove it from the list now
|
|
if be in backends:
|
|
del backends[backends.index(be)]
|
|
|
|
# Did not find it in the preferred backend, keep looking
|
|
img_in_backends = []
|
|
for backend in backends:
|
|
be = backend()
|
|
img_obj = be.has_image(img)
|
|
if img_obj:
|
|
img_in_backends.append((be, img_obj))
|
|
|
|
if len(img_in_backends) == 1:
|
|
return img_in_backends[0]
|
|
if len(img_in_backends) == 0:
|
|
raise ValueError("Unable to find '{}' in the following backends: {}".format(img, ", ".join([x().backend for x in self.available_backends])))
|
|
raise ValueError("Found {} in multiple storage backends: {}".
|
|
format(img, ', '.join([x.backend for x, _ in img_in_backends])))
|
|
|
|
def get_backend_and_container_obj(self, container_name, str_preferred_backend=None, required=False):
|
|
"""
|
|
Given a container name (str) and optionally a str reference to a backend,
|
|
this method looks for the container firstly on the preferred backend and
|
|
then on the alternate backends. It returns a backend object and a container
|
|
object.
|
|
:param container_name: name of image to look for
|
|
:param str_preferred_backend: i.e. 'docker'
|
|
:return: backend object and container object
|
|
"""
|
|
|
|
if str_preferred_backend and self._get_backend(str_preferred_backend) not in self.available_backends and required:
|
|
raise ValueError("The '{}' backend appears unavailable/inactive".format(str_preferred_backend))
|
|
|
|
backends = list(self.available_backends)
|
|
# Check preferred backend first
|
|
if str_preferred_backend and self._get_backend(str_preferred_backend) in self.available_backends:
|
|
be = self.get_backend_from_string(str_preferred_backend)
|
|
con_obj = be.has_container(container_name)
|
|
if con_obj:
|
|
return be, con_obj
|
|
if required:
|
|
raise ValueError("Unable to find {} in the {} backend".format(container_name, str_preferred_backend))
|
|
# Didnt find in preferred, need to remove it from the list now
|
|
if be in backends:
|
|
del backends[backends.index(be)]
|
|
|
|
container_in_backends = []
|
|
for backend in backends:
|
|
be = backend()
|
|
con_obj = be.has_container(container_name)
|
|
if con_obj:
|
|
container_in_backends.append((be, con_obj))
|
|
if len(container_in_backends) == 1:
|
|
return container_in_backends[0]
|
|
if len(container_in_backends) == 0:
|
|
raise ValueError("Unable to find backend associated with container '{}'".format(container_name))
|
|
raise ValueError("Found {} in multiple storage backends: {}".
|
|
format(container_name, ', '.join([x.backend for x in container_in_backends])))
|
|
|
|
def get_images(self, get_all=False):
|
|
backends = self.available_backends
|
|
img_objs = []
|
|
for backend in backends:
|
|
be = backend()
|
|
img_objs += be.get_images(get_all=get_all)
|
|
return img_objs
|
|
|
|
def get_containers(self):
|
|
backends = self.available_backends
|
|
con_objs = []
|
|
for backend in backends:
|
|
be = backend()
|
|
con_objs += be.get_containers()
|
|
return con_objs
|
|
|
|
def get_container_obj_by_image_name(self, image_name, str_preferred_backend):
|
|
pass
|
|
|
|
@staticmethod
|
|
def message_backend_change(previous, new):
|
|
write_out("\nNote: Switching from the '{}' backend to the '{}' backend based on the 'atomic.type' label in the "
|
|
"image. You can use --storage to override this behaviour.\n".format(previous, new))
|
|
|