Skip to content

Commit

Permalink
Supports YML and JSON in 2.1.1 (#2)
Browse files Browse the repository at this point in the history
* feat: support yml and json

* refactor: EasierDocker and log

* docs: update readme

* fix: setup version and license

* fix: add container ip address log

* docs: update README.md

* docs: update README.md
  • Loading branch information
touero committed Dec 1, 2023
1 parent 64b0348 commit 8f52279
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 34 deletions.
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ if __name__ == '__main__':
easier_docker = EasierDocker(config)
easier_docker.start()
"""
>>> Finding python:3.9 docker image in local
>>> Finding python_test docker container in local
>>> ContainerNotFound: python_test
>>> container id: d9233f82e9a17627d51d294091b43295fdcf3e2fae204f2d8e2bb7080b88c0b0 is running
>>> 2023-11-27 14:40:29,264 - INFO - easier-docker ==> Find docker image: [python:3.9] locally...:
>>> 2023-11-27 14:40:29,280 - INFO - easier-docker ==> Image: [python:3.9] is found locally
>>> 2023-11-27 14:40:29,280 - INFO - easier-docker ==> Find docker container: [python_test] locally...:
>>> 2023-11-27 14:40:29,284 - INFO - easier-docker ==> ContainerNotFound: [python_test], it will be created
>>> 2023-11-27 14:40:29,558 - INFO - easier-docker ==> Container name: [python_test] is running
>>> 2023-11-27 14:40:29,558 - INFO - easier-docker ==> Container id: [58509ced60ba] is running
>>> 2023-11-27 14:40:29,559 - INFO - easier-docker ==> Successfully container is running and be created at 2023-11-27T06:40:29.291320745Z
"""
```
The content of docker_example.py is
Expand All @@ -72,7 +75,7 @@ if __name__ == '__main__':
```

### Run directly from configuration file
Currently supports yaml
Currently supports type of file: _yml_, _yaml_, _json_
```bash
easier-docker -c config.yaml
```
Expand All @@ -94,14 +97,10 @@ command:
```


<div align="center">
<img src="https://github.com/weiensong/easier-docker/blob/master/image/containers.png" alt="containers" style="max-width:400px; max-height:300px;" />
</div>

<div align="center">
<img src="https://github.com/weiensong/easier-docker/blob/master/image/containers_log.png" alt="containers log" style="max-width:400px; max-height:300px;" />
</div>

| |
|--------------------------------------------------------------------------------------------------------|
| ![containers.png](https://github.com/weiensong/easier-docker/blob/master/image/containers.png) |
| ![containers_log.png](https://github.com/weiensong/easier-docker/blob/master/image/containers_log.png) |


## Related Repository
Expand All @@ -118,7 +117,7 @@ Building a Basic Information API for Chinese National Universities in the Handhe


## Maintainers
[@weiensong](https://github.com/weiensong)
[@touero](https://github.com/touero)


## Contributing
Expand Down
13 changes: 10 additions & 3 deletions easierdocker/config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import json
import yaml

from easierdocker.log_re import log


class Config:
def __init__(self, file_path: str):
self.file_path = file_path

def load_file(self) -> dict:
config = {}
if self.file_path.endswith('.yaml'):
config: dict = yaml.load(open(self.file_path, encoding='utf8'), yaml.FullLoader)
with open(self.file_path, encoding='utf8') as file:
if self.file_path.endswith(('.yaml', '.yml')):
config: dict = yaml.safe_load(file)
elif self.file_path.endswith('.json'):
config: dict = json.load(file)
else:
log(f'Currently unsupported file types: {self.file_path}')
return config

40 changes: 27 additions & 13 deletions easierdocker/easier_docker.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import json
import docker

import json
from .exceptions import DockerConnectionError
from .log_re import log

from typing import Union
from docker.errors import ImageNotFound, APIError
from docker.errors import ImageNotFound, APIError, DockerException
from docker.models.containers import Container


class EasierDocker:
def __init__(self, config: dict):
self._client = docker.from_env()
try:
self._client = docker.from_env()
except Exception as e:
if isinstance(e, DockerException):
raise DockerConnectionError
raise e
self.config = config
self.image_name = self.config['image']
self.container_name = self.config['name']

def _get_image(self):
log(f'Finding {self.image_name} docker image in local')
log(f'Find docker image: [{self.image_name}] locally...')
try:
self._client.images.get(self.image_name)
log(f'Image: [{self.image_name}] is found locally')
except Exception as e:
if isinstance(e, ImageNotFound):
log(f'ImageNotFound: {str(e)}')
log(f'Waiting docker pull {self.image_name}')
log(f'ImageNotFound: {str(e)}, it will be pulled')
log(f'Waiting docker pull {self.image_name}...')
for event in self._client.api.pull(self.image_name, stream=True):
event_info = json.loads(event.decode('utf-8'))
if 'status' in event_info:
Expand All @@ -34,21 +40,29 @@ def _get_image(self):
log(str(e))

def _get_container(self) -> Union[Container, None]:
log(f'Finding {self.container_name} docker container in local')
log(f'Find docker container: [{self.container_name}] locally...')
containers = self._client.containers.list(all=True)
for container in containers:
if self.container_name == container.name:
log(f'Finding docker container: {container.id}')
log(f'Container name: [{container.name}] is found locally')
log(f'Container id: [{container.short_id}] is found locally')
ip_address = container.attrs['NetworkSettings']['IPAddress']
log(f'Container ip address: [{ip_address}]')
created_time = container.attrs['Created']
log(f'Successfully container continue running and be created at {created_time}')
return container
log(f'ContainerNotFound: {self.container_name}')
log(f'ContainerNotFound: [{self.container_name}], it will be created')
return None

def _run_container(self):
try:
container: Container = self._client.containers.run(**self.config)
log(f'Container name: {container.name} is running')
log(f'Container id: {container.id} is running')
log('Successfully started container')
log(f'Container name: [{container.name}] is running')
log(f'Container id: [{container.short_id}] is running')
ip_address = container.attrs['NetworkSettings']['IPAddress']
log(f'Container ip address: [{ip_address}]')
created_time = container.attrs['Created']
log(f'Successfully container is running and be created at {created_time}')
except Exception as e:
if isinstance(e, APIError):
log(f'Error starting container: {str(e)}')
Expand Down
4 changes: 4 additions & 0 deletions easierdocker/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class DockerConnectionError(Exception):
def __init__(self, message="Unable to connect to Docker server, please make sure dockers is running."):
self.message = message
super().__init__(self.message)
4 changes: 2 additions & 2 deletions easierdocker/log_re.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ def log_info(self, msg: str = ''):
self.logger.info(msg)


logger = LogRe()
log = logger.log_info
_logger = LogRe()
log = _logger.log_info

8 changes: 6 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='easier-docker',
version='2.0.0',
version='2.1.0',
author='weiensong',
author_email='[email protected]',
description='It can create a container based on the local image. If the image does not exist, the image will be '
Expand All @@ -23,8 +23,12 @@
],
},
classifiers=[
'License :: OSI Approved :: MIT License',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
],
keywords='easy, docker, docker sdk, python docker',
project_urls={
Expand Down

0 comments on commit 8f52279

Please sign in to comment.