144
144
class _DiskImage(object):
145
145
"""Provide operations on a disk image file."""
147
tmp_prefix = 'openstack-disk-mount-tmp'
147
149
def __init__(self, image, partition=None, use_cow=False, mount_dir=None):
148
150
# These passed to each mounter
149
151
self.image = image
164
166
if not self.handlers:
165
167
raise exception.Error(_('no capable image handler configured'))
170
# Note the os.path.ismount() shortcut doesn't
171
# work with libguestfs due to permissions issues.
172
device = self._device_for_path(mount_dir)
177
def _device_for_path(path):
179
with open("/proc/mounts", 'r') as ifp:
181
fields = line.split()
182
if fields[1] == path:
187
def _reset(self, device):
188
"""Reset internal state for a previously mounted directory."""
189
mounter_cls = self._handler_class(device=device)
190
mounter = mounter_cls(image=self.image,
191
partition=self.partition,
192
mount_dir=self.mount_dir,
194
self._mounter = mounter
196
mount_name = os.path.basename(self.mount_dir or '')
197
self._mkdir = mount_name.startswith(self.tmp_prefix)
168
200
def errors(self):
169
201
"""Return the collated errors from all operations."""
170
202
return '\n--\n'.join([''] + self._errors)
173
def _handler_class(mode):
174
"""Look up the appropriate class to use based on MODE."""
205
def _handler_class(mode=None, device=None):
206
"""Look up the appropriate class to use based on MODE or DEVICE."""
175
207
for cls in (loop.Mount, nbd.Mount, guestfs.Mount):
178
raise exception.Error(_("unknown disk image handler: %s") % mode)
208
if mode and cls.mode == mode:
210
elif device and cls.device_id_string in device:
212
msg = _("no disk image handler for: %s") % mode or device
213
raise exception.Error(msg)
181
216
"""Mount a disk image, using the object attributes.
258
293
raise exception.Error(img.errors)
261
def setup_container(image, container_dir=None, use_cow=False):
296
def setup_container(image, container_dir, use_cow=False):
262
297
"""Setup the LXC container.
264
299
It will mount the loopback image to the container directory in order
265
300
to create the root filesystem for the container.
267
LXC does not support qcow2 images yet.
270
303
img = _DiskImage(image=image, use_cow=use_cow, mount_dir=container_dir)
274
305
raise exception.Error(img.errors)
275
306
except Exception, exn:
276
307
LOG.exception(_('Failed to mount filesystem: %s'), exn)
279
def destroy_container(img):
310
def destroy_container(container_dir):
280
311
"""Destroy the container once it terminates.
282
313
It will umount the container that is mounted,
283
314
and delete any linked devices.
285
LXC does not support qcow2 images yet.
317
img = _DiskImage(image=None, mount_dir=container_dir)
290
319
except Exception, exn:
291
320
LOG.exception(_('Failed to remove container: %s'), exn)