-
Notifications
You must be signed in to change notification settings - Fork 1
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
Basic Structure #5
base: develop
Are you sure you want to change the base?
Changes from all commits
63590c4
a0a4a1a
7a1ce10
f5733a4
0d3cf5b
76e47a7
33b69b6
4129a5e
6103cd3
0d56ca3
b576615
5c1b300
ef6f987
ca1a0f5
6614c12
95642c8
ed966e8
ee11d02
a578983
e632caa
bd88e15
09b44bd
26297a8
215a1a5
839f52c
1510445
3156873
ba00f2f
8959150
0eff03a
aa26361
a8bdcb8
b2f4425
562efac
cd1e570
6dac2c3
819b715
f317a7c
2e5099c
d7268cb
8faeee7
6efb915
4081893
f5b6a8b
94ddbe9
b6fe20e
d6db3c4
8fcdf5f
d53e546
8b1bcff
d206f34
6a2260c
1e8a311
adb61a3
b1159c2
b25a26c
3e31fb6
e14fcfb
36fc8a3
e72898f
bdb4806
c56e01d
407fc4b
99af59d
883fe7f
92ea031
800e5d9
9dfb7f1
cc1a0f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.pyc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
recursive-include public * |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
================================================================= | ||
Add fixed bugs in this file. Select a format to add bugs. | ||
================================================================= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
======================================================================== | ||
Add already implemented. | ||
======================================================================== |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
================================================================= | ||
Add known bugs in this file. Select a format to add bugs. | ||
================================================================= | ||
1) Add support for different communication mechnism between api server | ||
and engine. | ||
--> Message queue | ||
--> API server itself | ||
|
||
2) Create /var/run/netns at the start of the dockyard. | ||
3) Add database feature to keep data even after reboot. | ||
4) Add feature to create resource as dockyard start. | ||
5) Write a single function, which will load modules dynmically by taking | ||
information from the configuration file. It is being done many times in | ||
the project which will lead to resuability of the code. | ||
6) Create an API for attaching external network to the docker container |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
======================================================================== | ||
Add blueprints that needs to implmented. | ||
======================================================================== | ||
1. Monitoring of containers. User can specify which container to monitor. The monitoring module would monitor the containers and start the stopped container. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from oslo_config import cfg | ||
import pecan | ||
from pecan import make_app | ||
|
||
from dockyard.api import config as api_config | ||
# To be used later for initialization of database | ||
#from dockyard import model | ||
|
||
|
||
API_SERVICE_OPT = [ | ||
cfg.PortOpt('port', | ||
default=5869, | ||
help='Port for the dockyard service.'), | ||
cfg.IPOpt('host', | ||
default='0.0.0.0', | ||
help='Listening address for dockyard service'), | ||
] | ||
|
||
CONF = cfg.CONF | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure but there must be a way to define values of these parameters through configuration file. So that these default values can be overridden. 💯 |
||
opt_group = cfg.OptGroup(name='default', | ||
title='Group for the default values of dockyard api') | ||
CONF.register_group(opt_group) | ||
CONF.register_opts(API_SERVICE_OPT, opt_group) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Provide a sample file also for the reference, so that it can be used for development purpose. |
||
|
||
|
||
def get_pecan_config(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of this function, we have to identify and then remove if not required. |
||
# Set up the pecan configuration | ||
filename = api_config.__file__.replace('.pyc', '.py') | ||
return pecan.configuration.conf_from_file(filename) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think specific import can be done here, from pecan import configuration, need to check any guideline, use better and consistent. |
||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Write documentation for the each class and method of the class or function. |
||
def setup_app(config=None): | ||
if not config: | ||
config = get_pecan_config() | ||
|
||
# To be used later for initialization of database | ||
# model.init_model() | ||
app_conf = dict(config.app) | ||
|
||
return make_app( | ||
app_conf.pop('root'), | ||
logging=getattr(config, 'logging', {}), | ||
**app_conf | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Pecan Application Configurations | ||
app = { | ||
'root': 'dockyard.controllers.root.RootController', | ||
'modules': ['dockyard', 'dockyard.api'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As per documentation, for modules key values should be one. You can have two values but recommended is one. Therefor correct it and put only one required value. |
||
'debug': True | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import os | ||
import sys | ||
|
||
from oslo_config import cfg | ||
from oslo_log import log as logging | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logging not used in this module There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently application is running in foreground, we need to make it run as a service. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
from wsgiref import simple_server | ||
|
||
from dockyard.api import app as api_app | ||
from dockyard.common import utils | ||
|
||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
def main(): | ||
utils.prepare_logging(sys.argv) | ||
|
||
app = api_app.setup_app() | ||
|
||
# create the wsgi server and start it | ||
host, port = cfg.CONF.default.host, cfg.CONF.default.port | ||
srv = simple_server.make_server(host, port, app) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have to decide about loggin polices, As logging is not being done now. |
||
|
||
LOG.info('Starting dockyard in PID %s', os.getpid()) | ||
LOG.debug("Configuration:") | ||
cfg.CONF.log_opt_values(LOG, logging.DEBUG) | ||
|
||
LOG.info('serving at http://%s:%s' % (host, port)) | ||
srv.serve_forever() | ||
|
||
|
||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import ast | ||
import importlib | ||
from oslo_config import cfg | ||
from threading import Thread | ||
import time | ||
from dockyard.common.container.container import Container | ||
from dockyard.common.image.image import Image | ||
from dockyard.common.network.network import Network | ||
from dockyard.common.volume.volume import Volume | ||
from dockyard.common.utils import get_localhost_ip | ||
from dockyard.engine_client.synchronizer.synchronizer import ( | ||
ContainerSynchronizer) | ||
|
||
CONF = cfg.CONF | ||
|
||
|
||
class Synchronizer(Thread): | ||
def __init__(self): | ||
if CONF.docker.docker_host == "0.0.0.0": | ||
for ip in get_localhost_ip(): | ||
host = ip | ||
break | ||
else: | ||
host = CONF.docker.docker_host | ||
|
||
port = CONF.docker.docker_port | ||
self.host = { 'host': host, 'port': port } | ||
Thread.__init__(self) | ||
self.container = Container() | ||
self.image = Image() | ||
self.network = Network() | ||
self.volume = Volume() | ||
self.synchronizer = ContainerSynchronizer() | ||
self.sleep_time = CONF.database.synchronization_time | ||
|
||
|
||
def run(self): | ||
"""This thread is responsible for synchronizations of containers, | ||
and other docker resources. | ||
""" | ||
while True: | ||
self._synchronize() | ||
time.sleep(self.sleep_time) | ||
|
||
def _get_format(self, value, type_): | ||
"""This method converts a container information into the required format | ||
for the container. | ||
""" | ||
f_val = dict() | ||
for v in value: | ||
f_val[v] = "OK" | ||
|
||
value = {type_: f_val} | ||
key = (self.host["host"], type_) | ||
return (key, value) | ||
|
||
def _synchronize_container(self): | ||
containers = self.container.list(host=self.host) | ||
return self._sync(containers, type_="container") | ||
|
||
def _synchronize_image(self): | ||
images = self.image.list(host=self.host) | ||
return self._sync(images, type_="image") | ||
|
||
def _synchronize_network(self): | ||
networks = self.network.list(host=self.host) | ||
return self._sync(networks, type_="network") | ||
|
||
def _synchronize_volume(self): | ||
volumes = self.container.list(host=self.host) | ||
return self._sync(volumes, type_="volume") | ||
|
||
def _get_ids(self, info_s): | ||
"""This method returns all the values ids from the list of | ||
dictionary received. | ||
""" | ||
ids = [x["Id"] for x in info_s] | ||
return ids | ||
|
||
def _sync(self, info_s, type_=None): | ||
info_s = info_s.replace("null", "None") | ||
info_s = info_s.replace("true", "True") | ||
info_s = info_s.replace("false", "False") | ||
info_s = ast.literal_eval(info_s) | ||
info_s = self._get_ids(info_s) | ||
info_s = self._get_format(value=info_s, type_=type_) | ||
self.synchronizer.synchronize([info_s]) | ||
|
||
def _synchronize(self): | ||
"""This method fetch all the containers running on local machines. | ||
""" | ||
self._synchronize_container() | ||
self._synchronize_volume() | ||
self._synchronize_image() | ||
self._synchronize_network() | ||
|
||
|
||
def run_synchronizer(): | ||
"""This method is responsible for synchronizing containers information | ||
with the consul databse. | ||
""" | ||
sync = Synchronizer() | ||
sync.setName("Synchronizer") | ||
sync.start() | ||
|
||
run_synchronizer() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import abc | ||
import importlib | ||
from oslo_config import cfg | ||
from pecan import request | ||
from urllib3 import PoolManager | ||
|
||
ENGINE_CLIENT_OPT = [ | ||
cfg.StrOpt('engine_client', | ||
default='api_server.api_server.APIServerEngineClient', | ||
help='Client to be used for sending request to engine') | ||
] | ||
|
||
CONF = cfg.CONF | ||
CONF.register_opts(ENGINE_CLIENT_OPT, group='default') | ||
|
||
# Fetch scheduler defined in the configuration file and load it. | ||
engine_client_info = CONF.default.engine_client | ||
# May be this path can be specified in the configuration file. | ||
engine_client_loc = 'dockyard.engine_client' | ||
engine_client_info = (('%s.%s') % (engine_client_loc, engine_client_info)) | ||
module_name, class_name = engine_client_info.rsplit(".", 1) | ||
engine_client = getattr(importlib.import_module(module_name), class_name) | ||
|
||
class URL(object): | ||
def __init__(self): | ||
pass | ||
|
||
@abc.abstractmethod | ||
def send(self, method, url, headers=None, post_params=None, | ||
body=None, **kwargs): | ||
"""This methos is responsible for sending the request. | ||
:method: Method to be used for sending request. | ||
:url: URL to be send. | ||
:headers: headers in the requests. | ||
:post_params: post parameters. | ||
:body: Request body. | ||
""" | ||
|
||
class DockyardURL(URL): | ||
def __init__(self): | ||
self.engine_client = engine_client() | ||
self.pool = PoolManager() | ||
|
||
def _is_local_request(self): | ||
"""This method checks whether this is request for docker engine. | ||
""" | ||
try: | ||
request.headers.environ['Request-Status'] | ||
except KeyError: | ||
status = False | ||
except: | ||
status = True | ||
|
||
return status | ||
|
||
def send(self, method, url, headers=None, post_params=None, | ||
body=None, **kwargs): | ||
"""This methos is responsible for sending the request. | ||
:method: Method to be used for sending request. | ||
:url: URL to be send. | ||
:headers: headers in the requests. | ||
:post_params: post parameters. | ||
:body: Request body. | ||
""" | ||
req_type = self._is_local_request() | ||
# Pre processing needs to be done for dockyard feature before | ||
# performing some actions | ||
if req_type: | ||
self.engine_client.process(method=method, url=url, r_type="pre", | ||
body=body, headers=headers) | ||
|
||
data = self.pool.urlopen(method, url, headers=headers, body=body).data | ||
# Post processing needs to be done for some of the dockyard operations | ||
if req_type: | ||
self.engine_client.process(method=method, url=url, r_type="post", | ||
body=body, headers=headers) | ||
return data |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from oslo_config import cfg | ||
from oslo_log import log as logging | ||
|
||
|
||
class Cluster(object): | ||
def __init__(self): | ||
pass | ||
|
||
def register(self, cluster_id, host_ip, port): | ||
pass | ||
|
||
def unregister(self, cluster_id, host_ip): | ||
pass | ||
|
||
def get_hosts(self): | ||
LOG.debug("Registered hosts: %s" % cfg.CONF.membership.hosts) | ||
return cfg.CONF.membership.hosts | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Write a better membership algorithm because this one always adds its own host only. We have to decide about membership protocol to be used in this product. |
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 some requirement file also need to be created which specify the dependency modules(ex. oslo_config) for running dockyard.