1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 17:28:08 +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:
Julien Duponchelle 2017-07-26 12:41:06 +02:00
parent 86bd7b6058
commit a93f3b0576
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
2 changed files with 40 additions and 10 deletions

View File

@ -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(
"exec", "docker",
self._cid, "exec",
"/gns3/bin/busybox", self._cid,
"sh", "/gns3/bin/busybox",
"-c", "sh",
"(/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)) "-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),
)
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})

View File

@ -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):