-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
get container metadata from docker metadata #210
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, pretty good progress!
conu/apidefs/metadata.py
Outdated
@@ -47,8 +47,8 @@ def __init__(self, name=None, identifier=None, labels=None, command=None, | |||
:param env_variables: dict, {name: value} | |||
:param image: Image, reference to Image instance | |||
:param exposed_ports: list, list of exposed ports | |||
:param port_mappings: dict, dictionary of port mappings {"host_port": "container_port"}, example: | |||
- {"8080":"80"} map port 80 in the container to port 8080 on the host | |||
:param port_mappings: dict, dictionary of port mappings {"host_port": ["container_port"]}, example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this doesn't make much sense to me. How could one external port be mapped to two internal?
conu/backend/docker/container.py
Outdated
@@ -475,3 +490,69 @@ def write_to_stdin(self, message): | |||
self.popen_instance.stdin.flush() | |||
except subprocess.CalledProcessError as e: | |||
raise ConuException(e) | |||
|
|||
def get_container_metadata(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we discussed this with @dhodovsk and my suggestion was to break backwards compatibility: .get_metadata method would return instance of the Metadata class, and .inspect method would yield the dict from docker. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, get_metadata() can be used for conu-metadata. I'd suggest adding new commit that would rename all get_metadata() to inspect().
conu/backend/docker/container.py
Outdated
|
||
docker_metadata = self.get_metadata(refresh=True) | ||
|
||
print(docker_metadata) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably a leftover from debugging
conu/backend/docker/container.py
Outdated
# ['DISTTAG=f26container', 'FGC=f26'] | ||
env_variables = dict() | ||
for env_variable in docker_metadata['Config']['Env']: | ||
env_variables.update({env_variable.split('=')[0]: env_variable.split('=')[1]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I advise to do .split("=", 1)
since =
can be put also in the value; the other potential error could occur if the value is unset
Please add these two cases to tests.
Real example:
"Env": [
"ASD=",
"A=B=C=D",
"XYZ",
"DISTTAG=f28container",
"FGC=f28"
],
$ env
A=B=C=D
HOSTNAME=36256ed1fe0d
PWD=/
HOME=/root
DISTTAG=f28container
ASD=
FGC=f28
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/env
conu/backend/docker/container.py
Outdated
status = ContainerStatus.CREATED | ||
|
||
if docker_metadata['State']['Status'] == 'created': | ||
status = ContainerStatus.CREATED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure whether we should copy all the possible status from docker just like that. I would love to discuss this next week during our call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On meeting we decided on 4 states:
- Running
- Not-Running (Stopped, Created, Exited - with 0 code)
- Unknown (Restarting, Terminating,...)
- Failed
conu/backend/docker/container.py
Outdated
status = ContainerStatus.DEAD | ||
|
||
# format of Port mappings from docker inspect: | ||
# {'12345/tcp': [{'HostIp': '0.0.0.0', 'HostPort': '123'}, {'HostIp': '0.0.0.0', 'HostPort': '1234'}]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see, it's actually the other way around: multiple host ports can point to a single container port
tests/integration/test_docker.py
Outdated
assert container_metadata.status == ContainerStatus.RUNNING | ||
|
||
c.delete(force=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be in finally:
block
Thank you for the review. I pushed some new changes. We can discuss name of the methods and ContainerStatus on next meeting. I totally agree to not copy all fields from docker but make it more general. |
conu/backend/docker/container.py
Outdated
@@ -475,3 +490,69 @@ def write_to_stdin(self, message): | |||
self.popen_instance.stdin.flush() | |||
except subprocess.CalledProcessError as e: | |||
raise ConuException(e) | |||
|
|||
def get_container_metadata(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, get_metadata() can be used for conu-metadata. I'd suggest adding new commit that would rename all get_metadata() to inspect().
conu/backend/docker/container.py
Outdated
|
||
status = ContainerStatus.CREATED | ||
|
||
if docker_metadata['State']['Status'] == 'created': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a method on ContainerStatus -> status = ContainerStatus.get(string)
for env_variable in docker_metadata['Config']['Env']: | ||
try: | ||
env_variables.update({env_variable.split('=', 1)[0]: env_variable.split('=', 1)[1]}) | ||
except IndexError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this expected? If not, we should raise something.
conu/backend/docker/container.py
Outdated
if key in port_mappings.keys(): | ||
port_mappings[key].append(int(item['HostPort'])) | ||
else: | ||
port_mappings.update({key: [int(item['HostPort'])]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fails when inspecting container that is created with docker run -p 80 nginx
conu/backend/docker/container.py
Outdated
creation_timestamp=docker_metadata['Created'], | ||
env_variables=env_variables, | ||
image=image, | ||
exposed_ports=list(docker_metadata['Config']['ExposedPorts'].keys()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When there are no exposed ports on container, this field is missing in inspect and get_container_metadata()
fails on KeyError
tests/integration/test_docker.py
Outdated
assert container_metadata.hostname == "my_hostname" | ||
assert "XYZ" not in list(container_metadata.env_variables.keys()) | ||
assert container_metadata.port_mappings["1234"] == "12345/tcp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
container_metadata.port_mappings
actually returns {'12345/tcp': [1234, 123]}
in this case.
jenkins/superCI comment
|
The requested changes were addressed, it looks good! Thank you! |
@@ -433,7 +439,7 @@ def get_status(self): | |||
|
|||
:return: one of: 'created', 'restarting', 'running', 'paused', 'exited', 'dead' | |||
""" | |||
return self.get_metadata(refresh=True)["State"]["Status"] | |||
return self.inspect(refresh=True)["State"]["Status"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be awesome to use .get_metadata
for these. Not blocking this PR,
We need to discuss the naming of methods here, get_metadata and get_container_metadata sounds similar what can be confusing for users.