First step of getting started doc
This is a first step for the getting started document. Will work on other components in following patches. Change-Id: I2020c758f845c951e7af116ff965692357f1f066
This commit is contained in:
parent
e92e583908
commit
b683aca4ea
176
README.rst
176
README.rst
|
@ -1,124 +1,74 @@
|
|||
senlin
|
||||
Senlin
|
||||
======
|
||||
|
||||
Senlin is a clustering service for OpenStack cloud. It creates and operates
|
||||
clusters of homogenous objects exposed by other OpenStack services. The
|
||||
goal is to make orchestration of collections of similar objects easier.
|
||||
--------
|
||||
Overview
|
||||
--------
|
||||
|
||||
Senlin provides ReSTful APIs to users so that they can associate various
|
||||
Senlin is a clustering service for OpenStack clouds. It creates and operates
|
||||
clusters of homogenous objects exposed by other OpenStack services. The goal
|
||||
is to make the orchestration of collections of similar objects easier.
|
||||
|
||||
Senlin provides RESTful APIs to users so that they can associate various
|
||||
policies to a cluster. Sample policies include placement policy, load
|
||||
balancing policy, failover policy, scaling policy, ... and so on.
|
||||
balancing policy, health policy, scaling policy, update policy and so on.
|
||||
|
||||
IRC Channel: #senlin
|
||||
Senlin is designed to be capable of managing different types of objects. An
|
||||
object's lifecycle is managed using profile type implementations, which are
|
||||
themselves plugins.
|
||||
|
||||
--------------------
|
||||
Install via Devstack
|
||||
--------------------
|
||||
---------
|
||||
For Users
|
||||
---------
|
||||
|
||||
This is the recommended way to install Senlin service. Please refer to
|
||||
`devstack/README.rst` for detailed instructions.
|
||||
If you want to install Senlin for a try out, please refer to the documents
|
||||
under the ``doc/source/getting_started/`` subdirectory.
|
||||
|
||||
Note that Senlin client is also installed when following the instructions
|
||||
it the above mentioned document.
|
||||
--------------
|
||||
For Developers
|
||||
--------------
|
||||
|
||||
-------------------
|
||||
Manual Installation
|
||||
-------------------
|
||||
There are many ways to help improve the software, for example, filing a bug,
|
||||
submitting or reviewing a patch, writing or reviewing some documents. There
|
||||
are documents under the ``doc/source/developer/`` subdirectory.
|
||||
|
||||
---------
|
||||
Resources
|
||||
---------
|
||||
|
||||
Launchpad Projects
|
||||
------------------
|
||||
- Server: https://launchpad.net/senlin
|
||||
- Client: https://launchpad.net/python-senlinclient
|
||||
|
||||
Code Repository
|
||||
---------------
|
||||
- Server: https://git.openstack.org/cgit/stackforge/senlin
|
||||
- Client: https://git.openstack.org/cgit/stackforge/python-senlinclient
|
||||
|
||||
Blueprints
|
||||
----------
|
||||
- Blueprints: https://blueprints.launchpad.net/senlin
|
||||
|
||||
Bug Tracking
|
||||
------------
|
||||
- Bugs: https://bugs.launchpad.net/senlin
|
||||
|
||||
Weekly Meetings
|
||||
---------------
|
||||
- Schedule: every Tuesday at 1300 UTC, on #openstack-meeting channel
|
||||
- Agenda: http://wiki.openstack.org/wiki/Meetings/SenlinAgenda
|
||||
- Archive: http://eavesdrop.openstack.org/meetings/senlin/2015/
|
||||
|
||||
IRC
|
||||
---
|
||||
IRC Channel: #senlin on `Freenode`_.
|
||||
|
||||
Mailinglist
|
||||
-----------
|
||||
Project use http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
|
||||
as the mailinglist. Please use tag ``[Senlin]`` in the subject for new
|
||||
threads.
|
||||
|
||||
|
||||
Install Senlin Server
|
||||
---------------------
|
||||
|
||||
1. Get Senlin source code from OpenStack git repository
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack
|
||||
$ git clone http://git.openstack.org/stackforge/senlin.git
|
||||
|
||||
2. Install Senlin with required packages
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin
|
||||
$ sudo pip install -e .
|
||||
|
||||
3. Register Senlin clustering service with keystone.
|
||||
|
||||
This can be done using the `setup-service` script under `tools` folder.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin/tools
|
||||
$ ./setup-service <HOST IP> <SERVICE_PASSWORD>
|
||||
|
||||
4. Generate configuration file for the Senlin service
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin
|
||||
$ tools/gen-config
|
||||
$ sudo mkdir /etc/senlin
|
||||
$ sudo cp etc/senlin/api-paste.ini /etc/senlin
|
||||
$ sudo cp etc/senlin/policy.json /etc/senlin
|
||||
$ sudo cp etc/senlin/senlin.conf.sample /etc/senlin/senlin.conf
|
||||
|
||||
Edit file `/etc/senlin/senlin.conf` according to your system settings. The
|
||||
most common options to be customized include::
|
||||
|
||||
[database]
|
||||
connection = mysql://senlin:<DB PASSWORD>@127.0.0.1/senlin?charset=utf8
|
||||
|
||||
[keystone_authtoken]
|
||||
auth_uri = http://<HOST>:5000/v3
|
||||
auth_version = 3
|
||||
cafile = /opt/stack/data/ca-bundle.pem
|
||||
identity_uri = http://<HOST>:35357
|
||||
admin_user = senlin
|
||||
admin_password = <SENLIN PASSWORD>
|
||||
admin_tenant_name = service
|
||||
|
||||
[oslo_messaging_rabbit]
|
||||
rabbit_userid = <RABBIT USER ID>
|
||||
rabbit_hosts = <HOST>
|
||||
rabbit_password = <RABBIT PASSWORD>
|
||||
|
||||
5. Create Senlin Database
|
||||
|
||||
Create Senlin database using the `senlin-db-recreate` script under the `tools`
|
||||
subdirectory. Before calling the script, you need edit it to customize the
|
||||
password you will use for the `senlin` user.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin/tools
|
||||
$ ./senlin-db-recreate
|
||||
|
||||
6. Start senlin engine and api service.
|
||||
|
||||
You may need two consoles for the services each.
|
||||
|
||||
::
|
||||
|
||||
$ senlin-engine --config-file /etc/senlin/senlin.conf
|
||||
$ senlin-api --config-file /etc/senlin/senlin.conf
|
||||
|
||||
---------------------
|
||||
Install Senlin Client
|
||||
---------------------
|
||||
|
||||
1. Get Senlin client code from OpenStack git repository.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack
|
||||
$ git clone http://git.openstack.org/stackforge/python-senlinclient.git
|
||||
|
||||
2. Install senlin client.
|
||||
|
||||
::
|
||||
|
||||
$ cd python-senlinclient
|
||||
$ sudo python setup.py install
|
||||
|
||||
You are ready to begin your journey (aka. adventure) with Senlin, now.
|
||||
.. _Freenode: http://freenode.net/
|
||||
|
|
|
@ -12,16 +12,32 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-actions:
|
||||
|
||||
|
||||
Actions
|
||||
=======
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
An action is a ...
|
||||
An :term:`Action` is a ...
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Actions
|
||||
---------------
|
||||
|
||||
[TBC]
|
||||
(TBC)
|
||||
|
||||
|
||||
Showing Details of an Action
|
||||
----------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
* :doc:`Creating Webooks <webhooks>`
|
||||
* :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
..
|
||||
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.
|
||||
|
||||
Senlin Architecture
|
||||
===================
|
||||
|
||||
Senlin is a service to create and manage clusters of homogeneous resources on
|
||||
an OpenStack cloud. Senlin provides an OpenStack-native ReST API.
|
||||
|
||||
|
||||
--------------------
|
||||
Detailed Description
|
||||
--------------------
|
||||
|
||||
What is the purpose of the project and vision for it?
|
||||
|
||||
Senlin provides a clustering service for OpenStack that manages a collection
|
||||
of nodes that are of the same type.
|
||||
|
||||
Describe the relevance of the project to other OpenStack projects and the
|
||||
OpenStack mission to provide a ubiquitous cloud computing platform:
|
||||
|
||||
The Senlin service aggregates resources exposed by other components of
|
||||
OpenStack into a cluster. Such a cluster can be associated with different
|
||||
policies that can be checked/enforced at varying enforcement levels. Through
|
||||
service APIs, a user can dynamically add nodes to and remove nodes from a
|
||||
cluster, attach and detach policies, such as creation policy, deletion policy,
|
||||
load-balancing policy, scaling policy, health checking policy etc. Through
|
||||
integration with other OpenStack projects, users will be enabled to manage
|
||||
deployments and orchestrations large scale resource pools much easier.
|
||||
|
||||
Currently no other clustering service exists for OpenStack. The developers
|
||||
believe cloud developers have a strong desire to create and operate resource
|
||||
clusters on OpenStack deployments. The Heat project provides a preliminary
|
||||
support to resource groups but Heat developers have achieved a consensus that
|
||||
such kind of a service should stand on its own feet.
|
||||
|
||||
---------------
|
||||
Senlin Services
|
||||
---------------
|
||||
|
||||
The developers are focusing on creating an OpenStack style project using
|
||||
OpenStack design tenets, implemented in Python. We have started with a close
|
||||
interaction with Heat project.
|
||||
|
||||
As the developers have only started development in December 2014, the
|
||||
architecture is evolving rapidly.
|
||||
|
||||
senlin
|
||||
------
|
||||
|
||||
The senlin tool is a CLI which communicates with the senlin-api to manage
|
||||
clusters, nodes, profiles, policies and events. End developers could also use
|
||||
the Senlin REST API directly.
|
||||
|
||||
|
||||
senlin-api
|
||||
----------
|
||||
|
||||
The senlin-api component provides an OpenStack-native REST API that processes
|
||||
API requests by sending them to the senlin-engine over RPC.
|
||||
|
||||
|
||||
senlin-engine
|
||||
-------------
|
||||
|
||||
The senlin engine's main responsibility is to orchestrate the clusters, nodes,
|
||||
profiles and policies.
|
|
@ -0,0 +1,46 @@
|
|||
..
|
||||
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.
|
||||
|
||||
|
||||
.. _guide-bindings:
|
||||
|
||||
Cluster-Policy Bindings
|
||||
=======================
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A :term:`Policy` object can attached to at least one :term:`Cluster` at the
|
||||
same time. A cluster at any time can have more than one Policy objects
|
||||
attached to it.
|
||||
|
||||
|
||||
Listing Policies Attached to a Cluster
|
||||
--------------------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Attach a Policy to a Cluster
|
||||
----------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Detach a Policy from a Cluster
|
||||
------------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Update Policy Properties on a Cluster
|
||||
-------------------------------------
|
||||
|
||||
(TBC)
|
|
@ -12,16 +12,453 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-clusters:
|
||||
|
||||
Clusters
|
||||
========
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A cluster is a ...
|
||||
A :term:`Cluster` is a group of logical objects, each of which is called a
|
||||
:term:`Node` in Senlin's terminology. A cluster can contain zero or more
|
||||
nodes. A cluster has a ``profile_id`` property that specifies which
|
||||
:term:`Profile` to use when new nodes are created as members the cluster.
|
||||
|
||||
Senlin provides APIs and command line supports to manage the cluster
|
||||
membership. Please refer to :ref:`guide-membership` for details. Senlin also
|
||||
supports attaching :term:`Policy` objects to a cluster, customizing the policy
|
||||
properties when attaching a policy to a cluster. Please refer to
|
||||
:ref:`guide-bindings` for details.
|
||||
|
||||
Listing Clusters
|
||||
----------------
|
||||
|
||||
The following command shows the clusters managed by the Senlin service::
|
||||
|
||||
$ senlin cluster-list
|
||||
+----------+------+--------+---------------------+
|
||||
| id | name | status | created_time |
|
||||
+----------+------+--------+---------------------+
|
||||
| 2959122e | c1 | ACTIVE | 2015-05-05T13:27:28 |
|
||||
| 092d0955 | c2 | ACTIVE | 2015-05-05T13:27:48 |
|
||||
+----------+------+--------+---------------------+
|
||||
|
||||
The :program:`senlin` command line supports various options for the command
|
||||
:command:`cluster-list`. You can specify the option :option:`--show-deleted`
|
||||
(or :option:`-d`) to indicate that soft-deleted clusters be included in the
|
||||
list result.
|
||||
|
||||
Note that the first column in the output table is a *short ID* of a cluster
|
||||
object. Senlin command line use short IDs to save real estate on screen so
|
||||
that more useful information can be shown on a single line. To show the *full
|
||||
ID* in the list, you can add the :option:`-F` (or :option:`--full-id`) option
|
||||
to the command::
|
||||
|
||||
$ senlin cluster-list -F
|
||||
+--------------------------------------+------+--------+---------------------+--------------+
|
||||
| id | name | status | created_time | updated_time |
|
||||
+--------------------------------------+------+--------+---------------------+--------------+
|
||||
| 2959122e-11c7-4e82-b12f-f49dc5dac270 | c1 | ACTIVE | 2015-05-05T13:27:28 | None |
|
||||
| 092d0955-2645-461a-b8fa-6a44655cdb2c | c2 | ACTIVE | 2015-05-05T13:27:48 | None |
|
||||
+--------------------------------------+------+--------+---------------------+--------------+
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Sorting the List
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
[TBC]
|
||||
You specify the sorting keys and sorting directions for the cluster list,
|
||||
using the option :option:`--sort-keys` (or :option:`-k`) and the option
|
||||
:option:`--sort-dir` (or :option:`-s`). For example, the following command
|
||||
instructs the :program:`senlin` command line to sort clusters using the
|
||||
``name`` property in descending order::
|
||||
|
||||
$ senlin cluster-list -k name -s desc
|
||||
+----------+------+--------+---------------------+
|
||||
| id | name | status | created_time |
|
||||
+----------+------+--------+---------------------+
|
||||
| 2959122e | c1 | ACTIVE | 2015-05-05T13:27:28 |
|
||||
| 092d0955 | c2 | ACTIVE | 2015-05-05T13:27:48 |
|
||||
+----------+------+--------+---------------------+
|
||||
|
||||
For sorting the cluster list, the valid keys are: ``name``, ``status``,
|
||||
``created_time`` and ``updated_time``, the valid sorting directions are:
|
||||
``asc`` and ``desc``.
|
||||
|
||||
|
||||
Filtering the List
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :program:`senlin` command line also provides options for filtering the
|
||||
cluster list at the server side. The option :option:`--filters` (or
|
||||
:option:`-f`) can be used for this purpose. For example, the following command
|
||||
filters clusters by the ``status`` field::
|
||||
|
||||
$ senlin cluster-list -f status=ACTIVE
|
||||
+----------+------+--------+---------------------+
|
||||
| id | name | status | created_time |
|
||||
+----------+------+--------+---------------------+
|
||||
| 2959122e | c1 | ACTIVE | 2015-05-05T13:27:28 |
|
||||
| 092d0955 | c2 | ACTIVE | 2015-05-05T13:27:48 |
|
||||
+----------+------+--------+---------------------+
|
||||
|
||||
The option :option:`--filters` accepts a list of key-value pairs separated by
|
||||
semicolon (``;``), where each key-value pair is expected to be of format
|
||||
``<key>=<value>``. The valid keys for filtering include: ``status``, ``name``,
|
||||
``project``, ``parent`` and ``user``.
|
||||
|
||||
|
||||
Paginating the Query
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In case you have a huge collection of clusters, you can limit the number of
|
||||
clusters returned from Senlin server each time, using the option
|
||||
:option:`--limit <LIMIT>` (or :option:`--l <LIMIT>`). For example::
|
||||
|
||||
$ senlin cluster-list -l 1
|
||||
+----------+------+--------+---------------------+
|
||||
| id | name | status | created_time |
|
||||
+----------+------+--------+---------------------+
|
||||
| 2959122e | c1 | ACTIVE | 2015-05-05T13:27:28 |
|
||||
+----------+------+--------+---------------------+
|
||||
|
||||
Another option you can specify is the ID of a cluster from which you want to
|
||||
see the returned list starts. In other words, you don't want to see those
|
||||
clusters with IDs that come before the one you specify. You can use the option
|
||||
:option:`--marker <ID>` (or :option:`-m <ID>`) for this purpose. For example::
|
||||
|
||||
$ senlin profile-list -l 1 -m 2959122e-11c7-4e82-b12f-f49dc5dac270
|
||||
+----------+------+--------+---------------------+
|
||||
| id | name | status | created_time |
|
||||
+----------+------+--------+---------------------+
|
||||
| 092d0955 | c2 | ACTIVE | 2015-05-05T13:27:48 |
|
||||
+----------+------+--------+---------------------+
|
||||
|
||||
Only 1 cluster record is returned in this example and its UUID comes after the
|
||||
the one specified from the command line.
|
||||
|
||||
|
||||
Creating a Cluster
|
||||
------------------
|
||||
|
||||
To create a cluster, you need to provide the ID or name of the profile to be
|
||||
associated with the cluster. For example::
|
||||
|
||||
$ senlin cluster-create --profile qstack c3
|
||||
+------------------+--------------------------------------+
|
||||
| Property | Value |
|
||||
+------------------+--------------------------------------+
|
||||
| created_time | None |
|
||||
| data | {} |
|
||||
| deleted_time | None |
|
||||
| desired_capacity | 0 |
|
||||
| domain | None |
|
||||
| id | 60424eb3-6adf-4fc3-b9a1-4a035bf171ac |
|
||||
| max_size | -1 |
|
||||
| metadata | {} |
|
||||
| min_size | 0 |
|
||||
| name | c3 |
|
||||
| nodes | |
|
||||
| parent | None |
|
||||
| profile_id | bf38dc9f-d204-46c9-b515-79caf1e45c4d |
|
||||
| profile_name | qstack |
|
||||
| project | 333acb15a43242f4a609a27cb097a8f2 |
|
||||
| status | INIT |
|
||||
| status_reason | Initializing |
|
||||
| timeout | None |
|
||||
| updated_time | None |
|
||||
| user | 0b82043b57014cd58add97a2ef79dac3 |
|
||||
+------------------+--------------------------------------+
|
||||
|
||||
From the output you can see that a new cluster object created and put to
|
||||
``INIT`` status. Senlin will verify if profile specified using the option
|
||||
:option:`--profile <PROFILE>` (or :option:`-p <PROFILE>`) does exist. The
|
||||
server allows the ``<PROFILE>`` value to be a profile name, a profile ID or
|
||||
the short ID of a profile object. If the profile is not found or multiple
|
||||
profiles found matching the value, you will receive an error message.
|
||||
|
||||
|
||||
Controlling Cluster Capacity
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When creating a cluster, by default :program:`senlin` will create a cluster
|
||||
with no nodes, i.e. the ``desired_capacity`` will be set to 0. However, you
|
||||
can specify the desired capacity of the cluster, the maximum size and/or the
|
||||
minimum size of the cluster. The default value for ``min_size`` is 0 and the
|
||||
default value for ``max_size`` is -1, meaning that there is no upper bound for
|
||||
the cluster size.
|
||||
|
||||
The following command creates a cluster named "``test_cluster``", with its
|
||||
desired capacity set to 2, its minimum size set to 1 and its maximum size set
|
||||
to 3::
|
||||
|
||||
$ senlin cluster-create -n 1 -c 2 -m 3 -p myprofile test_cluster
|
||||
|
||||
Senlin API and Senlin engine will validate the settings for these capacity
|
||||
arguments when receiving this request. An error message will be returned if
|
||||
the arguments fail to pass this validation, or else the cluster creation
|
||||
request will be queued as an action for execution.
|
||||
|
||||
When ``desired_capacity`` is not specified and ``min_size`` is not specified,
|
||||
Senlin engine will create an empty cluster. When either ``desired_capacity``
|
||||
or ``min_size`` is specified, Senlin will start the process of creating nodes
|
||||
immediately after the cluster object is created.
|
||||
|
||||
|
||||
Other Properties
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use the option :option:`--metadata` (or :option:`-d`) to associate
|
||||
some key-value pairs to the cluster to be created. These data are referred to
|
||||
as the "metadata" for the cluster.
|
||||
|
||||
Since cluster operations may take some time to finish when being executed and
|
||||
Senlin interacts with the backend services to make it happen, there needs a
|
||||
way to verify whether an operation has timed out. When creating a cluster
|
||||
using the :program:`senlin` command line tool, you can use the option
|
||||
:option:`--timeout <TIMEOUT>` (or :option:`-t <TIMEOUT>`) to specify the
|
||||
default time out in number of seconds. This value would be the global setting
|
||||
for the cluster.
|
||||
|
||||
Optionally, you can specify the option :option:`--parent <PARENT_ID>`` (or
|
||||
:option:`-o <PARENT_ID>`) when creating a cluster. This is a feature reserved
|
||||
for nested clusters. It is not supported yet at the time of this writing.
|
||||
|
||||
|
||||
Showing Details of a Cluster
|
||||
----------------------------
|
||||
|
||||
When there are clusters in the Senlin database, you can request Senlin to show
|
||||
the details about a cluster you are intested in.
|
||||
|
||||
You can use the name, the ID or the "short ID" of a cluster to name a cluster
|
||||
for show. Senlin API and engine will verify if the identifier you specified
|
||||
can uniquely identify a cluster. An error message will be returned if there is
|
||||
no cluster matching the identifier or if more than one cluster matching it.
|
||||
|
||||
An example is shown below::
|
||||
|
||||
$ senlin cluster-show c3
|
||||
+------------------+--------------------------------------+
|
||||
| Property | Value |
|
||||
+------------------+--------------------------------------+
|
||||
| created_time | 2015-07-07T03:30:53 |
|
||||
| data | {} |
|
||||
| deleted_time | None |
|
||||
| desired_capacity | 0 |
|
||||
| domain | None |
|
||||
| id | 2b7e9294-b5cd-470f-b191-b18f7e672495 |
|
||||
| max_size | -1 |
|
||||
| metadata | {} |
|
||||
| min_size | 0 |
|
||||
| name | c3 |
|
||||
| nodes | b28692a5-2536-4921-985b-1142d6045e1f |
|
||||
| | 4be10a88-e340-4518-a9e1-d742c53ac37f |
|
||||
| parent | None |
|
||||
| profile_id | bf38dc9f-d204-46c9-b515-79caf1e45c4d |
|
||||
| profile_name | qstack |
|
||||
| project | 333acb15a43242f4a609a27cb097a8f2 |
|
||||
| status | ACTIVE |
|
||||
| status_reason | Node stack2: Creation succeeded |
|
||||
| timeout | None |
|
||||
| updated_time | None |
|
||||
| user | 0b82043b57014cd58add97a2ef79dac3 |
|
||||
+------------------+--------------------------------------+
|
||||
|
||||
From the result, you can examine the list of nodes (if any) that are members
|
||||
of this cluster.
|
||||
|
||||
|
||||
Updating a Cluster
|
||||
------------------
|
||||
|
||||
Once a cluster has been created, you change its properties using the
|
||||
:program:`senlin` command line. For example, to change the name of a cluster,
|
||||
you can use the following command::
|
||||
|
||||
$ senlin cluster-update -n web_bak web_servers
|
||||
|
||||
You can change the ``timeout`` property using option :option:`--timeout` (or
|
||||
:option:`-t`) for the ``cluster-update`` command. You can change the metadata
|
||||
associated with cluster using option :option:`--metadata` (or :option:`-d`).
|
||||
When cluster nesting is implemented, you will be able to change the parent
|
||||
cluster using the option :option:`--parent` (or :option:`-o`).
|
||||
|
||||
Using the :command:`cluster-update` command, you can change the profile used
|
||||
by the cluster and its member nodes. The following example launches a global
|
||||
update on the cluster for switching to a different profile::
|
||||
|
||||
$ senlin cluster-update -p fedora21_server web_cluster
|
||||
|
||||
Suppose the cluster ``web_cluster`` is now using a profile of type
|
||||
``os.nova.server`` where a Fedora 20 image is used, the command above will
|
||||
initiate a global upgrade to a new profile where a Fedora 21 image is used.
|
||||
|
||||
Senlin engine will verify whether the new profile has the same profile type
|
||||
with that of the existing one and whether the new profile has a well-formed
|
||||
``spec`` property. If everything is fine, the engine will start a node level
|
||||
profile update process. The node level update operation is subject to policy
|
||||
checkings/enforcements when there is an update policy attached to the cluster.
|
||||
Please refer to :ref:`guide-policies` and :ref:`guide-bindings` for more
|
||||
information.
|
||||
|
||||
|
||||
Resizing a Cluster
|
||||
------------------
|
||||
|
||||
The :program:`senlin` tool supports several different commands to resize a
|
||||
cluster.
|
||||
|
||||
|
||||
``cluster-resize``
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The command :command:`cluster-resize` takes several arguments that allow you
|
||||
to resize a cluster in various ways:
|
||||
|
||||
- you can change the size of a cluster to a specified number;
|
||||
- you can add a specified number of nodes to a cluster or remove a specified
|
||||
number of nodes from a cluster;
|
||||
- you can instruct :program:`senlin` to resize a cluster by a specified
|
||||
percentage;
|
||||
- you can tune the ``min_size`` and/or ``max_size`` property of a cluster when
|
||||
resizing it;
|
||||
- you can request a size change made on a best-effort basis, if the resize
|
||||
operation cannot be fully realized due to some restrictions, this argument
|
||||
tells Senlin engine whether it is still expected to partially realize the
|
||||
resize operation.
|
||||
|
||||
You can specify one and only one of the following options for the
|
||||
:command:`cluster-resize` command:
|
||||
|
||||
- use :option:`--capacity <CAPACITY>` (:option:`-c <CAPACITY>`) to specify
|
||||
the exact value of the new cluster size;
|
||||
- use :option:`--adjustment <ADJUSTMENT>` (:option:`-a <ADJUSTMENT>`) to
|
||||
specify the relative number of nodes to add/remove;
|
||||
- use :option:`--percentage <PERCENTAGE>` (:option:`-p <PERCENTAGE>`) to
|
||||
specify the percentage of cluster size change.
|
||||
|
||||
The following command resizes the cluster ``test_cluster`` to 2 nodes,
|
||||
provided that the ``min_size`` is less than or equal to 2 and the ``max_size``
|
||||
is either no less than 2 or equal to -1 (indicating that there is no upper
|
||||
bound for the cluster size). This command makes use of the option
|
||||
:option:`--capacity <CAPACITY>` (or :option:`-c <CAPACITY>`), where
|
||||
``<CAPACITY>`` is the new size of the cluster::
|
||||
|
||||
$ senlin cluster-resize -c 2 test_cluster
|
||||
|
||||
Another way to resize a cluster is by specifying the :option:`--adjustment
|
||||
<ADJUSTMENT>` (or :option:`-a <ADJUSTMENT>`) option, where ``<ADJUSTMENT>``
|
||||
can be a positive or a negative integer giving the number of nodes to add or
|
||||
remove respectively. For example, the following command adds two nodes to the
|
||||
specified cluster::
|
||||
|
||||
$ senlin cluster-resize -a 2 test_cluster
|
||||
|
||||
The following command removes two nodes from the specified cluster::
|
||||
|
||||
$ senlin cluster-resize -a -2 test_cluster
|
||||
|
||||
Yet another way to resize a cluster is by specifying the size change in
|
||||
percentage. You will use the option :option:`--percentage <PERCENTAGE>` (or
|
||||
:option:`-p <PERCENTAGE>` for this purpose. The ``<PERCENTAGE>`` value can be
|
||||
either a positive float value or a negative float value giving the percentage
|
||||
of cluster size. For example, the following command increases the cluster size
|
||||
by 30%::
|
||||
|
||||
$ senlin cluster-resize -p 30 test_cluster
|
||||
|
||||
The following command decreases the cluster size by 25%::
|
||||
|
||||
$ senlin cluster-resize -p -25 test_cluster
|
||||
|
||||
Senlin engine computes the actual number of nodes to add or to remove based on
|
||||
the current size of the cluster, the specified percentage value, the
|
||||
constraints (i.e. the ``min_size`` and the ``max_size`` properties).
|
||||
|
||||
When computing the new capacity for the cluster, senlin engine will determine
|
||||
the value based on the following rules:
|
||||
|
||||
- If the value of new capacity is greater than 1.0 or less than -1.0, it will
|
||||
be rounded to the integer part of the value. For example, 3.4 will be rounded
|
||||
to 3, -1.9 will be rounded to -1;
|
||||
- If the value of the new capacity is between 0 and 1, Senlin will round it up
|
||||
to 1;
|
||||
- If the value of the new capacity is between 0 and -1, Senlin will round it
|
||||
down to -1;
|
||||
- The new capacity should be in the range of ``min_size`` and ``max_size``,
|
||||
inclusively, unless option :option:`--strict` (or :option:`-s`) is specified;
|
||||
- The range checking will be performed against the current size constraints if
|
||||
no new value for ``min_size`` and/or ``max_size`` is given, or else Senlin
|
||||
will first verify the new size constraints and perform range checking
|
||||
against the new constraints;
|
||||
- If option :option:`--min-step <MIN_STEP>` (or :option:`-t <MIN_STEP>`) is
|
||||
specified, the ``<MIN_STEP>`` value will be used if the absolute value of
|
||||
the new capacity value is less than ``<MIN_STEP>``.
|
||||
|
||||
If option :option:`--strict`` (or :option:`-s`) is specified, Senlin will
|
||||
strictly conform to the cluster size constraints. If the capacity value falls
|
||||
out of the range, the request will be rejected. When :option:`--strict` is set
|
||||
to False, Senlin engine will do a resize on a best-effort basis.
|
||||
|
||||
Suppose we have a cluster A with ``min_size`` set to 5 and its current size is
|
||||
7. If the new capacity value is 4 and option :option:`--strict` is set to
|
||||
``True``, the request will be rejected with an error message. If the new
|
||||
capacity value is 4 and the option :option:`--strict` is not set, Senlin will
|
||||
try resize the cluster to 5 nodes.
|
||||
|
||||
Along with the :command:`cluster-resize` command, you can specify the new size
|
||||
constraints using either the option :option:`--min-size` (or :option:`-n`) or
|
||||
the option :option:`--max-size` (or :option:`-m`) or both.
|
||||
|
||||
``cluster-scale-in`` and ``cluster-scale-out``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :command:`cluster-scale-in` command and the :command:`cluster-scale-out`
|
||||
command are provided for convenience when you want to add specific number of
|
||||
nodes to a cluster or remove specific number of nodes from a cluster,
|
||||
respectively. These two commands both take an argument ``<COUNT>`` which is a
|
||||
positive integer giving the number of nodes to add or remove. For example, the
|
||||
following command adds two nodes to the ``web_servers`` cluster::
|
||||
|
||||
$ senlin cluster-scale-out -c 2 web_servers
|
||||
|
||||
The following command removes two nodes from the ``web_servers`` cluster::
|
||||
|
||||
$ senlin cluster-scale-in -c 2 web_servers
|
||||
|
||||
The option :option:`--count <COUNT>` (:option:`-c <COUNT>`) is optional. If
|
||||
this option is specified, Senlin will use it for cluster size change, even
|
||||
when there are scaling policies attached to the cluster. If this option is
|
||||
omitted, however, Senlin will treat it as implicitly set to value 1.
|
||||
|
||||
|
||||
Deleting a Cluster
|
||||
------------------
|
||||
|
||||
A cluster can be deleted using the command :command:`cluster-delete`, for
|
||||
example::
|
||||
|
||||
$ senlin cluster-delete my_cluster
|
||||
|
||||
Note that in this command you can use the name, the ID or the "short ID" to
|
||||
specify the cluster object you want to delete. If the specified criteria
|
||||
cannot match any clusters, you will get a ``ClusterNotFound`` error. If more
|
||||
than one cluster matches the criteria, you will get a ``MultipleChoices``
|
||||
error.
|
||||
|
||||
When there are nodes in the cluster, the Senlin engine will launch a process
|
||||
to delete all nodes from the cluster and destroy them before deleting the
|
||||
cluster object itself.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
There are other operations related to clusters. Please refer to the following
|
||||
links for operations related to cluster membership management and the creation
|
||||
and management of cluster-policy bindings:
|
||||
|
||||
- :doc:`Managing Cluster Membership <membership>`
|
||||
- :doc:`Bindging Policies to Clusters <bindings>`
|
||||
- :doc:`Examining Actions <actions>`
|
||||
- :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -12,16 +12,20 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-events:
|
||||
|
||||
Events
|
||||
======
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
An event is a ...
|
||||
An :term:`Event` is a record generated during engine execution.
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Events
|
||||
--------------
|
||||
|
||||
[TBC]
|
||||
(TBC)
|
||||
|
||||
Showing Details about an Event
|
||||
-------------------------------
|
||||
|
||||
(TBC)
|
||||
|
|
|
@ -11,29 +11,88 @@
|
|||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _guide-index:
|
||||
|
||||
Getting Started with Senlin
|
||||
===========================
|
||||
|
||||
Before You Begin
|
||||
----------------
|
||||
--------
|
||||
Overview
|
||||
--------
|
||||
|
||||
Senlin is a **clustering service** for OpenStack clouds. It creates and
|
||||
operates clusters of homogenous objects exposed by other OpenStack services.
|
||||
The goal is to make orchestration of collections of similar objects easier.
|
||||
|
||||
A :term:`Cluster` can be associated with different :term:`Policy` objects
|
||||
that can be checked/enforced at varying enforcement levels. Through service
|
||||
APIs, a user can dynamically add :term:`Node` to and remove node from a
|
||||
cluster, attach and detach policies, such as *creation policy*, *deletion
|
||||
policy*, *load-balancing policy*, *scaling policy*, *health policy* etc.
|
||||
Through integration with other OpenStack projects, users will be enabled to
|
||||
manage deployments and orchestrations large-scale resource pools much easier.
|
||||
|
||||
Currently no other clustering service exists for OpenStack. The developers
|
||||
believe cloud operators have a strong desire to create and operate resource
|
||||
pools on OpenStack deployments. The *Heat* project provides a preliminary
|
||||
support to resource groups but Heat team has achieved a consensus that
|
||||
such kind of a service should stand on its own feet.
|
||||
|
||||
Senlin is designed to be capable of managing different types of objects. An
|
||||
object's lifecycle is managed using :term:`Profile Type` implementations,
|
||||
which are plugins that can be dynamically loaded by the service engine.
|
||||
|
||||
Components
|
||||
----------
|
||||
|
||||
The developers are focusing on creating an OpenStack style project using
|
||||
OpenStack design tenets, implemented in Python. We have started with a close
|
||||
interaction with Heat project.
|
||||
|
||||
senlin
|
||||
------
|
||||
|
||||
The :program:`senlin` tool is a command line interface that communicates with
|
||||
the :program:`senlin-api` to manage clusters, nodes, profiles, policies,
|
||||
actions and events. End developers could also use the Senlin REST API directly.
|
||||
|
||||
senlin-api
|
||||
----------
|
||||
|
||||
The :program:`senlin-api` component provides an OpenStack-native REST API that
|
||||
processes API requests by sending them to the :program:`senlin-engine` over RPC.
|
||||
|
||||
senlin-engine
|
||||
-------------
|
||||
|
||||
The :program:`senlin-engine`'s main responsibility is to create and orchestrate
|
||||
the clusters, nodes, profiles and policies.
|
||||
|
||||
|
||||
------------
|
||||
Installation
|
||||
------------
|
||||
|
||||
You will need to make sure you have a suitable environment for deploying
|
||||
Senlin.
|
||||
Senlin. Please refer to :ref:`Installation <guide-install>` for detailed
|
||||
instructions on setting up an environment to use the Senlin service.
|
||||
|
||||
|
||||
----------
|
||||
How To Use
|
||||
----------------
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
----------
|
||||
|
||||
architecture
|
||||
profile_types
|
||||
profiles
|
||||
clusters
|
||||
nodes
|
||||
policy_types
|
||||
policies
|
||||
actions
|
||||
events
|
||||
webhooks
|
||||
glossary
|
||||
This section walks you through some basic operations you can do with the
|
||||
Senlin service including its clients.
|
||||
|
||||
- :doc:`Working with Profile Types <profile_types>`
|
||||
- :doc:`Managing Profiles Objects <profiles>`
|
||||
- :doc:`Creating Clusters <clusters>`
|
||||
- :doc:`Creating and Managing Nodes <nodes>`
|
||||
- :doc:`Managing Cluster Membership <membership>`
|
||||
- :doc:`Working with Policy Types <policy_types>`
|
||||
- :doc:`Creating Your Own Policy Objects <policies>`
|
||||
- :doc:`Binding a Policy to a Cluster <bindings>`
|
||||
- :doc:`Creating Webhooks for Your Objects <webhooks>`
|
||||
- :doc:`Examinining Actions <actions>`
|
||||
- :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
..
|
||||
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.
|
||||
|
||||
.. _guide-install:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
There are in general two ways to install Senlin service: you can install it
|
||||
via devstack, or you install it manually, following the steps outlined in this
|
||||
document.
|
||||
|
||||
|
||||
--------------------
|
||||
Install via Devstack
|
||||
--------------------
|
||||
|
||||
This is the recommended way to install the Senlin service. Please refer to
|
||||
:file:`devstack/README.rst` for detailed instructions.
|
||||
|
||||
Note that Senlin client is also installed when following the instructions
|
||||
it the above mentioned document.
|
||||
|
||||
-------------------
|
||||
Manual Installation
|
||||
-------------------
|
||||
|
||||
|
||||
Install Senlin Server
|
||||
---------------------
|
||||
|
||||
1. Get Senlin source code from OpenStack git repository
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack
|
||||
$ git clone http://git.openstack.org/stackforge/senlin.git
|
||||
|
||||
2. Install Senlin with required packages
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin
|
||||
$ sudo pip install -e .
|
||||
|
||||
3. Register Senlin clustering service with keystone.
|
||||
|
||||
This can be done using the :command:`setup-service` script under the
|
||||
:file:`tools` folder.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin/tools
|
||||
$ ./setup-service <HOST IP> <SERVICE_PASSWORD>
|
||||
|
||||
4. Generate configuration file for the Senlin service.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin
|
||||
$ tools/gen-config
|
||||
$ sudo mkdir /etc/senlin
|
||||
$ sudo cp etc/senlin/api-paste.ini /etc/senlin
|
||||
$ sudo cp etc/senlin/policy.json /etc/senlin
|
||||
$ sudo cp etc/senlin/senlin.conf.sample /etc/senlin/senlin.conf
|
||||
|
||||
Edit file :file:`/etc/senlin/senlin.conf` according to your system settings.
|
||||
The most common options to be customized include:
|
||||
|
||||
::
|
||||
|
||||
[database]
|
||||
connection = mysql://senlin:<DB PASSWORD>@127.0.0.1/senlin?charset=utf8
|
||||
|
||||
[keystone_authtoken]
|
||||
auth_uri = http://<HOST>:5000/v3
|
||||
auth_version = 3
|
||||
cafile = /opt/stack/data/ca-bundle.pem
|
||||
identity_uri = http://<HOST>:35357
|
||||
admin_user = senlin
|
||||
admin_password = <SENLIN PASSWORD>
|
||||
admin_tenant_name = service
|
||||
|
||||
[oslo_messaging_rabbit]
|
||||
rabbit_userid = <RABBIT USER ID>
|
||||
rabbit_hosts = <HOST>
|
||||
rabbit_password = <RABBIT PASSWORD>
|
||||
|
||||
5. Create Senlin Database
|
||||
|
||||
Create Senlin database using the :command:`senlin-db-recreate` script under
|
||||
the :file:`tools` subdirectory. Before calling the script, you need edit it
|
||||
to customize the password you will use for the ``senlin`` user.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack/senlin/tools
|
||||
$ ./senlin-db-recreate
|
||||
|
||||
6. Start senlin engine and api service.
|
||||
|
||||
You may need two consoles for the services each.
|
||||
|
||||
::
|
||||
|
||||
$ senlin-engine --config-file /etc/senlin/senlin.conf
|
||||
$ senlin-api --config-file /etc/senlin/senlin.conf
|
||||
|
||||
---------------------
|
||||
Install Senlin Client
|
||||
---------------------
|
||||
|
||||
1. Get Senlin client code from OpenStack git repository.
|
||||
|
||||
::
|
||||
|
||||
$ cd /opt/stack
|
||||
$ git clone http://git.openstack.org/stackforge/python-senlinclient.git
|
||||
|
||||
2. Install senlin client.
|
||||
|
||||
::
|
||||
|
||||
$ cd python-senlinclient
|
||||
$ sudo python setup.py install
|
||||
|
||||
You are ready to begin your journey (aka. adventure) with Senlin, now.
|
|
@ -0,0 +1,45 @@
|
|||
..
|
||||
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.
|
||||
|
||||
|
||||
.. _guide-membership:
|
||||
|
||||
Cluster Membership
|
||||
==================
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A :term:`Node` can belong to at most one :term:`Cluster` at any time. A node
|
||||
is referred to as an *orphan node* when it doesn belong to any cluster.
|
||||
|
||||
|
||||
Listing Nodes in a Cluster
|
||||
--------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Specify the Cluster When Creating a Node
|
||||
----------------------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Adding Node(s) to A Cluster
|
||||
--------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Removing Node(s) from a Cluster
|
||||
-------------------------------
|
||||
|
||||
(TBC)
|
|
@ -12,16 +12,54 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-nodes:
|
||||
|
||||
Nodes
|
||||
=====
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A node is a ...
|
||||
A :term:`Node` is a logical object managed by the Senlin service.
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Nodes
|
||||
-------------
|
||||
|
||||
[TBC]
|
||||
(TBC)
|
||||
|
||||
|
||||
Creating a Node
|
||||
---------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Updating a Node
|
||||
---------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Showing Details of a Node
|
||||
-------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
This includes the ``-details`` argument that shows the physical object
|
||||
details.
|
||||
|
||||
Deleting a Node
|
||||
---------------
|
||||
|
||||
(TBC)
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
Below are links to documents related to node management:
|
||||
|
||||
- :doc:`Managing Profile Objects <profiles>`
|
||||
- :doc:`Creating Clusters <clusters>`
|
||||
- :doc:`Managing Cluster Membership <membership>`
|
||||
- :doc:`Examining Actions <actions>`
|
||||
- :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -12,16 +12,51 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-policies:
|
||||
|
||||
Policies
|
||||
========
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A policy is a ...
|
||||
A :term:`Policy` is an object instantiated from a :term:`Policy Type`.
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Policies
|
||||
----------------
|
||||
|
||||
[TBC]
|
||||
(TBC)
|
||||
|
||||
|
||||
Creating a Policy
|
||||
-----------------
|
||||
|
||||
(TBC)
|
||||
|
||||
|
||||
Updating a Policy
|
||||
-----------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Showing the Details of a Policy
|
||||
-------------------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
Deleting a Policy
|
||||
-----------------
|
||||
|
||||
(TBC)
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
The list below provides links to documents related to the creation and usage
|
||||
of policy objects.
|
||||
|
||||
* :doc:`Working with Policy Types <policy_types>`
|
||||
* :doc:`Managing the Bindings between Clusters and Policies <bindings>`
|
||||
* :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -12,16 +12,37 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-policy-types:
|
||||
|
||||
Policy Types
|
||||
============
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A policy type is a ...
|
||||
A :term:`Policy Type` is an abstract specification of the rules to be checked
|
||||
and/or enforced when certain :term:`Action` is performed on a cluster that
|
||||
contains nodes of certain :term:`Profile Type`.
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Policy Types
|
||||
--------------------
|
||||
|
||||
[TBC]
|
||||
(TBC)
|
||||
|
||||
|
||||
Showing Policy Schema
|
||||
---------------------
|
||||
|
||||
(TBC)
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
Check the list below for documents related to the creation and usage of
|
||||
:term:`Policy` objects.
|
||||
|
||||
* :doc:`Creating Your Own Policy Objects <policies>`
|
||||
* :doc:`Managing the Binding between Cluster and Policy <bindings>`
|
||||
* :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _guide-profile-types:
|
||||
|
||||
Profile Types
|
||||
=============
|
||||
|
@ -18,35 +19,148 @@ Profile Types
|
|||
Basic Concept
|
||||
-------------
|
||||
|
||||
A Profile Type can be treated as a meta-type of a profile. A registry of
|
||||
profile typess is built in memory when Senlin engine is started. In future,
|
||||
Senlin will allow user to provide additional profile type implementations
|
||||
as plug-ins.
|
||||
A :term:`Profile Type` can be treated as the meta-type of a :term:`Profile`
|
||||
object. A registry of profile types is built in memory when Senlin engine
|
||||
(:program:`senlin-engine`) is started. In future, Senlin will allow users to
|
||||
provide additional profile type implementations as plug-ins to be loaded
|
||||
dynamically.
|
||||
|
||||
A profile type only dictates which fields are required. When a profile is
|
||||
created out of such a profile type, the fields are assigned with concrete
|
||||
values. For example, a profile type can be `aws.autoscaling.launchconfig`
|
||||
that conceptually specifies the properties required::
|
||||
A profile type implementation dictates which fields are required. When a
|
||||
profile is created by referencing this profile type, the fields are assigned
|
||||
with concrete values. For example, a profile type can be ``os.heat.stack``
|
||||
that conceptually specifies the properties required:
|
||||
|
||||
properties:
|
||||
UserData: string
|
||||
ImageId: string
|
||||
InstanceId: string
|
||||
KeyName: string
|
||||
InstanceType: string
|
||||
::
|
||||
|
||||
A profile of type `aws.autoscaling.launchconfig` may look like::
|
||||
context: Map
|
||||
template: Map
|
||||
parameters: Map
|
||||
files: Map
|
||||
timeout: Integer
|
||||
disable_rollback: Boolean
|
||||
environment: Map
|
||||
|
||||
# spec for aws.autoscaling.launchconfig
|
||||
UserData: |
|
||||
#!/bin/sh
|
||||
echo 'Script running'
|
||||
ImageId: 23
|
||||
KeyName: oskey
|
||||
InstanceType: m1.small
|
||||
A profile of type ``os.heat.stack`` may look like:
|
||||
|
||||
::
|
||||
|
||||
# a spec for os.heat.stack
|
||||
context:
|
||||
region_name: RegionOne
|
||||
template:
|
||||
heat_template_version: 2014-10-16
|
||||
parameters:
|
||||
length: Integer
|
||||
resources:
|
||||
rand:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
len: {get_param: length}
|
||||
outputs:
|
||||
rand_val:
|
||||
value: {get_attr: [rand, value]}
|
||||
parameters:
|
||||
length: 32
|
||||
files: {}
|
||||
timeout: 60
|
||||
disable_rollback: True
|
||||
environment: {}
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Listing Profile Types
|
||||
---------------------
|
||||
|
||||
(TBC)
|
||||
Senlin server comes with some built-in profile types. You can check the list
|
||||
of profile types using the following command::
|
||||
|
||||
$ senlin profile-type-list
|
||||
+----------------+
|
||||
| name |
|
||||
+----------------+
|
||||
| os.heat.stack |
|
||||
| os.nova.server |
|
||||
+----------------+
|
||||
|
||||
The output is a list of profile types supported by the Senlin server.
|
||||
|
||||
|
||||
Showing Profile Schema
|
||||
----------------------
|
||||
|
||||
Each :term:`Profile Type` has a schema for its *spec* (i.e. specification)
|
||||
that describes the names and the types of properties that can be accepted. To
|
||||
show the schema of a specific profile type, you can use the following
|
||||
command::
|
||||
|
||||
$ senlin profile-type-schema os.heat.stack
|
||||
profile_type: os.heat.stack
|
||||
spec:
|
||||
context:
|
||||
default: {}
|
||||
description: A dictionary for specifying the customized context for
|
||||
stack operations
|
||||
readonly: false
|
||||
required: false
|
||||
type: Map
|
||||
disable_rollback:
|
||||
default: true
|
||||
description: A boolean specifying whether a stack operation can be
|
||||
rolled back.
|
||||
readonly: false
|
||||
required: false
|
||||
type: Boolean
|
||||
<... omitted ...>
|
||||
timeout:
|
||||
description: A integer that specifies the number of minutes that a
|
||||
stack operation times out.
|
||||
readonly: false
|
||||
required: false
|
||||
type: Integer
|
||||
|
||||
Here, each property has the following attributes:
|
||||
|
||||
- ``default``: the default value for a property when not explicitly specified;
|
||||
- ``description``: a textual description of the use of a property;
|
||||
- ``readonly``: a boolean indicating whether a property is read only for
|
||||
reasons like being part of the outputs of an object;
|
||||
- ``required``: whether the property must be specified. Such kind of a
|
||||
property usually doesn't have a ``default`` value.
|
||||
- ``type``: one of ``String``, ``Integer``, ``Boolean``, ``Map`` or ``List``.
|
||||
|
||||
The default output from the :command:`profile-type-schema` command is in YAML
|
||||
format. You can choose to show the spec schema in JSON format by specifying
|
||||
the the :option:`-F json` option as exemplified below::
|
||||
|
||||
$ senlin profile-type-schema -F json os.heat.stack
|
||||
{
|
||||
"spec": {
|
||||
"files": {
|
||||
"default": {},
|
||||
"readonly": false,
|
||||
"required": false,
|
||||
"type": "Map",
|
||||
"description": "Contents of files referenced by the template, if any."
|
||||
},
|
||||
<... omitted ...>
|
||||
"context": {
|
||||
"default": {},
|
||||
"readonly": false,
|
||||
"required": false,
|
||||
"type": "Map",
|
||||
"description": "A dictionary for specifying the customized context for stack operations"
|
||||
}
|
||||
},
|
||||
"profile_type": "os.heat.stack"
|
||||
}
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
Below is a list of links to the documents related to profile types:
|
||||
|
||||
* :doc:`Managing Profile Objects <profiles>`
|
||||
* :doc:`Creating and Managing Clusters <clusters>`
|
||||
* :doc:`Creating and Managing Nodes <nodes>`
|
||||
* :doc:`Managing Cluster Membership <membership>`
|
||||
* :doc:`Browsing Events <events>`
|
||||
|
|
|
@ -12,35 +12,292 @@
|
|||
under the License.
|
||||
|
||||
|
||||
.. _guide-profiles:
|
||||
|
||||
Profiles
|
||||
========
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
||||
A profile is the mould used for creating nodes to be managed by Senlin.
|
||||
It can be seen as an instance of a :term:`Profile Type`, with a unique ID.
|
||||
A profile encodes the information needed for node creation into a property
|
||||
named `spec`. For example, below is a spec for the `os.heat.stack` profile
|
||||
type::
|
||||
A :term:`Profile` is the mould used for creating a :term:`Node` to be managed
|
||||
by the Senlin service. It can be treated as an instance of a
|
||||
:term:`Profile Type` with an unique ID. A profile encodes the information
|
||||
needed for node creation in a property named ``spec``.
|
||||
|
||||
# spec for os.heat.stack
|
||||
template: my_stack.yaml
|
||||
parameters:
|
||||
key_name: oskey
|
||||
environment:
|
||||
- env.yaml
|
||||
|
||||
The primary job for a profile's implementation is to translate user provided
|
||||
JSON data structure into information that can be consumed by a driver. A
|
||||
The primary job for a profile type implementation is to translate user provided
|
||||
JSON data structure into information that can be consumed by a driver. A
|
||||
driver will create/delete/update a physical object based on the information
|
||||
provided.
|
||||
|
||||
A profile as a `permission` string which defaults to an empty string at the
|
||||
moment. In future, it will be used for access authorization checking.
|
||||
|
||||
Listing Profiles
|
||||
----------------
|
||||
|
||||
To examine the list of profile objects supported by the Senlin engine, you can
|
||||
use the following command::
|
||||
|
||||
$ senlin profile-list
|
||||
+----------+----------+----------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+----------+----------+----------------+---------------------+
|
||||
| 560a8f9d | myserver | os.nova.server | 2015-05-05T13:26:00 |
|
||||
| ceda64bd | mystack | os.heat.stack | 2015-05-05T13:26:25 |
|
||||
| 9b127538 | pstack | os.heat.stack | 2015-06-25T12:59:01 |
|
||||
+----------+----------+----------------+---------------------+
|
||||
|
||||
Note that the first column in the output table is a *short ID* of a profile
|
||||
object. Senlin command line use short IDs to save real estate on screen so
|
||||
that more useful information can be shown on a single line. To show the *full
|
||||
ID* in the list, you can add the :option:`-F` (or :option:`--full-id`) option
|
||||
to the command::
|
||||
|
||||
$ senlin profile-list -F
|
||||
+--------------------------------------+----------+----------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+--------------------------------------+----------+----------------+---------------------+
|
||||
| 560a8f9d-7596-4a32-85e8-03645fa7be13 | myserver | os.nova.server | 2015-05-05T13:26:00 |
|
||||
| ceda64bd-70b7-4711-9526-77d5d51241c5 | mystack | os.heat.stack | 2015-05-05T13:26:25 |
|
||||
| 9b127538-a675-4271-ab9b-f24f54cfe173 | pstack | os.heat.stack | 2015-06-25T12:59:01 |
|
||||
+--------------------------------------+----------+----------------+---------------------+
|
||||
|
||||
By default, the command :command:`profile-list` filters out profile objects
|
||||
that have been soft deleted. However, you can add the option :option:`-d`
|
||||
(or :option:`--show-deleted`) to the command to indicate that soft-deleted
|
||||
profiles should be included in the list.
|
||||
|
||||
In case you have a huge collection of profile objects, you can limit the
|
||||
number of profiles returned from Senlin server, using the option :option:`-l
|
||||
<LIMIT>` (or :option:`--limit <LIMIT>`). For example::
|
||||
|
||||
$ senlin profile-list -l 1
|
||||
+----------+----------+----------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+----------+----------+----------------+---------------------+
|
||||
| 560a8f9d | myserver | os.nova.server | 2015-05-05T13:26:00 |
|
||||
+----------+----------+----------------+---------------------+
|
||||
|
||||
Yet another option you can specify is the ID of a profile object from which
|
||||
you want to see the list starts. In other words, you don't want to see those
|
||||
profiles with IDs that come before the one you specify. You can use the option
|
||||
:option:`-m <ID>` (or :option:`--marker <ID>` for this purpose. For example::
|
||||
|
||||
$ senlin profile-list -l 1 -m ceda64bd-70b7-4711-9526-77d5d51241c5
|
||||
+----------+--------+---------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+----------+--------+---------------+---------------------+
|
||||
| 9b127538 | pstack | os.heat.stack | 2015-06-25T12:59:01 |
|
||||
+----------+--------+---------------+---------------------+
|
||||
|
||||
|
||||
How To Use
|
||||
----------
|
||||
Creating a Profile
|
||||
------------------
|
||||
|
||||
(TBC)
|
||||
Before working with a :term:`Cluster` or a :term:`Node`, you will need a
|
||||
:term:`Profile` object created with a profile type. To create a profile, you
|
||||
will need a "spec" file in YAML format. For example, below is a simple spec
|
||||
for the ``os.heat.stack`` profile type (the source can be found in the
|
||||
:file:`examples/profiles/heat_stack_random_string.spec` file).
|
||||
|
||||
::
|
||||
|
||||
# spec for os.heat.stack
|
||||
name: random_string_stack
|
||||
template: random_string_stack.yaml
|
||||
environment:
|
||||
- env.yaml
|
||||
|
||||
The ``random_string_stack.yaml`` is the name of a Heat template file to be used
|
||||
for stack creation. The ``env.yaml`` is the name of an environment file to be
|
||||
passed to Heat for processing. It is given here only as an example. You can
|
||||
decide which properties to use based on your requirements.
|
||||
|
||||
Now you can create a profile using the following command::
|
||||
|
||||
$ cd /opt/stack/senlin/examples/profiles
|
||||
$ senlin profile-create -t os.heat.stack \
|
||||
-s heat_stack_random_string.spec my_stack
|
||||
+--------------+-------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+--------------+-------------------------------------------------------------------+
|
||||
| created_time | 2015-07-06T06:46:31 |
|
||||
| deleted_time | None |
|
||||
| id | bf38dc9f-d204-46c9-b515-79caf1e45c4d |
|
||||
| metadata | {} |
|
||||
| name | my_stack |
|
||||
| spec | +------------------+--------------------------------------------+ |
|
||||
| | | property | value | |
|
||||
| | +------------------+--------------------------------------------+ |
|
||||
| | | files | { | |
|
||||
| | | | "file:///cript.sh": "#!/bin/bash\n... | |
|
||||
| | | | } | |
|
||||
| | | disable_rollback | true | |
|
||||
| | | template | { | |
|
||||
| | | | "outputs": { | |
|
||||
| | | | "result": { | |
|
||||
| | | | "value": { | |
|
||||
| | | | "get_attr": [ | |
|
||||
| | | | "random", | |
|
||||
| | | | "value" | |
|
||||
| | | | ] | |
|
||||
| | | | } | |
|
||||
| | | | } | |
|
||||
| | | | }, | |
|
||||
| | | | "heat_template_version": "2014-10-16", | |
|
||||
| | | | "resources": { | |
|
||||
| | | | "random": { | |
|
||||
| | | | "type": "OS::Heat::RandomString", | |
|
||||
| | | | "properties": { | |
|
||||
| | | | "length": 64 | |
|
||||
| | | | } | |
|
||||
| | | | } | |
|
||||
| | | | }, | |
|
||||
| | | | "parameters": { | |
|
||||
| | | | "file": { | |
|
||||
| | | | "default": { | |
|
||||
| | | | "get_file": "file://test_script.sh"| |
|
||||
| | | | }, | |
|
||||
| | | | "type": "string" | |
|
||||
| | | | } | |
|
||||
| | | | } | |
|
||||
| | | | } | |
|
||||
| | | parameters | {} | |
|
||||
| | | timeout | 60 | |
|
||||
| | | environment | { | |
|
||||
| | | | "resource_registry": { | |
|
||||
| | | | "os.heat.server": "OS::Heat::Server" | |
|
||||
| | | | } | |
|
||||
| | | | } | |
|
||||
| | | context | {} | |
|
||||
| | +------------------+--------------------------------------------+ |
|
||||
| type | os.heat.stack |
|
||||
+--------------+-------------------------------------------------------------------+
|
||||
|
||||
From the outputs, you can see that the profile is created with a new ``id``
|
||||
generated. The ``spec`` property is dumped for the purpose of verification.
|
||||
|
||||
Optionally, you can attach some key-value pairs to the new profile when
|
||||
creating it. This data is referred to as the *metadata* for the profile::
|
||||
|
||||
$ senlin profile-create -t os.heat.stack \
|
||||
-s heat_stack_random_string.spec \
|
||||
-d author=Tom;version=1.0 \
|
||||
my_stack
|
||||
|
||||
|
||||
Showing the Details of a Profile
|
||||
--------------------------------
|
||||
|
||||
Once there are profile objects in Senlin database, you can use the following
|
||||
command to show the properties of a profile::
|
||||
|
||||
$ senlin profile-show myserver
|
||||
+--------------+--------------------------------------------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+--------------+--------------------------------------------------------------------------------------------------------+
|
||||
| created_time | 2015-05-05T13:26:00 |
|
||||
| deleted_time | None |
|
||||
| id | 560a8f9d-7596-4a32-85e8-03645fa7be13 |
|
||||
| metadata | {} |
|
||||
| name | myserver |
|
||||
| permission | |
|
||||
| spec | {u'key_name': u'qmkey', u'flavor': 1, u'image': u'cirros-0.3.2-x86_64-uec', u'name': u'cirros_server'} |
|
||||
| type | os.nova.server |
|
||||
+--------------+--------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Note that :program:`senlin` command line accepts one of the following values
|
||||
when retrieving a profile object:
|
||||
|
||||
- name: the name of a profile;
|
||||
- ID: the UUID of a profile;
|
||||
- short ID: an "abbreviated version" of the profile UUID.
|
||||
|
||||
Since Senlin doesn't require a profile name to be unique, specifying profile
|
||||
name for the :command:`profile-show` command won't guarantee that a profile
|
||||
object is returned. You may get a ``MultipleChoices`` exception if more than
|
||||
one profile object match the name.
|
||||
|
||||
As another option, when retrieving a profile (or in fact any other objects,
|
||||
e.g. a cluster, a node, a policy etc.), you can specify the leading sub-string
|
||||
of an UUID as the "short ID" for query. For example::
|
||||
|
||||
$ senlin profile-show 560a8f9d
|
||||
+----------+----------+----------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+----------+----------+----------------+---------------------+
|
||||
| 560a8f9d | myserver | os.nova.server | 2015-05-05T13:26:00 |
|
||||
+----------+----------+----------------+---------------------+
|
||||
$ senlin profile-show 560a
|
||||
+----------+----------+----------------+---------------------+
|
||||
| id | name | type | created_time |
|
||||
+----------+----------+----------------+---------------------+
|
||||
| 560a8f9d | myserver | os.nova.server | 2015-05-05T13:26:00 |
|
||||
+----------+----------+----------------+---------------------+
|
||||
|
||||
As with query by name, a "short ID" won't guarantee that a profile object is
|
||||
returned even if it does exist. When there are more than one object matching
|
||||
the short ID, you will get a ``MultipleChoices`` exception.
|
||||
|
||||
|
||||
Updating a Profile
|
||||
------------------
|
||||
|
||||
In general, a profile object should not be updated after creation. This is a
|
||||
restriction to keep cluster and node status consistent at any time. However,
|
||||
considering that there are cases where a user may want to change some
|
||||
properties of a profile, :program:`senlin` command line does support the
|
||||
:command:`profile-update` command. For example, the folowing command changes
|
||||
the name of a profile to ``new_server``::
|
||||
|
||||
$ senlin profile-update -n new_server -t os.nova.server myserver
|
||||
|
||||
The following command creates or updates the metadata associated with the given
|
||||
profile::
|
||||
|
||||
$ senlin profile-update -d version=2.2 -t os.nova.server myserver
|
||||
|
||||
**NOTE**: The option :option:`-t <profile_type>` will be removed in future.
|
||||
|
||||
Changing the "spec" of a profile is not allowed, but you still can specify a
|
||||
new spec file for use in the :command:`profile-update` command::
|
||||
|
||||
$ senlin profile-update -s new_specfile.spec -t os.nova.server myserver
|
||||
|
||||
The result of this update command is that a new profile will be created. The
|
||||
new profile will have the same profile name, but a different ``spec`` property
|
||||
and a new ``id``.
|
||||
|
||||
**NOTE**: This behavior is subject to change in future.
|
||||
|
||||
|
||||
Deleting a Profile
|
||||
------------------
|
||||
|
||||
When there are no clusters or nodes referencing a profile object, you can
|
||||
delete it from the Senlin database using the following command::
|
||||
|
||||
$ senlin profile-delete myserver
|
||||
|
||||
Note that in this command you can use the name, the ID or the "short ID" to
|
||||
specify the profile object you want to delete. If the specified criteria
|
||||
cannot match any profiles, you will get a ``ProfileNotFound`` exception.
|
||||
If more than one profile matches the criteria, you will get a
|
||||
``MultipleChoices`` exception. For example::
|
||||
|
||||
$ senlin profile-delete my
|
||||
ERROR(404): The profile (my) could not be found.
|
||||
Failed to delete any of the specified profile(s).
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
The following is a list of the links to documents related to profile's
|
||||
creation and usage:
|
||||
|
||||
- :doc:`Working with Profile Types <profile_types>`
|
||||
- :doc:`Creating and Managing Clusters <clusters>`
|
||||
- :doc:`Creating and Managing Nodes <nodes>`
|
||||
- :doc:`Managing Cluster Membership <membership>`
|
||||
- :doc:`Examinging Actions <actions>`
|
||||
- :doc:`Browing Events <events>`
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _guide-webhooks:
|
||||
|
||||
Webhook
|
||||
=======
|
||||
|
||||
Webhook is used to trigger a specific action on a senlin entity, for instance
|
||||
the actions that change the size of a specified cluster.
|
||||
A :term:`Webhook` is used to trigger a specific :term:`Action` on a senlin
|
||||
object, for instance the actions that change the size of a specified cluster.
|
||||
|
||||
How to use
|
||||
----------
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
..
|
||||
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
|
||||
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.
|
||||
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.
|
||||
|
||||
==========
|
||||
Glossary
|
||||
==========
|
||||
|
||||
========
|
||||
Glossary
|
||||
========
|
||||
|
||||
This section contains the glossary for the Senlin service.
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
|
@ -59,6 +59,7 @@ Man Pages
|
|||
|
||||
Developers Documentation
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
|
|
Loading…
Reference in New Issue