Browse Source

Move statless design from experiment to master branch

The statless design was developed in the experiment branch, the experiment
shows advantage in removing the status synchronization, uuid mapping
compared to the stateful design, and also fully reduce the coupling with
OpenStack services like Nova, Cinder. The overhead query latency for
resources also acceptable. It's time to move the statless design to the
master branch

BP: https://blueprints.launchpad.net/tricircle/+spec/implement-stateless

Change-Id: I51bbb60dc07da5b2e79f25e02209aa2eb72711ac
Signed-off-by: Chaoyi Huang <joehuang@huawei.com>
changes/93/267293/2
Chaoyi Huang 5 years ago
parent
commit
81b45f2c1d
119 changed files with 10088 additions and 4643 deletions
  1. +105
    -5
      README.md
  2. +8
    -9
      cmd/api.py
  3. +63
    -0
      cmd/cinder_apigw.py
  4. +0
    -85
      cmd/dispatcher.py
  5. +2
    -2
      cmd/manage.py
  6. +68
    -0
      cmd/nova_apigw.py
  7. +0
    -85
      cmd/proxy.py
  8. +61
    -0
      cmd/xjob.py
  9. +18
    -11
      devstack/local.conf.sample
  10. +261
    -74
      devstack/plugin.sh
  11. +26
    -10
      devstack/settings
  12. +90
    -50
      doc/source/api_v1.rst
  13. +16
    -0
      etc/api-cfg-gen.conf
  14. +0
    -412
      etc/api.conf
  15. +16
    -0
      etc/cinder_apigw-cfg-gen.conf
  16. +0
    -521
      etc/dispatcher.conf
  17. +16
    -0
      etc/nova_apigw-cfg-gen.conf
  18. +0
    -485
      etc/policy.json
  19. +15
    -0
      etc/xjob-cfg-gen.conf
  20. +3
    -3
      requirements.txt
  21. +9
    -0
      setup.cfg
  22. +1
    -1
      test-requirements.txt
  23. +8
    -6
      tox.ini
  24. +0
    -0
      tricircle/api/__init__.py
  25. +29
    -21
      tricircle/api/app.py
  26. +301
    -0
      tricircle/api/controllers/pod.py
  27. +22
    -90
      tricircle/api/controllers/root.py
  28. +22
    -0
      tricircle/api/opts.py
  29. +0
    -0
      tricircle/cinder_apigw/__init__.py
  30. +76
    -0
      tricircle/cinder_apigw/app.py
  31. +0
    -0
      tricircle/cinder_apigw/controllers/__init__.py
  32. +118
    -0
      tricircle/cinder_apigw/controllers/root.py
  33. +332
    -0
      tricircle/cinder_apigw/controllers/volume.py
  34. +22
    -0
      tricircle/cinder_apigw/opts.py
  35. +164
    -0
      tricircle/common/az_ag.py
  36. +75
    -0
      tricircle/common/baserpc.py
  37. +0
    -76
      tricircle/common/cascading_networking_api.py
  38. +0
    -50
      tricircle/common/cascading_site_api.py
  39. +103
    -49
      tricircle/common/client.py
  40. +13
    -63
      tricircle/common/config.py
  41. +46
    -0
      tricircle/common/constants.py
  42. +50
    -2
      tricircle/common/context.py
  43. +40
    -1
      tricircle/common/exceptions.py
  44. +138
    -0
      tricircle/common/httpclient.py
  45. +124
    -0
      tricircle/common/lock_handle.py
  46. +0
    -65
      tricircle/common/nova_lib.py
  47. +26
    -0
      tricircle/common/opts.py
  48. +320
    -0
      tricircle/common/resource_handle.py
  49. +52
    -0
      tricircle/common/restapp.py
  50. +131
    -115
      tricircle/common/rpc.py
  51. +11
    -6
      tricircle/common/serializer.py
  52. +0
    -80
      tricircle/common/service.py
  53. +0
    -30
      tricircle/common/singleton.py
  54. +1
    -6
      tricircle/common/topics.py
  55. +13
    -6
      tricircle/common/utils.py
  56. +1
    -3
      tricircle/common/version.py
  57. +74
    -0
      tricircle/common/xrpcapi.py
  58. +168
    -0
      tricircle/db/api.py
  59. +27
    -9
      tricircle/db/core.py
  60. +0
    -70
      tricircle/db/exception.py
  61. +32
    -15
      tricircle/db/migrate_repo/versions/001_init.py
  62. +196
    -0
      tricircle/db/migrate_repo/versions/002_resource.py
  63. +244
    -47
      tricircle/db/models.py
  64. +22
    -0
      tricircle/db/opts.py
  65. +0
    -191
      tricircle/db/resource_handle.py
  66. +0
    -126
      tricircle/dispatcher/compute_manager.py
  67. +0
    -52
      tricircle/dispatcher/endpoints/networking.py
  68. +0
    -32
      tricircle/dispatcher/endpoints/site.py
  69. +0
    -50
      tricircle/dispatcher/host_manager.py
  70. +0
    -77
      tricircle/dispatcher/service.py
  71. +0
    -140
      tricircle/dispatcher/site_manager.py
  72. +0
    -0
      tricircle/network/__init__.py
  73. +850
    -0
      tricircle/network/plugin.py
  74. +0
    -149
      tricircle/networking/plugin.py
  75. +0
    -38
      tricircle/networking/rpc.py
  76. +0
    -0
      tricircle/nova_apigw/__init__.py
  77. +76
    -0
      tricircle/nova_apigw/app.py
  78. +0
    -0
      tricircle/nova_apigw/controllers/__init__.py
  79. +128
    -0
      tricircle/nova_apigw/controllers/aggregate.py
  80. +198
    -0
      tricircle/nova_apigw/controllers/flavor.py
  81. +43
    -0
      tricircle/nova_apigw/controllers/image.py
  82. +163
    -0
      tricircle/nova_apigw/controllers/root.py
  83. +384
    -0
      tricircle/nova_apigw/controllers/server.py
  84. +22
    -0
      tricircle/nova_apigw/opts.py
  85. +0
    -751
      tricircle/proxy/compute_manager.py
  86. +0
    -42
      tricircle/proxy/service.py
  87. +20
    -0
      tricircle/tests/base.py
  88. +0
    -0
      tricircle/tests/functional/__init__.py
  89. +0
    -0
      tricircle/tests/functional/api/__init__.py
  90. +0
    -0
      tricircle/tests/functional/api/controllers/__init__.py
  91. +622
    -0
      tricircle/tests/functional/api/controllers/test_pod.py
  92. +171
    -0
      tricircle/tests/functional/api/controllers/test_root.py
  93. +0
    -0
      tricircle/tests/functional/cinder_apigw/__init__.py
  94. +0
    -0
      tricircle/tests/functional/cinder_apigw/controllers/__init__.py
  95. +172
    -0
      tricircle/tests/functional/cinder_apigw/controllers/test_root.py
  96. +460
    -0
      tricircle/tests/functional/cinder_apigw/controllers/test_volume.py
  97. +0
    -0
      tricircle/tests/functional/nova_apigw/__init__.py
  98. +0
    -0
      tricircle/tests/functional/nova_apigw/controllers/__init__.py
  99. +173
    -0
      tricircle/tests/functional/nova_apigw/controllers/test_root.py
  100. +135
    -0
      tricircle/tests/unit/api/controllers/test_pod.py

+ 105
- 5
README.md View File

@ -1,11 +1,111 @@
# Tricircle
(Attention Please, Stateless Design Proposal is being worked on the ["experiment"](https://github.com/openstack/tricircle/tree/experiment) branch).
(The original PoC source code, please switch to
["poc"](https://github.com/openstack/tricircle/tree/poc) tag, or
["stable/fortest"](https://github.com/openstack/tricircle/tree/stable/fortest)
branch)
(The origningal PoC source code, please switch to ["poc"](https://github.com/openstack/tricircle/tree/poc) tag, or ["stable/fortest"](https://github.com/openstack/tricircle/tree/stable/fortest) branch)
Tricircle is an OpenStack project that aims to deal with multiple OpenStack
deployment across multiple data centers. It provides users a single management
view by having only one Tricircle instance on behalf of all the involved
OpenStack instances.
Tricircle is a openstack project that aims to deal with OpenStack deployment across multiple sites. It provides users a single management view by having only one OpenStack instance on behalf of all the involved ones. It essentially serves as a communication bus between the central OpenStack instance and the other OpenStack instances that are called upon.
Tricircle presents one big region to the end user in KeyStone. And each
OpenStack instance, which is called a pod, is a sub-region of Tricircle in
KeyStone, and not visible to end user directly.
Tricircle acts as OpenStack API gateway, can accept all OpenStack API calls
and forward the API calls to regarding OpenStack instance(pod), and deal with
cross pod networking automaticly.
The end user can see avaialbility zone (AZ in short) and use AZ to provision
VM, Volume, even Network through Tricircle.
Similar as AWS, one AZ can includes many pods, and a tenant's resources will
be bound to specific pods automaticly.
## Project Resources
- Project status, bugs, and blueprints are tracked on [Launchpad](https://launchpad.net/tricircle)
- Additional resources are linked from the project [Wiki](https://wiki.openstack.org/wiki/Tricircle) page
License: Apache 2.0
- Design documentation: [Tricircle Design Blueprint](https://docs.google.com/document/d/18kZZ1snMOCD9IQvUKI5NVDzSASpw-QKj7l2zNqMEd3g/)
- Wiki: https://wiki.openstack.org/wiki/tricircle
- Documentation: http://docs.openstack.org/developer/tricircle
- Source: https://github.com/openstack/tricircle
- Bugs: http://bugs.launchpad.net/tricircle
- Blueprints: https://launchpad.net/tricircle
## Play with DevStack
Now stateless design can be played with DevStack.
- 1 Git clone DevStack.
- 2 Git clone Tricircle, or just download devstack/local.conf.sample
- 3 Copy devstack/local.conf.sample to DevStack folder and rename it to
local.conf, change password in the file if needed.
- 4 Run DevStack.
- 5 After DevStack successfully starts, check if services have been correctly
registered. Run "openstack endpoint list" and you should get similar output
as following:
```
+----------------------------------+-----------+--------------+----------------+
| ID | Region | Service Name | Service Type |
+----------------------------------+-----------+--------------+----------------+
| 230059e8533e4d389e034fd68257034b | RegionOne | glance | image |
| 25180a0a08cb41f69de52a7773452b28 | RegionOne | nova | compute |
| bd1ed1d6f0cc42398688a77bcc3bda91 | Pod1 | neutron | network |
| 673736f54ec147b79e97c395afe832f9 | RegionOne | ec2 | ec2 |
| fd7f188e2ba04ebd856d582828cdc50c | RegionOne | neutron | network |
| ffb56fd8b24a4a27bf6a707a7f78157f | RegionOne | keystone | identity |
| 88da40693bfa43b9b02e1478b1fa0bc6 | Pod1 | nova | compute |
| f35d64c2ddc44c16a4f9dfcd76e23d9f | RegionOne | nova_legacy | compute_legacy |
| 8759b2941fe7469e9651de3f6a123998 | RegionOne | tricircle | Cascading |
+----------------------------------+-----------+--------------+----------------+
```
"RegionOne" is the region you set in local.conf via REGION_NAME, whose default
value is "RegionOne", we use it as the region for top OpenStack(Tricircle);
"Pod1" is the region set via "POD_REGION_NAME", new configuration option
introduced by Tricircle, we use it as the bottom OpenStack.
- 6 Create pod instances for Tricircle and bottom OpenStack
```
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionOne"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "Pod1", "az_name": "az1"}}'
```
Pay attention to "pod_name" parameter we specify when creating pod. Pod name
should exactly match the region name registered in Keystone since it is used
by Tricircle to route API request. In the above commands, we create pods named
"RegionOne" and "Pod1" for top OpenStack(Tricircle) and bottom OpenStack.
Tricircle API service will automatically create a aggregate when user creates
a bottom pod, so command "nova aggregate-list" will show the following result:
```
+----+----------+-------------------+
| Id | Name | Availability Zone |
+----+----------+-------------------+
| 1 | ag_Pod1 | az1 |
+----+----------+-------------------+
```
- 7 Create necessary resources to boot a virtual machine.
```
nova flavor-create test 1 1024 10 1
neutron net-create net1
neutron subnet-create net1 10.0.0.0/24
glance image-list
```
Note that flavor mapping has not been implemented yet so the created flavor is
just a database record and actually flavor in bottom OpenStack with the same id
will be used.
- 8 Boot a virtual machine.
```
nova boot --flavor 1 --image $image_id --nic net-id=$net_id --availability-zone az1 vm1
```
- 9 Create, list, show and delete volume.
```
cinder --debug create --availability-zone=az1 1
cinder --debug list
cinder --debug show $volume_id
cinder --debug delete $volume_id
cinder --debug list
```

+ 8
- 9
cmd/api.py View File

@ -21,14 +21,13 @@ import sys
from oslo_config import cfg
from oslo_log import log as logging
from werkzeug import serving
from oslo_service import wsgi
from tricircle.api import app
from tricircle.common import config
from tricircle.common.i18n import _LI
from tricircle.common.i18n import _LW
from tricircle.common import restapp
CONF = cfg.CONF
@ -36,8 +35,7 @@ LOG = logging.getLogger(__name__)
def main():
config.init(sys.argv[1:])
config.setup_logging()
config.init(app.common_opts, sys.argv[1:])
application = app.setup_app()
host = CONF.bind_host
@ -48,16 +46,17 @@ def main():
LOG.warning(_LW("Wrong worker number, worker = %(workers)s"), workers)
workers = 1
LOG.info(_LI("Server on http://%(host)s:%(port)s with %(workers)s"),
LOG.info(_LI("Admin API on http://%(host)s:%(port)s with %(workers)s"),
{'host': host, 'port': port, 'workers': workers})
serving.run_simple(host, port,
application,
processes=workers)
service = wsgi.Server(CONF, 'Tricircle Admin_API', application, host, port)
restapp.serve(service, CONF, workers)
LOG.info(_LI("Configuration:"))
CONF.log_opt_values(LOG, std_logging.INFO)
restapp.wait()
if __name__ == '__main__':
main()

+ 63
- 0
cmd/cinder_apigw.py View File

@ -0,0 +1,63 @@
# Copyright 2015 Huawei Technologies Co., Ltd.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Much of this module is based on the work of the Ironic team
# see http://git.openstack.org/cgit/openstack/ironic/tree/ironic/cmd/api.py
import logging as std_logging
import sys
from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import wsgi
from tricircle.common import config
from tricircle.common.i18n import _LI
from tricircle.common.i18n import _LW
from tricircle.common import restapp
from tricircle.cinder_apigw import app
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def main():
config.init(app.common_opts, sys.argv[1:])
application = app.setup_app()
host = CONF.bind_host
port = CONF.bind_port
workers = CONF.api_workers
if workers < 1:
LOG.warning(_LW("Wrong worker number, worker = %(workers)s"), workers)
workers = 1
LOG.info(_LI("Cinder_APIGW on http://%(host)s:%(port)s with %(workers)s"),
{'host': host, 'port': port, 'workers': workers})
service = wsgi.Server(CONF, 'Tricircle Cinder_APIGW',
application, host, port)
restapp.serve(service, CONF, workers)
LOG.info(_LI("Configuration:"))
CONF.log_opt_values(LOG, std_logging.INFO)
restapp.wait()
if __name__ == '__main__':
main()

+ 0
- 85
cmd/dispatcher.py View File

@ -1,85 +0,0 @@
# Copyright 2015 Huawei Technologies Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import eventlet
if __name__ == "__main__":
eventlet.monkey_patch()
import sys
import traceback
from oslo_config import cfg
from oslo_log import log as logging
from tricircle.common.i18n import _LE
from tricircle.common.nova_lib import conductor_rpcapi
from tricircle.common.nova_lib import db_api as nova_db_api
from tricircle.common.nova_lib import exception as nova_exception
from tricircle.common.nova_lib import objects as nova_objects
from tricircle.common.nova_lib import objects_base
from tricircle.common.nova_lib import quota
from tricircle.common.nova_lib import rpc as nova_rpc
from tricircle.dispatcher import service
def block_db_access():
class NoDB(object):
def __getattr__(self, attr):
return self
def __call__(self, *args, **kwargs):
stacktrace = "".join(traceback.format_stack())
LOG = logging.getLogger('nova.compute')
LOG.error(_LE('No db access allowed in nova-compute: %s'),
stacktrace)
raise nova_exception.DBNotAllowed('nova-compute')
nova_db_api.IMPL = NoDB()
def set_up_nova_object_indirection():
conductor = conductor_rpcapi.ConductorAPI()
conductor.client.target.exchange = "nova"
objects_base.NovaObject.indirection_api = conductor
def process_command_line_arguments():
logging.register_options(cfg.CONF)
logging.set_defaults()
cfg.CONF(sys.argv[1:])
logging.setup(cfg.CONF, "dispatcher", version='0.1')
def _set_up_nova_objects():
nova_rpc.init(cfg.CONF)
block_db_access()
set_up_nova_object_indirection()
nova_objects.register_all()
def _disable_quotas():
QUOTAS = quota.QUOTAS
QUOTAS._driver_cls = quota.NoopQuotaDriver()
if __name__ == "__main__":
_set_up_nova_objects()
_disable_quotas()
process_command_line_arguments()
server = service.setup_server()
server.start()
server.wait()

+ 2
- 2
cmd/manage.py View File

@ -19,7 +19,7 @@ import sys
from oslo_config import cfg
from tricircle.db import core
import tricircle.db.migration_helpers as migration_helpers
from tricircle.db import migration_helpers
def main(argv=None, config_files=None):
@ -28,7 +28,7 @@ def main(argv=None, config_files=None):
project='tricircle',
default_config_files=config_files)
migration_helpers.find_migrate_repo()
migration_helpers.sync_repo(1)
migration_helpers.sync_repo(2)
if __name__ == '__main__':


+ 68
- 0
cmd/nova_apigw.py View File

@ -0,0 +1,68 @@
# Copyright 2015 Huawei Technologies Co., Ltd.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Much of this module is based on the work of the Ironic team
# see http://git.openstack.org/cgit/openstack/ironic/tree/ironic/cmd/api.py
import eventlet
if __name__ == "__main__":
eventlet.monkey_patch()
import logging as std_logging
import sys
from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import wsgi
from tricircle.common import config
from tricircle.common.i18n import _LI
from tricircle.common.i18n import _LW
from tricircle.common import restapp
from tricircle.nova_apigw import app
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def main():
config.init(app.common_opts, sys.argv[1:])
application = app.setup_app()
host = CONF.bind_host
port = CONF.bind_port
workers = CONF.api_workers
if workers < 1:
LOG.warning(_LW("Wrong worker number, worker = %(workers)s"), workers)
workers = 1
LOG.info(_LI("Nova_APIGW on http://%(host)s:%(port)s with %(workers)s"),
{'host': host, 'port': port, 'workers': workers})
service = wsgi.Server(CONF, 'Tricircle Nova_APIGW',
application, host, port)
restapp.serve(service, CONF, workers)
LOG.info(_LI("Configuration:"))
CONF.log_opt_values(LOG, std_logging.INFO)
restapp.wait()
if __name__ == '__main__':
main()

+ 0
- 85
cmd/proxy.py View File

@ -1,85 +0,0 @@
# Copyright 2015 Huawei Technologies Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import eventlet
if __name__ == "__main__":
eventlet.monkey_patch()
import sys
import traceback
from oslo_config import cfg
from oslo_log import log as logging
from tricircle.common.i18n import _LE
from tricircle.common.nova_lib import conductor_rpcapi
from tricircle.common.nova_lib import db_api as nova_db_api
from tricircle.common.nova_lib import exception as nova_exception
from tricircle.common.nova_lib import objects as nova_objects
from tricircle.common.nova_lib import objects_base
from tricircle.common.nova_lib import quota
from tricircle.common.nova_lib import rpc as nova_rpc
from tricircle.proxy import service
def block_db_access():
class NoDB(object):
def __getattr__(self, attr):
return self
def __call__(self, *args, **kwargs):
stacktrace = "".join(traceback.format_stack())
LOG = logging.getLogger('nova.compute')
LOG.error(_LE('No db access allowed in nova-compute: %s'),
stacktrace)
raise nova_exception.DBNotAllowed('nova-compute')
nova_db_api.IMPL = NoDB()
def set_up_nova_object_indirection():
conductor = conductor_rpcapi.ConductorAPI()
conductor.client.target.exchange = "nova"
objects_base.NovaObject.indirection_api = conductor
def process_command_line_arguments():
logging.register_options(cfg.CONF)
logging.set_defaults()
cfg.CONF(sys.argv[1:])
logging.setup(cfg.CONF, "proxy", version='0.1')
def _set_up_nova_objects():
nova_rpc.init(cfg.CONF)
block_db_access()
set_up_nova_object_indirection()
nova_objects.register_all()
def _disable_quotas():
QUOTAS = quota.QUOTAS
QUOTAS._driver_cls = quota.NoopQuotaDriver()
if __name__ == "__main__":
_set_up_nova_objects()
_disable_quotas()
process_command_line_arguments()
server = service.setup_server()
server.start()
server.wait()

+ 61
- 0
cmd/xjob.py View File

@ -0,0 +1,61 @@
# Copyright 2015 Huawei Technologies Co., Ltd.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Much of this module is based on the work of the Ironic team
# see http://git.openstack.org/cgit/openstack/ironic/tree/ironic/cmd/api.py
import eventlet
if __name__ == "__main__":
eventlet.monkey_patch()
import logging as std_logging
import sys
from oslo_config import cfg
from oslo_log import log as logging
from tricircle.common import config
from tricircle.common.i18n import _LI
from tricircle.common.i18n import _LW
from tricircle.xjob import xservice
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def main():
config.init(xservice.common_opts, sys.argv[1:])
host = CONF.host
workers = CONF.workers
if workers < 1:
LOG.warning(_LW("Wrong worker number, worker = %(workers)s"), workers)
workers = 1
LOG.info(_LI("XJob Server on http://%(host)s with %(workers)s"),
{'host': host, 'workers': workers})
xservice.serve(xservice.create_service(), workers)
LOG.info(_LI("Configuration:"))
CONF.log_opt_values(LOG, std_logging.INFO)
xservice.wait()
if __name__ == '__main__':
main()

+ 18
- 11
devstack/local.conf.sample View File

@ -27,25 +27,32 @@ Q_FLOATING_ALLOCATION_POOL=start=10.100.100.160,end=10.100.100.192
PUBLIC_NETWORK_GATEWAY=10.100.100.3
TENANT_VLAN_RANGE=2001:3000
PHYSICAL_NETWORK=bridge
Q_ENABLE_TRICIRCLE=True
enable_plugin tricircle https://git.openstack.org/openstack/tricircle master
enable_plugin tricircle https://github.com/openstack/tricircle/
# Tricircle Services
enable_service t-api
enable_service t-prx
enable_service t-dis
enable_service t-ngw
enable_service t-cgw
enable_service t-job
# Use Neutron instead of nova-network
disable_service n-net
disable_service n-cpu
disable_service n-sch
enable_service q-svc
disable_service q-dhcp
enable_service q-svc1
enable_service q-dhcp
enable_service q-agt
disable_service n-obj
disable_service n-cauth
disable_service n-novnc
disable_service q-l3
disable_service q-agt
disable_service c-api
disable_service c-vol
enable_service c-api
enable_service c-vol
enable_service c-sch
disable_service c-bak
disable_service c-sch
disable_service cinder
disable_service tempest
disable_service horizon

+ 261
- 74
devstack/plugin.sh View File

@ -3,7 +3,7 @@
# Test if any tricircle services are enabled
# is_tricircle_enabled
function is_tricircle_enabled {
[[ ,${ENABLED_SERVICES} =~ ,"t-" ]] && return 0
[[ ,${ENABLED_SERVICES} =~ ,"t-api" ]] && return 0
return 1
}
@ -18,9 +18,9 @@ function create_tricircle_accounts {
create_service_user "tricircle"
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
local tricircle_dispatcher=$(get_or_create_service "tricircle" \
local tricircle_api=$(get_or_create_service "tricircle" \
"Cascading" "OpenStack Cascading Service")
get_or_create_endpoint $tricircle_dispatcher \
get_or_create_endpoint $tricircle_api \
"$REGION_NAME" \
"$SERVICE_PROTOCOL://$TRICIRCLE_API_HOST:$TRICIRCLE_API_PORT/v1.0" \
"$SERVICE_PROTOCOL://$TRICIRCLE_API_HOST:$TRICIRCLE_API_PORT/v1.0" \
@ -29,6 +29,79 @@ function create_tricircle_accounts {
fi
}
# create_nova_apigw_accounts() - Set up common required nova_apigw
# work as nova api serice
# service accounts in keystone
# Project User Roles
# -----------------------------------------------------------------
# $SERVICE_TENANT_NAME nova_apigw service
function create_nova_apigw_accounts {
if [[ "$ENABLED_SERVICES" =~ "t-ngw" ]]; then
create_service_user "nova_apigw"
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
local tricircle_nova_apigw=$(get_or_create_service "nova" \
"compute" "Nova Compute Service")
remove_old_endpoint_conf $tricircle_nova_apigw
get_or_create_endpoint $tricircle_nova_apigw \
"$REGION_NAME" \
"$SERVICE_PROTOCOL://$TRICIRCLE_NOVA_APIGW_HOST:$TRICIRCLE_NOVA_APIGW_PORT/v2.1/"'$(tenant_id)s' \
"$SERVICE_PROTOCOL://$TRICIRCLE_NOVA_APIGW_HOST:$TRICIRCLE_NOVA_APIGW_PORT/v2.1/"'$(tenant_id)s' \
"$SERVICE_PROTOCOL://$TRICIRCLE_NOVA_APIGW_HOST:$TRICIRCLE_NOVA_APIGW_PORT/v2.1/"'$(tenant_id)s'
fi
fi
}
# create_cinder_apigw_accounts() - Set up common required cinder_apigw
# work as cinder api serice
# service accounts in keystone
# Project User Roles
# ---------------------------------------------------------------------
# $SERVICE_TENANT_NAME cinder_apigw service
function create_cinder_apigw_accounts {
if [[ "$ENABLED_SERVICES" =~ "t-cgw" ]]; then
create_service_user "cinder_apigw"
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
local tricircle_cinder_apigw=$(get_or_create_service "cinder" \
"volumev2" "Cinder Volume Service")
remove_old_endpoint_conf $tricircle_cinder_apigw
get_or_create_endpoint $tricircle_cinder_apigw \
"$REGION_NAME" \
"$SERVICE_PROTOCOL://$TRICIRCLE_CINDER_APIGW_HOST:$TRICIRCLE_CINDER_APIGW_PORT/v2/"'$(tenant_id)s' \
"$SERVICE_PROTOCOL://$TRICIRCLE_CINDER_APIGW_HOST:$TRICIRCLE_CINDER_APIGW_PORT/v2/"'$(tenant_id)s' \
"$SERVICE_PROTOCOL://$TRICIRCLE_CINDER_APIGW_HOST:$TRICIRCLE_CINDER_APIGW_PORT/v2/"'$(tenant_id)s'
fi
fi
}
# common config-file configuration for tricircle services
function remove_old_endpoint_conf {
local service=$1
local endpoint_id
interface_list="public admin internal"
for interface in $interface_list; do
endpoint_id=$(openstack endpoint list \
--service "$service" \
--interface "$interface" \
--region "$REGION_NAME" \
-c ID -f value)
if [[ -n "$endpoint_id" ]]; then
# Delete endpoint
openstack endpoint delete "$endpoint_id"
fi
done
}
# create_tricircle_cache_dir() - Set up cache dir for tricircle
function create_tricircle_cache_dir {
@ -36,68 +109,33 @@ function create_tricircle_cache_dir {
sudo rm -rf $TRICIRCLE_AUTH_CACHE_DIR
sudo mkdir -p $TRICIRCLE_AUTH_CACHE_DIR
sudo chown `whoami` $TRICIRCLE_AUTH_CACHE_DIR
}
# common config-file configuration for tricircle services
function init_common_tricircle_conf {
local conf_file=$1
function configure_tricircle_dispatcher {
if is_service_enabled q-svc ; then
echo "Configuring Neutron plugin for Tricircle"
Q_PLUGIN_CLASS="tricircle.networking.plugin.TricirclePlugin"
#NEUTRON_CONF=/etc/neutron/neutron.conf
iniset $NEUTRON_CONF DEFAULT core_plugin "$Q_PLUGIN_CLASS"
iniset $NEUTRON_CONF DEFAULT service_plugins ""
fi
if is_service_enabled t-dis ; then
echo "Configuring Tricircle Dispatcher"
sudo install -d -o $STACK_USER -m 755 $TRICIRCLE_CONF_DIR
cp -p $TRICIRCLE_DIR/etc/dispatcher.conf $TRICIRCLE_DISPATCHER_CONF
TRICIRCLE_POLICY_FILE=$TRICIRCLE_CONF_DIR/policy.json
cp $TRICIRCLE_DIR/etc/policy.json $TRICIRCLE_POLICY_FILE
iniset $TRICIRCLE_DISPATCHER_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $TRICIRCLE_DISPATCHER_CONF DEFAULT verbose True
setup_colorized_logging $TRICIRCLE_DISPATCHER_CONF DEFAULT tenant
iniset $TRICIRCLE_DISPATCHER_CONF DEFAULT bind_host $TRICIRCLE_DISPATCHER_LISTEN_ADDRESS
iniset $TRICIRCLE_DISPATCHER_CONF DEFAULT use_syslog $SYSLOG
iniset_rpc_backend tricircle $TRICIRCLE_DISPATCHER_CONF
iniset $TRICIRCLE_DISPATCHER_CONF database connection `database_connection_url tricircle`
iniset $TRICIRCLE_DISPATCHER_CONF client admin_username admin
iniset $TRICIRCLE_DISPATCHER_CONF client admin_password $ADMIN_PASSWORD
iniset $TRICIRCLE_DISPATCHER_CONF client admin_tenant demo
iniset $TRICIRCLE_DISPATCHER_CONF client auto_refresh_endpoint True
iniset $TRICIRCLE_DISPATCHER_CONF client top_site_name $OS_REGION_NAME
fi
}
touch $conf_file
iniset $conf_file DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $conf_file DEFAULT verbose True
iniset $conf_file DEFAULT use_syslog $SYSLOG
iniset $conf_file DEFAULT tricircle_db_connection `database_connection_url tricircle`
function configure_tricircle_proxy {
if is_service_enabled t-prx ; then
echo "Configuring Tricircle Proxy"
iniset $conf_file client admin_username admin
iniset $conf_file client admin_password $ADMIN_PASSWORD
iniset $conf_file client admin_tenant demo
iniset $conf_file client auto_refresh_endpoint True
iniset $conf_file client top_pod_name $REGION_NAME
cp -p $NOVA_CONF $TRICIRCLE_CONF_DIR
mv $TRICIRCLE_CONF_DIR/nova.conf $TRICIRCLE_PROXY_CONF
fi
iniset $conf_file oslo_concurrency lock_path $TRICIRCLE_STATE_PATH/lock
}
function configure_tricircle_api {
if is_service_enabled t-api ; then
echo "Configuring Tricircle API"
cp -p $TRICIRCLE_DIR/etc/api.conf $TRICIRCLE_API_CONF
iniset $TRICIRCLE_API_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $TRICIRCLE_API_CONF DEFAULT verbose True
iniset $TRICIRCLE_API_CONF DEFAULT use_syslog $SYSLOG
iniset $TRICIRCLE_API_CONF database connection `database_connection_url tricircle`
iniset $TRICIRCLE_API_CONF client admin_username admin
iniset $TRICIRCLE_API_CONF client admin_password $ADMIN_PASSWORD
iniset $TRICIRCLE_API_CONF client admin_tenant demo
iniset $TRICIRCLE_API_CONF client auto_refresh_endpoint True
iniset $TRICIRCLE_API_CONF client top_site_name $OS_REGION_NAME
init_common_tricircle_conf $TRICIRCLE_API_CONF
setup_colorized_logging $TRICIRCLE_API_CONF DEFAULT tenant_name
@ -116,59 +154,208 @@ function configure_tricircle_api {
fi
}
function configure_tricircle_nova_apigw {
if is_service_enabled t-ngw ; then
echo "Configuring Tricircle Nova APIGW"
init_common_tricircle_conf $TRICIRCLE_NOVA_APIGW_CONF
iniset $NEUTRON_CONF client admin_username admin
iniset $NEUTRON_CONF client admin_password $ADMIN_PASSWORD
iniset $NEUTRON_CONF client admin_tenant demo
iniset $NEUTRON_CONF client auto_refresh_endpoint True
iniset $NEUTRON_CONF client top_pod_name $REGION_NAME
setup_colorized_logging $TRICIRCLE_NOVA_APIGW_CONF DEFAULT tenant_name
if is_service_enabled keystone; then
create_tricircle_cache_dir
# Configure auth token middleware
configure_auth_token_middleware $TRICIRCLE_NOVA_APIGW_CONF tricircle \
$TRICIRCLE_AUTH_CACHE_DIR
else
iniset $TRICIRCLE_NOVA_APIGW_CONF DEFAULT auth_strategy noauth
fi
fi
}
function configure_tricircle_cinder_apigw {
if is_service_enabled t-cgw ; then
echo "Configuring Tricircle Cinder APIGW"
init_common_tricircle_conf $TRICIRCLE_CINDER_APIGW_CONF
setup_colorized_logging $TRICIRCLE_CINDER_APIGW_CONF DEFAULT tenant_name
if is_service_enabled keystone; then
create_tricircle_cache_dir
# Configure auth token middleware
configure_auth_token_middleware $TRICIRCLE_CINDER_APIGW_CONF tricircle \
$TRICIRCLE_AUTH_CACHE_DIR
else
iniset $TRICIRCLE_CINDER_APIGW_CONF DEFAULT auth_strategy noauth
fi
fi
}
function configure_tricircle_xjob {
if is_service_enabled t-job ; then
echo "Configuring Tricircle xjob"
init_common_tricircle_conf $TRICIRCLE_XJOB_CONF
setup_colorized_logging $TRICIRCLE_XJOB_CONF DEFAULT
fi
}
function start_new_neutron_server {
local server_index=$1
local region_name=$2
local q_port=$3
get_or_create_service "neutron" "network" "Neutron Service"
get_or_create_endpoint "network" \
"$region_name" \
"$Q_PROTOCOL://$SERVICE_HOST:$q_port/" \
"$Q_PROTOCOL://$SERVICE_HOST:$q_port/" \
"$Q_PROTOCOL://$SERVICE_HOST:$q_port/"
cp $NEUTRON_CONF $NEUTRON_CONF.$server_index
iniset $NEUTRON_CONF.$server_index database connection `database_connection_url $Q_DB_NAME$server_index`
iniset $NEUTRON_CONF.$server_index nova region_name $region_name
iniset $NEUTRON_CONF.$server_index DEFAULT bind_port $q_port
recreate_database $Q_DB_NAME$server_index
$NEUTRON_BIN_DIR/neutron-db-manage --config-file $NEUTRON_CONF.$server_index --config-file /$Q_PLUGIN_CONF_FILE upgrade head
run_process q-svc$server_index "$NEUTRON_BIN_DIR/neutron-server --config-file $NEUTRON_CONF.$server_index --config-file /$Q_PLUGIN_CONF_FILE"
}
if [[ "$Q_ENABLE_TRICIRCLE" == "True" ]]; then
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
echo summary "Tricircle pre-install"
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
echo_summary "Installing Tricircle"
git_clone $TRICIRCLE_REPO $TRICIRCLE_DIR $TRICIRCLE_BRANCH
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
echo_summary "Configuring Tricircle"
configure_tricircle_dispatcher
configure_tricircle_proxy
sudo install -d -o $STACK_USER -m 755 $TRICIRCLE_CONF_DIR
configure_tricircle_api
configure_tricircle_nova_apigw
configure_tricircle_cinder_apigw
configure_tricircle_xjob
echo export PYTHONPATH=\$PYTHONPATH:$TRICIRCLE_DIR >> $RC_DIR/.localrc.auto
recreate_database tricircle
python "$TRICIRCLE_DIR/cmd/manage.py" "$TRICIRCLE_DISPATCHER_CONF"
python "$TRICIRCLE_DIR/cmd/manage.py" "$TRICIRCLE_API_CONF"
if is_service_enabled q-svc ; then
start_new_neutron_server 1 $POD_REGION_NAME $TRICIRCLE_NEUTRON_PORT
# reconfigure neutron server to use our own plugin
echo "Configuring Neutron plugin for Tricircle"
Q_PLUGIN_CLASS="tricircle.network.plugin.TricirclePlugin"
iniset $NEUTRON_CONF DEFAULT core_plugin "$Q_PLUGIN_CLASS"
iniset $NEUTRON_CONF DEFAULT service_plugins ""
iniset $NEUTRON_CONF DEFAULT tricircle_db_connection `database_connection_url tricircle`
iniset $NEUTRON_CONF client admin_username admin
iniset $NEUTRON_CONF client admin_password $ADMIN_PASSWORD
iniset $NEUTRON_CONF client admin_tenant demo
iniset $NEUTRON_CONF client auto_refresh_endpoint True
iniset $NEUTRON_CONF client top_pod_name $REGION_NAME
iniset $NEUTRON_CONF tricircle bridge_segmentation_id `echo $TENANT_VLAN_RANGE | awk -F: '{print $2}'`
iniset $NEUTRON_CONF tricircle bridge_physical_network $PHYSICAL_NETWORK
fi
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
echo_summary "Initializing Tricircle Service"
if is_service_enabled t-dis; then
run_process t-dis "python $TRICIRCLE_DISPATCHER --config-file $TRICIRCLE_DISPATCHER_CONF"
if is_service_enabled t-api; then
create_tricircle_accounts
run_process t-api "python $TRICIRCLE_API --config-file $TRICIRCLE_API_CONF"
fi
if is_service_enabled t-prx; then
run_process t-prx "python $TRICIRCLE_PROXY --config-file $TRICIRCLE_PROXY_CONF"
if is_service_enabled t-ngw; then
create_nova_apigw_accounts
run_process t-ngw "python $TRICIRCLE_NOVA_APIGW --config-file $TRICIRCLE_NOVA_APIGW_CONF"
# Nova services are running, but we need to re-configure them to
# move them to bottom region
iniset $NOVA_CONF neutron region_name $POD_REGION_NAME
iniset $NOVA_CONF neutron url "$Q_PROTOCOL://$SERVICE_HOST:$TRICIRCLE_NEUTRON_PORT"
get_or_create_endpoint "compute" \
"$POD_REGION_NAME" \
"$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2.1/"'$(tenant_id)s' \
"$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2.1/"'$(tenant_id)s' \
"$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2.1/"'$(tenant_id)s'
stop_process n-api
stop_process n-cpu
# remove previous failure flag file since we are going to restart service
rm -f "$SERVICE_DIR/$SCREEN_NAME"/n-api.failure
rm -f "$SERVICE_DIR/$SCREEN_NAME"/n-cpu.failure
sleep 20
run_process n-api "$NOVA_BIN_DIR/nova-api"
run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CONF" $LIBVIRT_GROUP
fi
if is_service_enabled t-api; then
if is_service_enabled t-cgw; then
create_tricircle_accounts
create_cinder_apigw_accounts
run_process t-api "python $TRICIRCLE_API --config-file $TRICIRCLE_API_CONF"
run_process t-cgw "python $TRICIRCLE_CINDER_APIGW --config-file $TRICIRCLE_CINDER_APIGW_CONF"
get_or_create_endpoint "volumev2" \
"$POD_REGION_NAME" \
"$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/"'$(tenant_id)s' \
"$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/"'$(tenant_id)s' \
"$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/"'$(tenant_id)s'
fi
if is_service_enabled t-job; then
run_process t-job "python $TRICIRCLE_XJOB --config-file $TRICIRCLE_XJOB_CONF"
fi
fi
if [[ "$1" == "unstack" ]]; then
if is_service_enabled t-dis; then
stop_process t-dis
if is_service_enabled t-api; then
stop_process t-api
fi
if is_service_enabled t-ngw; then
stop_process t-ngw
fi
if is_service_enabled t-prx; then
stop_process t-prx
if is_service_enabled t-cgw; then
stop_process t-cgw
fi
if is_service_enabled t-api; then
stop_process t-api
if is_service_enabled t-job; then
stop_process t-job
fi
if is_service_enabled q-svc1; then
stop_process q-svc1
fi
fi
fi

+ 26
- 10
devstack/settings View File

@ -4,18 +4,12 @@ TRICIRCLE_DIR=$DEST/tricircle
TRICIRCLE_BRANCH=${TRICIRCLE_BRANCH:-master}
# common variables
POD_REGION_NAME=${POD_REGION_NAME:-Pod1}
TRICIRCLE_NEUTRON_PORT=${TRICIRCLE_NEUTRON_PORT:-20001}
TRICIRCLE_CONF_DIR=${TRICIRCLE_CONF_DIR:-/etc/tricircle}
TRICIRCLE_STATE_PATH=${TRICIRCLE_STATE_PATH:-/var/lib/tricircle}
# tricircle dispatcher
TRICIRCLE_DISPATCHER=$TRICIRCLE_DIR/cmd/dispatcher.py
TRICIRCLE_DISPATCHER_CONF=$TRICIRCLE_CONF_DIR/dispatcher.conf
TRICIRCLE_DISPATCHER_LISTEN_ADDRESS=${TRICIRCLE_DISPATCHER_LISTEN_ADDRESS:-0.0.0.0}
# tricircle proxy
TRICIRCLE_PROXY=$TRICIRCLE_DIR/cmd/proxy.py
TRICIRCLE_PROXY_CONF=$TRICIRCLE_CONF_DIR/proxy.conf
# tricircle rest api
# tricircle rest admin api
TRICIRCLE_API=$TRICIRCLE_DIR/cmd/api.py
TRICIRCLE_API_CONF=$TRICIRCLE_CONF_DIR/api.conf
@ -24,6 +18,28 @@ TRICIRCLE_API_HOST=${TRICIRCLE_API_HOST:-$SERVICE_HOST}
TRICIRCLE_API_PORT=${TRICIRCLE_API_PORT:-19999}
TRICIRCLE_API_PROTOCOL=${TRICIRCLE_API_PROTOCOL:-$SERVICE_PROTOCOL}
# tricircle nova_apigw
TRICIRCLE_NOVA_APIGW=$TRICIRCLE_DIR/cmd/nova_apigw.py
TRICIRCLE_NOVA_APIGW_CONF=$TRICIRCLE_CONF_DIR/nova_apigw.conf
TRICIRCLE_NOVA_APIGW_LISTEN_ADDRESS=${TRICIRCLE_NOVA_APIGW_LISTEN_ADDRESS:-0.0.0.0}
TRICIRCLE_NOVA_APIGW_HOST=${TRICIRCLE_NOVA_APIGW_HOST:-$SERVICE_HOST}
TRICIRCLE_NOVA_APIGW_PORT=${TRICIRCLE_NOVA_APIGW_PORT:-19998}
TRICIRCLE_NOVA_APIGW_PROTOCOL=${TRICIRCLE_NOVA_APIGW_PROTOCOL:-$SERVICE_PROTOCOL}
# tricircle cinder_apigw
TRICIRCLE_CINDER_APIGW=$TRICIRCLE_DIR/cmd/cinder_apigw.py
TRICIRCLE_CINDER_APIGW_CONF=$TRICIRCLE_CONF_DIR/cinder_apigw.conf
TRICIRCLE_CINDER_APIGW_LISTEN_ADDRESS=${TRICIRCLE_CINDER_APIGW_LISTEN_ADDRESS:-0.0.0.0}
TRICIRCLE_CINDER_APIGW_HOST=${TRICIRCLE_CINDER_APIGW_HOST:-$SERVICE_HOST}
TRICIRCLE_CINDER_APIGW_PORT=${TRICIRCLE_CINDER_APIGW_PORT:-19997}
TRICIRCLE_CINDER_APIGW_PROTOCOL=${TRICIRCLE_CINDER_APIGW_PROTOCOL:-$SERVICE_PROTOCOL}
# tricircle xjob
TRICIRCLE_XJOB=$TRICIRCLE_DIR/cmd/xjob.py
TRICIRCLE_XJOB_CONF=$TRICIRCLE_CONF_DIR/xjob.conf
TRICIRCLE_AUTH_CACHE_DIR=${TRICIRCLE_AUTH_CACHE_DIR:-/var/cache/tricircle}
export PYTHONPATH=$PYTHONPATH:$TRICIRCLE_DIR

+ 90
- 50
doc/source/api_v1.rst View File

@ -1,7 +1,7 @@
================
Tricircle API v1
================
This API describes the ways of interacting with Tricircle(Cascade) service via
This API describes the ways of interacting with Tricircle service via
HTTP protocol using Representational State Transfer(ReST).
Application Root [/]
@ -13,106 +13,146 @@ API v1 Root [/v1/]
==================
All API v1 URLs are relative to API v1 root.
Site [/sites/{site_id}]
Pod [/pods/{pod_id}]
=======================
A site represents a region in Keystone. When operating a site, Tricircle
decides the correct endpoints to send request based on the region of the site.
A pod represents a region in Keystone. When operating a pod, Tricircle
decides the correct endpoints to send request based on the region of the pod.
Considering the 2-layers architecture of Tricircle, we also have 2 kinds of
sites: top site and bottom site. A site has the following attributes:
pods: top pod and bottom pod. A pod has the following attributes:
- site_id
- site_name
- az_id
- pod_id
- pod_name
- pod_az_name
- dc_name
- az_name
**site_id** is automatically generated when creating a site. **site_name** is
specified by user but **MUST** match the region name registered in Keystone.
When creating a bottom site, Tricircle automatically creates a host aggregate
and assigns the new availability zone id to **az_id**. Top site doesn't need a
host aggregate so **az_id** is left empty.
**pod_id** is automatically generated when creating a site.
**pod_name** is specified by user but **MUST** match the region name
registered in Keystone. When creating a bottom pod, Tricircle automatically
creates a host aggregate and assigns the new availability zone id to
**az_name**. When **az_name** is empty, that means this pod is top region,
no host aggregate will be generated. If **az_name** is not empty, that means
this pod will belong to this availability zone. Multiple pods with same
**az_name** means that these pods are under same availability zone.
**pod_az_name** is the az name in the bottom pod, it could be empty, if empty,
then no az parameter will be added to the request to the bottom pod. If the
**pod_az_name** is different than **az_name**, then the az parameter will be
replaced to the **pod_az_name** when the request is forwarded to regarding
bottom pod.
**dc_name** is the name of the data center where the pod is located.
URL Parameters
--------------
- site_id: Site id
- pod_id: Pod id
Models
------
::
{
"site_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"site_name": "Site1",
"az_id": "az_Site1"
"pod_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"pod_name": "pod1",
"pod_az_name": "az1",
"dc_name": "data center 1",
"az_name": "az1"
}
Retrieve Site List [GET]
Retrieve Pod List [GET]
------------------------
- URL: /sites
- URL: /pods
- Status: 200
- Returns: List of Sites
- Returns: List of Pods
Response
::
{
"sites": [
"pods": [
{
"site_id": "f91ca3a5-d5c6-45d6-be4c-763f5a2c4aa3",
"site_name": "RegionOne",
"az_id": ""
"pod_id": "f91ca3a5-d5c6-45d6-be4c-763f5a2c4aa3",
"pod_name": "RegionOne",
},
{
"site_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"site_name": "Site1",
"az_id": "az_Site1"
"pod_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"pod_name": "pod1",
"pod_az_name": "az1",
"dc_name": "data center 1",
"az_name": "az1"
}
]
}
Retrieve a Single Site [GET]
Retrieve a Single Pod [GET]
----------------------------
- URL: /sites/site_id
- URL: /pods/pod_id
- Status: 200
- Returns: Site
- Returns: Pod
Response
::
{
"site": {
"site_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"site_name": "Site1",
"az_id": "az_Site1"
"pod": {
"pod_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"pod_name": "pod1",
"pod_az_name": "az1",
"dc_name": "data center 1",
"az_name": "az1"
}
}
Create a Site [POST]
Create a Pod [POST]
--------------------
- URL: /sites
- URL: /pods
- Status: 201
- Returns: Created Site
- Returns: Created Pod
Request (application/json)
.. csv-table::
:header: "Parameter", "Type", "Description"
name, string, name of the Site
top, bool, "indicate whether it's a top Site, optional, default false"
::
# for the pod represent the region where the Tricircle is running
{
"name": "RegionOne"
"top": true
"pod": {
"pod_name": "RegionOne",
}
}
# for the bottom pod which is managed by Tricircle
{
"pod": {
"pod_name": "pod1",
"pod_az_name": "az1",
"dc_name": "data center 1",
"az_name": "az1"
}
}
Response
::
# for the pod represent the region where the Tricircle is running
{
"pod": {
"pod_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"pod_name": "RegionOne",
"pod_az_name": "",
"dc_name": "",
"az_name": ""
}
}
# for the bottom pod which is managed by Tricircle
{
"site": {
"site_id": "f91ca3a5-d5c6-45d6-be4c-763f5a2c4aa3",
"site_name": "RegionOne",
"az_id": ""
"pod": {
"pod_id": "302e02a6-523c-4a92-a8d1-4939b31a788c",
"pod_name": "pod1",
"pod_az_name": "az1",
"dc_name": "data center 1",
"az_name": "az1"
}
}

+ 16
- 0
etc/api-cfg-gen.conf View File

@ -0,0 +1,16 @@
[DEFAULT]
output_file = etc/api.conf.sample
wrap_width = 79
namespace = tricircle.api
namespace = tricircle.common
namespace = tricircle.db
namespace = oslo.log
namespace = oslo.messaging
namespace = oslo.policy
namespace = oslo.service.periodic_task
namespace = oslo.service.service
namespace = oslo.service.sslutils
namespace = oslo.db
namespace = oslo.middleware
namespace = oslo.concurrency
namespace = keystonemiddleware.auth_token

+ 0
- 412
etc/api.conf View File

@ -1,412 +0,0 @@
[DEFAULT]
# Print more verbose output (set logging level to INFO instead of default WARNING level).
# verbose = True
# Print debugging output (set logging level to DEBUG instead of default WARNING level).
# debug = False
# Where to store Tricircle state files. This directory must be writable by the
# user executing the agent.
# state_path = /var/lib/tricircle
# log_format = %(asctime)s %(levelname)8s [%(name)s] %(message)s
# log_date_format = %Y-%m-%d %H:%M:%S
# use_syslog -> syslog
# log_file and log_dir -> log_dir/log_file
# (not log_file) and log_dir -> log_dir/{binary_name}.log
# use_stderr -> stderr
# (not user_stderr) and (not log_file) -> stdout
# publish_errors -> notification system
# use_syslog = False
# syslog_log_facility = LOG_USER
# use_stderr = True
# log_file =
# log_dir =
# publish_errors = False
# Address to bind the API server to
# bind_host = 127.0.0.1
# Port the bind the API server to
# bind_port = 19999
# Paste configuration file
# api_paste_config = api-paste.ini
# (StrOpt) Hostname to be used by the tricircle server, agents and services
# running on this machine. All the agents and services running on this machine
# must use the same host value.
# The default value is hostname of the machine.
#
# host =
# admin_tenant_name = %SERVICE_TENANT_NAME%
# admin_user = %SERVICE_USER%
# admin_password = %SERVICE_PASSWORD%
# Enable or disable bulk create/update/delete operations
# allow_bulk = True
# Enable or disable pagination
# allow_pagination = False
# Enable or disable sorting
# allow_sorting = False
# Default maximum number of items returned in a single response,
# value == infinite and value < 0 means no max limit, and value must
# be greater than 0. If the number of items requested is greater than
# pagination_max_limit, server will just return pagination_max_limit
# of number of items.
# pagination_max_limit = -1
# =========== WSGI parameters related to the API server ==============
# Number of separate worker processes to spawn. The default, 0, runs the
# worker thread in the current process. Greater than 0 launches that number of
# child processes as workers. The parent process manages them.
# api_workers = 3
# Number of separate RPC worker processes to spawn. The default, 0, runs the
# worker thread in the current process. Greater than 0 launches that number of
# child processes as RPC workers. The parent process manages them.
# This feature is experimental until issues are addressed and testing has been
# enabled for various plugins for compatibility.
# rpc_workers = 0
# Timeout for client connections socket operations. If an
# incoming connection is idle for this number of seconds it
# will be closed. A value of '0' means wait forever. (integer
# value)
# client_socket_timeout = 900
# wsgi keepalive option. Determines if connections are allowed to be held open
# by clients after a request is fulfilled. A value of False will ensure that
# the socket connection will be explicitly closed once a response has been
# sent to the client.
# wsgi_keep_alive = True
# Sets the value of TCP_KEEPIDLE in seconds to use for each server socket when
# starting API server. Not supported on OS X.
# tcp_keepidle = 600
# Number of seconds to keep retrying to listen
# retry_until_window = 30
# Number of backlog requests to configure the socket with.
# backlog = 4096
# Max header line to accommodate large tokens
# max_header_line = 16384
# Enable SSL on the API server
# use_ssl = False
# Certificate file to use when starting API server securely
# ssl_cert_file = /path/to/certfile
# Private key file to use when starting API server securely
# ssl_key_file = /path/to/keyfile
# CA certificate file to use when starting API server securely to
# verify connecting clients. This is an optional parameter only required if
# API clients need to authenticate to the API server using SSL certificates
# signed by a trusted CA
# ssl_ca_file = /path/to/cafile
# ======== end of WSGI parameters related to the API server ==========
# The strategy to be used for auth.
# Supported values are 'keystone'(default), 'noauth'.
# auth_strategy = keystone
[filter:authtoken]
# paste.filter_factory = keystonemiddleware.auth_token:filter_factory
[keystone_authtoken]
# auth_uri = http://162.3.111.227:35357/v3
# identity_uri = http://162.3.111.227:35357
# admin_tenant_name = service
# admin_user = tricircle
# admin_password = 1234
# auth_version = 3
[database]
# This line MUST be changed to actually run the plugin.
# Example:
# connection = mysql://root:pass@127.0.0.1:3306/neutron
# Replace 127.0.0.1 above with the IP address of the database used by the
# main neutron server. (Leave it as is if the database runs on this host.)
# connection = sqlite://
# NOTE: In deployment the [database] section and its connection attribute may
# be set in the corresponding core plugin '.ini' file. However, it is suggested
# to put the [database] section and its connection attribute in this
# configuration file.
# Database engine for which script will be generated when using offline
# migration
# engine =
# The SQLAlchemy connection string used to connect to the slave database
# slave_connection =
# Database reconnection retry times - in event connectivity is lost
# set to -1 implies an infinite retry count
# max_retries = 10
# Database reconnection interval in seconds - if the initial connection to the
# database fails
# retry_interval = 10
# Minimum number of SQL connections to keep open in a pool
# min_pool_size = 1
# Maximum number of SQL connections to keep open in a pool
# max_pool_size = 10
# Timeout in seconds before idle sql connections are reaped
# idle_timeout = 3600
# If set, use this value for max_overflow with sqlalchemy
# max_overflow = 20
# Verbosity of SQL debugging information. 0=None, 100=Everything
# connection_debug = 0
# Add python stack traces to SQL as comment strings
# connection_trace = False
# If set, use this value for pool_timeout with sqlalchemy
# pool_timeout = 10
[client]
# Keystone authentication URL
# auth_url = http://127.0.0.1:5000/v3
# Keystone service URL
# identity_url = http://127.0.0.1:35357/v3
# If set to True, endpoint will be automatically refreshed if timeout
# accessing endpoint.
# auto_refresh_endpoint = False
# Name of top site which client needs to access
# top_site_name =
# Username of admin account for synchronizing endpoint with Keystone
# admin_username =
# Password of admin account for synchronizing endpoint with Keystone
# admin_password =
# Tenant name of admin account for synchronizing endpoint with Keystone
# admin_tenant =
# User domain name of admin account for synchronizing endpoint with Keystone
# admin_user_domain_name = default
# Tenant domain name of admin account for synchronizing endpoint with Keystone
# admin_tenant_domain_name = default
# Timeout for glance client in seconds
# glance_timeout = 60
# Timeout for neutron client in seconds
# neutron_timeout = 60
# Timeout for nova client in seconds
# nova_timeout = 60
[oslo_concurrency]
# Directory to use for lock files. For security, the specified directory should
# only be writable by the user running the processes that need locking.
# Defaults to environment variable OSLO_LOCK_PATH. If external locks are used,
# a lock path must be set.
lock_path = $state_path/lock
# Enables or disables inter-process locks.
# disable_process_locking = False
[oslo_policy]
# The JSON file that defines policies.
# policy_file = policy.json
# Default rule. Enforced when a requested rule is not found.
# policy_default_rule = default
# Directories where policy configuration files are stored.
# They can be relative to any directory in the search path defined by the
# config_dir option, or absolute paths. The file defined by policy_file
# must exist for these directories to be searched. Missing or empty
# directories are ignored.
# policy_dirs = policy.d
[oslo_messaging_amqp]
#
# From oslo.messaging
#
# Address prefix used when sending to a specific server (string value)
# server_request_prefix = exclusive
# Address prefix used when broadcasting to all servers (string value)
# broadcast_prefix = broadcast
# Address prefix when sending to any server in group (string value)
# group_request_prefix = unicast
# Name for the AMQP container (string value)
# container_name =
# Timeout for inactive connections (in seconds) (integer value)
# idle_timeout = 0
# Debug: dump AMQP frames to stdout (boolean value)
# trace = false
# CA certificate PEM file for verifing server certificate (string value)
# ssl_ca_file =
# Identifying certificate PEM file to present to clients (string value)
# ssl_cert_file =
# Private key PEM file used to sign cert_file certificate (string value)
# ssl_key_file =
# Password for decrypting ssl_key_file (if encrypted) (string value)
# ssl_key_password =
# Accept clients using either SSL or plain TCP (boolean value)
# allow_insecure_clients = false
[oslo_messaging_qpid]
#
# From oslo.messaging
#
# Use durable queues in AMQP. (boolean value)
# amqp_durable_queues = false
# Auto-delete queues in AMQP. (boolean value)
# amqp_auto_delete = false
# Size of RPC connection pool. (integer value)
# rpc_conn_pool_size = 30
# Qpid broker hostname. (string value)
# qpid_hostname = localhost
# Qpid broker port. (integer value)
# qpid_port = 5672
# Qpid HA cluster host:port pairs. (list value)
# qpid_hosts = $qpid_hostname:$qpid_port
# Username for Qpid connection. (string value)
# qpid_username =
# Password for Qpid connection. (string value)
# qpid_password =
# Space separated list of SASL mechanisms to use for auth. (string value)
# qpid_sasl_mechanisms =
# Seconds between connection keepalive heartbeats. (integer value)
# qpid_heartbeat = 60
# Transport to use, either 'tcp' or 'ssl'. (string value)
# qpid_protocol = tcp
# Whether to disable the Nagle algorithm. (boolean value)
# qpid_tcp_nodelay = true
# The number of prefetched messages held by receiver. (integer value)
# qpid_receiver_capacity = 1
# The qpid topology version to use. Version 1 is what was originally used by
# impl_qpid. Version 2 includes some backwards-incompatible changes that allow
# broker federation to work. Users should update to version 2 when they are
# able to take everything down, as it requires a clean break. (integer value)
# qpid_topology_version = 1
[oslo_messaging_rabbit]
#
# From oslo.messaging
#
# Use durable queues in AMQP. (boolean value)
# amqp_durable_queues = false
# Auto-delete queues in AMQP. (boolean value)
# amqp_auto_delete = false
# Size of RPC connection pool. (integer value)
# rpc_conn_pool_size = 30
# SSL version to use (valid only if SSL enabled). Valid values are TLSv1 and
# SSLv23. SSLv2, SSLv3, TLSv1_1, and TLSv1_2 may be available on some
# distributions. (string value)
# kombu_ssl_version =
# SSL key file (valid only if SSL enabled). (string value)
# kombu_ssl_keyfile =
# SSL cert file (valid only if SSL enabled). (string value)
# kombu_ssl_certfile =
# SSL certification authority file (valid only if SSL enabled). (string value)
# kombu_ssl_ca_certs =
# How long to wait before reconnecting in response to an AMQP consumer cancel
# notification. (floating point value)
# kombu_reconnect_delay = 1.0
# The RabbitMQ broker address where a single node is used. (string value)
# rabbit_host = localhost
# The RabbitMQ broker port where a single node is used. (integer value)
# rabbit_port = 5672
# RabbitMQ HA cluster host:port pairs. (list value)
# rabbit_hosts = $rabbit_host:$rabbit_port
# Connect over SSL for RabbitMQ. (boolean value)
# rabbit_use_ssl = false
# The RabbitMQ userid. (string value)
# rabbit_userid = guest
# The RabbitMQ password. (string value)
# rabbit_password = guest
# The RabbitMQ login method. (string value)
# rabbit_login_method = AMQPLAIN
# The RabbitMQ virtual host. (string value)
# rabbit_virtual_host = /
# How frequently to retry connecting with RabbitMQ. (integer value)
# rabbit_retry_interval = 1
# How long to backoff for between retries when connecting to RabbitMQ. (integer
# value)
# rabbit_retry_backoff = 2
# Maximum number of RabbitMQ connection retries. Default is 0 (infinite retry
# count). (integer value)
# rabbit_max_retries = 0
# Use HA queues in RabbitMQ (x-ha-policy: all). If you change this option, you
# must wipe the RabbitMQ database. (boolean value)
# rabbit_ha_queues = false
# Deprecated, use rpc_backend=kombu+memory or rpc_backend=fake (boolean value)
# fake_rabbit = false

+ 16
- 0
etc/cinder_apigw-cfg-gen.conf View File

@ -0,0 +1,16 @@
[DEFAULT]
output_file = etc/cinder_apigw.conf.sample
wrap_width = 79
namespace = tricircle.cinder_apigw
namespace = tricircle.common
namespace = tricircle.db
namespace = oslo.log
namespace = oslo.messaging
namespace = oslo.policy
namespace = oslo.service.periodic_task
namespace = oslo.service.service
namespace = oslo.service.sslutils
namespace = oslo.db
namespace = oslo.middleware
namespace = oslo.concurrency
namespace = keystonemiddleware.auth_token

+ 0
- 521
etc/dispatcher.conf View File

@ -1,521 +0,0 @@
[DEFAULT]
# Print more verbose output (set logging level to INFO instead of default WARNING level).
# verbose = True
# Print debugging output (set logging level to DEBUG instead of default WARNING level).
# debug = True
# log_format = %(asctime)s %(levelname)8s [%(name)s] %(message)s
# log_date_format = %Y-%m-%d %H:%M:%S
# use_syslog -> syslog
# log_file and log_dir -> log_dir/log_file
# (not log_file) and log_dir -> log_dir/{binary_name}.log
# use_stderr -> stderr
# (not user_stderr) and (not log_file) -> stdout
# publish_errors -> notification system
# use_syslog = False
# syslog_log_facility = LOG_USER
# use_stderr = True
# log_file =
# log_dir =
# publish_errors = False
# Address to bind the API server to
# bind_host = 0.0.0.0
# Port the bind the API server to
# bind_port = 9696
#
# Options defined in oslo.messaging
#
# Use durable queues in amqp. (boolean value)
# Deprecated group/name - [DEFAULT]/rabbit_durable_queues