-
-
Notifications
You must be signed in to change notification settings - Fork 104
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
Aiodocker Helper #341
Aiodocker Helper #341
Conversation
Pull Request Test Coverage Report for Build 1058
💛 - Coveralls |
self.logger.exception('Error while fetching %s container %s', container_name, server_error) | ||
return container | ||
|
||
async def create_container(self, container_name, cmd=None, image=None): |
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 function, for now, is used only in tests, why you need it?
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.
Yes, because with aiodocker we can execute commands in both ways, by using client.containers.create
and with docker_client.containers.run
as well. But, I think its good to have this method if we need to create container at some point then it can help :)
|
||
async def create_attacker_env(self, session): |
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.
why you don't associate docker with a session anymore?
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.
For the above reason, I only followed one method to execute commands (containers.run
) :) so haven't used a container like the previous implementation.
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 am interested more in re-using containers. Creating a new container each time might be critical for small instances
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.
You're right, got your point.
image = self.host_image | ||
|
||
config = {"Cmd": cmd, "Image": image} | ||
container = await self.docker_client.containers.run(config=config) |
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.
As far as I understood, you create all the time new containers with a random name, how you suppose to clean it?
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.
For now these containers have to be deleted manually because of the risk other containers can also be deleted if we try to delete them all.
Do you have something else in mind?
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.
Previously we had a procedure to delete containers in session routine, the idea is to have an associated container with session and delete it by name while deleting the session
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.
Ahh! Yes, then in this case we should use create method to run commands in emulators right?
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.
You can use create
, get
and start
methods
or
You can still create the containers with run
and delete it right after the execution.
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 don't know what is better in terms of architecture and performance, you can test it :)
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 think the second method works best. :)
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.
The only problem I can imagine with a second approach is a (possible) inconsistency in the sequence of requests. And also, have you measured what is faster: always create and delete new one or get existing and start it? I would be happy to see such comparison
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.
So, I analyzed the performance of both methods - (averaged multiple runs)
-
create_or_replace: gets the container and replaces new config or creates a new one + starting the container - 1.4206 sec (deleting time and logs output time has to be added)
-
run + delete: creates a new container and deleting [ had to force :( ] container + checking output using logs- 1.5324 sec
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 think it's not a significant performance difference, but the method you will prefer would be final :)
tanner/utils/aiodocker_helper.py
Outdated
except aiodocker.exceptions.DockerError as server_error: | ||
self.logger.exception('Error while removing %s container %s', container_name, server_error) | ||
|
||
async def close_docker(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.
used only in tests
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.
Should I close the client directly in tests and remove this?
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 think in test yes and on tanner shutdown either
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.
Done.
execute_result = execute_result.replace('\x00', '\n') | ||
return execute_result | ||
cmd = ["sh", "-c", "cat {file}".format(file=shlex.quote(file_path))] | ||
execute_result = await self.helper.execute_cmd(cmd) |
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.
since in lfi we are only read the files, it's better to create only 1 container (pass the same name) and on a shutdown of tanner remove this container
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.
As such we don't really need to create a container before to execute some commands. I guess run
method creates them itself.
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.
Run method creates the containers, yes, but it will create each time a new container, which is not ok.
Changes made: