merofeev / docker-windows-volume-watcher

A tool to notify Docker contianers about changes in mounts on Windows.
MIT License
188 stars 30 forks source link

Error on reading permissions when using docker v3.0.0 #9

Closed RolandMay closed 6 years ago

RolandMay commented 6 years ago

Issue

I received the following error when watching local file changes while running under docker v3.0.0:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "c:\anwendungen\python36-32\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "c:\anwendungen\python36-32\lib\site-packages\watchdog\observers\api.py", line 199, in run
    self.dispatch_events(self.event_queue, self.timeout)
  File "c:\anwendungen\python36-32\lib\site-packages\watchdog\observers\api.py", line 368, in dispatch_events
    handler.dispatch(event)
  File "c:\anwendungen\python36-32\lib\site-packages\watchdog\events.py", line 454, in dispatch
    _method_map[event_type](event)
  File "c:\anwendungen\python36-32\lib\site-packages\docker_volume_watcher\container_notifier.py", line 49, in __change_handler
    self.notify(absolute_path)
  File "c:\anwendungen\python36-32\lib\site-packages\docker_volume_watcher\container_notifier.py", line 66, in notify
    permissions = permissions.decode('utf-8').strip()
AttributeError: 'ExecResult' object has no attribute 'decode'

Docker version (pip show docker):

Name: docker
Version: 3.0.0
Summary: A Python library for the Docker Engine API.
Home-page: https://github.com/docker/docker-py
Author: Joffrey F
Author-email: joffrey@docker.com
License: Apache License 2.0
Location: c:\anwendungen\python36-32\lib\site-packages
Requires: websocket-client, pypiwin32, docker-pycreds, six, requests

Solution

Calling output on permissions solves the issue for docker >=3.0.0.

docker_volume_watcher (https://github.com/merofeev/docker-windows-volume-watcher/blob/master/docker_volume_watcher/container_notifier.py#L66)

...
 permissions = self.container.exec_run(
                ['stat', '-c', '%a', absolute_path], privileged=True)
            permissions = permissions.output.decode('utf-8').strip()
            response = self.container.exec_run(
                ['chmod', permissions, absolute_path], privileged=True)
...

The cause seems to be that the output of exec_run changed to an ExecResult instead of a string with the version bump to 3.0.0: https://github.com/docker/docker-py/blob/05d34ed1fbaa8233a4cf51a0f52b67aef99a9521/docker/models/containers.py#L129.

Ideally, permissions is checked for its type before calling decode on it.

ArneZsng commented 6 years ago

@merofeev I created this issue with @RolandMay and just noticed that it is a duplicate of #8. Let me know if we can help by creating a PR.

merofeev commented 6 years ago

Hi @ArneZsng , @RolandMay ! Thanks for suggesting the solution and sorry for delay with response (I'm currently on vacation). If you could contribute PR, this will be great! If you decide to do it let me suggest a few things:

  1. To avoid type checking of value returned by exec_run we can set minimum version of docker package to 3.0.0 in both requirements.txt and setup.py
  2. I think we also should check exit code returned by exec_run and show some warning message to user in case we failed to execute chmod or stat
merofeev commented 6 years ago

Should be fixed by #10