mirror of
https://github.com/projectatomic/atomic.git
synced 2026-02-07 06:44:52 +01:00
Merge pull request #85 from willmtemple/mount-overlay-backend
OverlayFS DockerMount backend for atomic mount command.
This commit is contained in:
@@ -242,12 +242,21 @@ class DockerMount(Mount):
|
||||
''.format(identifier))
|
||||
|
||||
@staticmethod
|
||||
def _no_gd_api(cid):
|
||||
def _no_gd_api_dm(cid):
|
||||
# TODO: Deprecated
|
||||
desc_file = os.path.join('/var/lib/docker/devicemapper/metadata', cid)
|
||||
desc = json.loads(open(desc_file).read())
|
||||
return desc['device_id'], desc['size']
|
||||
|
||||
@staticmethod
|
||||
def _no_gd_api_overlay(cid):
|
||||
# TODO: Deprecated
|
||||
prefix = os.path.join('/var/lib/docker/overlay/', cid)
|
||||
ld_metafile = open(os.path.join(prefix, 'lower-id'))
|
||||
ld_loc = os.path.join('/var/lib/docker/overlay/', ld_metafile.read())
|
||||
return (os.path.join(ld_loc, 'root'), os.path.join(prefix, 'upper'),
|
||||
os.path.join(prefix, 'work'))
|
||||
|
||||
def mount(self, identifier, options=[]):
|
||||
"""
|
||||
Mounts a container or image referred to by identifier to
|
||||
@@ -305,13 +314,13 @@ class DockerMount(Mount):
|
||||
dm_dev_name, dm_dev_id, dm_dev_size = '', '', ''
|
||||
dm_pool = info['DriverStatus'][0][1]
|
||||
|
||||
if 'GraphDriver' in cinfo:
|
||||
try:
|
||||
dm_dev_name = cinfo['GraphDriver']['Data']['DeviceName']
|
||||
dm_dev_id = cinfo['GraphDriver']['Data']['DeviceId']
|
||||
dm_dev_size = cinfo['GraphDriver']['Data']['DeviceSize']
|
||||
else:
|
||||
except:
|
||||
# TODO: deprecated when GraphDriver patch makes it upstream
|
||||
dm_dev_id, dm_dev_size = DockerMount._no_gd_api(cid)
|
||||
dm_dev_id, dm_dev_size = DockerMount._no_gd_api_dm(cid)
|
||||
dm_dev_name = dm_pool.replace('pool', cid)
|
||||
|
||||
dm_dev_path = os.path.join('/dev/mapper', dm_dev_name)
|
||||
@@ -338,6 +347,42 @@ class DockerMount(Mount):
|
||||
self._cleanup_container(cinfo)
|
||||
raise de
|
||||
|
||||
def _mount_overlay(self, identifier, options):
|
||||
"""
|
||||
OverlayFS mount backend.
|
||||
"""
|
||||
if os.geteuid() != 0:
|
||||
raise MountError('Insufficient privileges to mount device.')
|
||||
|
||||
if self.live:
|
||||
raise MountError('The OverlayFS backend does not support live '
|
||||
'mounts.')
|
||||
elif 'rw' in options:
|
||||
raise MountError('The OverlayFS backend does not support '
|
||||
'writeable mounts.')
|
||||
|
||||
cid = self._identifier_as_cid(identifier)
|
||||
cinfo = self.client.inspect_container(cid)
|
||||
|
||||
ld, ud, wd = '', '', ''
|
||||
try:
|
||||
ld = cinfo['GraphDriver']['Data']['lowerDir']
|
||||
ud = cinfo['GraphDriver']['Data']['upperDir']
|
||||
wd = cinfo['GraphDriver']['Data']['workDir']
|
||||
except:
|
||||
ld, ud, wd = DockerMount._no_gd_api_overlay(cid)
|
||||
|
||||
options += ['ro', 'lowerdir=' + ld, 'upperdir=' + ud, 'workdir=' + wd]
|
||||
optstring = ','.join(options)
|
||||
cmd = ['mount', '-t', 'overlay', '-o', optstring, 'overlay',
|
||||
self.mountpoint]
|
||||
status = util.subp(cmd)
|
||||
|
||||
if status.return_code != 0:
|
||||
self._cleanup_container(cinfo)
|
||||
raise MountError('Failed to mount OverlayFS device.\n' +
|
||||
status.stderr)
|
||||
|
||||
def _cleanup_container(self, cinfo):
|
||||
"""
|
||||
Remove a container and clean up its image if necessary.
|
||||
@@ -398,3 +443,30 @@ class DockerMount(Mount):
|
||||
|
||||
Mount._remove_thin_device(dev_name)
|
||||
self._cleanup_container(cinfo)
|
||||
|
||||
def _get_overlay_mount_cid(self):
|
||||
"""
|
||||
Returns the cid of the container mounted at mountpoint.
|
||||
"""
|
||||
cmd = ['findmnt', '-o', 'OPTIONS', '-n', self.mountpoint]
|
||||
r = util.subp(cmd)
|
||||
if r.return_code != 0:
|
||||
raise MountError('No devices mounted at that location.')
|
||||
optstring = r.stdout.strip().split('\n')[-1]
|
||||
upperdir = [o.replace('upperdir=', '') for o in optstring.split(',')
|
||||
if o.startswith('upperdir=')][0]
|
||||
cdir = upperdir.rsplit('/', 1)[0]
|
||||
if not cdir.startswith('/var/lib/docker/overlay/'):
|
||||
raise MountError('The device mounted at that location is not a '
|
||||
'docker container.')
|
||||
return cdir.replace('/var/lib/docker/overlay/', '')
|
||||
|
||||
def _unmount_overlay(self):
|
||||
"""
|
||||
OverlayFS unmount backend.
|
||||
"""
|
||||
if Mount.get_dev_at_mountpoint(self.mountpoint) != 'overlay':
|
||||
raise MountError('Device mounted at {} is not an atomic mount.')
|
||||
cid = self._get_overlay_mount_cid()
|
||||
Mount.unmount_path(self.mountpoint)
|
||||
self._cleanup_container(self.client.inspect_container(cid))
|
||||
|
||||
@@ -19,23 +19,27 @@ If the given UUID or NAME is a container, and **--live** is not set, then
|
||||
temporary image and spawning a temporary container from that image. If UUID or
|
||||
REPO refers to an image, then *atomic mount* will simply create a temporary
|
||||
container from the given image. All temporary artifacts are cleaned upon
|
||||
*atomic unmount*.
|
||||
*atomic unmount*. Atomic mount is *only* supported on the devicemapper and
|
||||
overlayfs docker storage backends.
|
||||
|
||||
# OPTIONS
|
||||
**-o|--options** *OPTIONS*
|
||||
Specify options to be passed to *mount*. All options accepted by the 'mount'
|
||||
command are valid. The default mount options (if the **--live** flag is unset)
|
||||
are: 'ro,nodev,nosuid'. If the **-o** flag is specified, then no default
|
||||
options are assumed. Use of the 'rw' flag is discouraged, as writes into the
|
||||
atomic temporary containers are never preserved. Use of this option conflicts
|
||||
with **--live**, as live containers have predetermined, immutable mount
|
||||
options.
|
||||
command are valid. The default mount options for the devicemapper backend (if
|
||||
the **--live** flag is unset) are: 'ro,nodev,nosuid'. If the **-o** flag is
|
||||
specified, then no default options are assumed. Use of the 'rw' flag is
|
||||
discouraged, as writes into the atomic temporary containers are never
|
||||
preserved. Use of this option conflicts with **--live**, as live containers
|
||||
have predetermined, immutable mount options. The OverlayFS driver has, by
|
||||
default, only the 'ro' option set, and the 'rw' option is illegal and will
|
||||
cause the program to terminate.
|
||||
|
||||
**--live**
|
||||
Mount a container live, writable, and synchronized. This option allows the user
|
||||
to modify the container's contents as it runs or update the container's
|
||||
software without rebuilding the container. If live mode is used, no mount
|
||||
options may be provided.
|
||||
options may be provided. Live mode is *not* supported on the OverlayFS docker
|
||||
storage driver.
|
||||
|
||||
# HISTORY
|
||||
June 2015, Originally compiled by William Temple (wtemple at redhat dot com)
|
||||
|
||||
0
tests/integration/test_mount.sh
Normal file → Executable file
0
tests/integration/test_mount.sh
Normal file → Executable file
0
tests/integration/test_pass.sh
Normal file → Executable file
0
tests/integration/test_pass.sh
Normal file → Executable file
Reference in New Issue
Block a user