mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-28 11:18:11 +00:00
Fix permission on exited container
If a container is exited we quickly start it to fix the permissions. Fix https://github.com/GNS3/gns3-gui/issues/2181
This commit is contained in:
parent
86bd7b6058
commit
a93f3b0576
@ -416,16 +416,30 @@ class DockerVM(BaseNode):
|
|||||||
Because docker run as root we need to fix permission and ownership to allow user to interact
|
Because docker run as root we need to fix permission and ownership to allow user to interact
|
||||||
with it from their filesystem and do operation like file delete
|
with it from their filesystem and do operation like file delete
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
state = yield from self._get_container_state()
|
||||||
|
if state == "stopped" or state == "exited":
|
||||||
|
# We need to restart it to fix permissions
|
||||||
|
yield from self.manager.query("POST", "containers/{}/start".format(self._cid))
|
||||||
|
|
||||||
for volume in self._volumes:
|
for volume in self._volumes:
|
||||||
log.debug("Docker container '{name}' [{image}] fix ownership on {path}".format(
|
log.debug("Docker container '{name}' [{image}] fix ownership on {path}".format(
|
||||||
name=self._name, image=self._image, path=volume))
|
name=self._name, image=self._image, path=volume))
|
||||||
process = yield from asyncio.subprocess.create_subprocess_exec("docker",
|
process = yield from asyncio.subprocess.create_subprocess_exec(
|
||||||
|
"docker",
|
||||||
"exec",
|
"exec",
|
||||||
self._cid,
|
self._cid,
|
||||||
"/gns3/bin/busybox",
|
"/gns3/bin/busybox",
|
||||||
"sh",
|
"sh",
|
||||||
"-c",
|
"-c",
|
||||||
"(/gns3/bin/busybox find \"{path}\" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{path}/.gns3_perms\") && /gns3/bin/busybox chmod -R u+rX \"{path}\" && /gns3/bin/busybox chown {uid}:{gid} -R \"{path}\"".format(uid=os.getuid(), gid=os.getgid(), path=volume))
|
"("
|
||||||
|
"/gns3/bin/busybox find \"{path}\" -depth -print0"
|
||||||
|
" | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{path}/.gns3_perms\""
|
||||||
|
")"
|
||||||
|
" && /gns3/bin/busybox chmod -R u+rX \"{path}\""
|
||||||
|
" && /gns3/bin/busybox chown {uid}:{gid} -R \"{path}\""
|
||||||
|
.format(uid=os.getuid(), gid=os.getgid(), path=volume),
|
||||||
|
)
|
||||||
yield from process.wait()
|
yield from process.wait()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -564,13 +578,15 @@ class DockerVM(BaseNode):
|
|||||||
try:
|
try:
|
||||||
state = yield from self._get_container_state()
|
state = yield from self._get_container_state()
|
||||||
except DockerHttp404Error:
|
except DockerHttp404Error:
|
||||||
state = "stopped"
|
self.status = "stopped"
|
||||||
|
return
|
||||||
|
|
||||||
if state == "paused":
|
if state == "paused":
|
||||||
yield from self.unpause()
|
yield from self.unpause()
|
||||||
|
|
||||||
if state != "stopped":
|
|
||||||
yield from self._fix_permissions()
|
yield from self._fix_permissions()
|
||||||
|
state = yield from self._get_container_state()
|
||||||
|
if state != "stopped" or state != "exited":
|
||||||
# t=5 number of seconds to wait before killing the container
|
# t=5 number of seconds to wait before killing the container
|
||||||
try:
|
try:
|
||||||
yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5})
|
yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5})
|
||||||
|
@ -934,6 +934,7 @@ def test_create_network_interfaces(vm):
|
|||||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||||
def test_fix_permission(vm, loop):
|
def test_fix_permission(vm, loop):
|
||||||
vm._volumes = ["/etc"]
|
vm._volumes = ["/etc"]
|
||||||
|
vm._get_container_state = AsyncioMagicMock(return_value="running")
|
||||||
process = MagicMock()
|
process = MagicMock()
|
||||||
with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=process) as mock_exec:
|
with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=process) as mock_exec:
|
||||||
loop.run_until_complete(vm._fix_permissions())
|
loop.run_until_complete(vm._fix_permissions())
|
||||||
@ -941,6 +942,19 @@ def test_fix_permission(vm, loop):
|
|||||||
assert process.wait.called
|
assert process.wait.called
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
|
||||||
|
def test_fix_permission_not_running(vm, loop):
|
||||||
|
vm._volumes = ["/etc"]
|
||||||
|
vm._get_container_state = AsyncioMagicMock(return_value="stopped")
|
||||||
|
process = MagicMock()
|
||||||
|
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_start:
|
||||||
|
with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=process) as mock_exec:
|
||||||
|
loop.run_until_complete(vm._fix_permissions())
|
||||||
|
mock_exec.assert_called_with('docker', 'exec', 'e90e34656842', '/gns3/bin/busybox', 'sh', '-c', '(/gns3/bin/busybox find "/etc" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c \'%a:%u:%g:%n\' > "/etc/.gns3_perms") && /gns3/bin/busybox chmod -R u+rX "/etc" && /gns3/bin/busybox chown {}:{} -R "/etc"'.format(os.getuid(), os.getgid()))
|
||||||
|
assert mock_start.called
|
||||||
|
assert process.wait.called
|
||||||
|
|
||||||
|
|
||||||
def test_read_console_output_with_binary_mode(vm, loop):
|
def test_read_console_output_with_binary_mode(vm, loop):
|
||||||
class InputStreamMock(object):
|
class InputStreamMock(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user