4d32b1fbe9
* Also fixes part of the example which showed having a custom permission that could not exist in the way that django_openstack_auth's keystone backend was implemented. Change-Id: I46e748302d34f82648ef6690e2d5db4618487a6a Closes-Bug: #1605842
326 lines
9.8 KiB
ReStructuredText
326 lines
9.8 KiB
ReStructuredText
.. _quickstart:
|
|
|
|
==========
|
|
Quickstart
|
|
==========
|
|
|
|
.. Note ::
|
|
|
|
This section has been tested for Horizon on Ubuntu (16.04-64) and RPM-based
|
|
(RHEL 7.x) distributions. Feel free to add notes and any changes according
|
|
to your experiences or operating system.
|
|
|
|
Linux Systems
|
|
=============
|
|
|
|
Install the prerequisite packages.
|
|
|
|
On Ubuntu
|
|
|
|
.. code-block:: console
|
|
|
|
$ sudo apt-get install git python-pip
|
|
|
|
On RPM-based distributions (e.g., Fedora/RHEL/CentOS/Scientific Linux)
|
|
|
|
.. code-block:: console
|
|
|
|
$ sudo yum install gcc git-core python-devel python-virtualenv openssl-devel libffi-devel which
|
|
|
|
.. note::
|
|
|
|
Some tests rely on the Chrome web browser being installed. While the above
|
|
requirements will allow you to run and manually test Horizon, you will
|
|
need to install Chrome to run the full test suite.
|
|
|
|
Setup
|
|
=====
|
|
|
|
To begin setting up a Horizon development environment simply clone the Horizon
|
|
git repository from https://git.openstack.org/cgit/openstack/horizon
|
|
|
|
.. code-block:: console
|
|
|
|
$ git clone https://git.openstack.org/openstack/horizon
|
|
|
|
Next you will need to configure Horizon by adding a ``local_settings.py`` file.
|
|
A good starting point is to use the example config with the following command,
|
|
from within the ``horizon`` directory.
|
|
|
|
.. code-block:: console
|
|
|
|
$ cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
|
|
|
|
Horizon connects to the rest of OpenStack via a Keystone service catalog. By
|
|
default Horizon looks for an endpoint at ``http://localhost:5000/v2.0``; this
|
|
can be customised by modifying the ``OPENSTACK_HOST`` and
|
|
``OPENSTACK_KEYSTONE_URL`` values in
|
|
``openstack_dashboard/local/local_settings.py``
|
|
|
|
.. note::
|
|
|
|
The DevStack project (http://devstack.org/) can be used to install
|
|
an OpenStack development environment from scratch. For a local.conf that
|
|
enables most services that Horizon supports managing, see
|
|
:ref:`local-conf`
|
|
|
|
Horizon uses ``tox`` to manage virtual environments for testing and other
|
|
development tasks. You can install it with
|
|
|
|
.. code-block:: console
|
|
|
|
$ pip install tox
|
|
|
|
The ``tox`` environments provide wrappers around ``manage.py``. For more
|
|
information on ``manage.py``, which is a Django command, see
|
|
https://docs.djangoproject.com/en/dev/ref/django-admin/
|
|
|
|
To start the Horizon development server use the command below
|
|
|
|
.. code-block:: console
|
|
|
|
$ tox -e runserver
|
|
|
|
.. note::
|
|
|
|
The default port for runserver is 8000 which is already consumed by
|
|
heat-api-cfn in DevStack. If running in DevStack
|
|
``tox -e runserver -- localhost:9000`` will start the test server at
|
|
``http://localhost:9000``
|
|
|
|
Once the Horizon server is running, point a web browser to ``http://localhost``
|
|
or to the IP and port the server is listening for. Enter your Keystone
|
|
credentials, log in and you'll be presented with the Horizon dashboard.
|
|
Congratulations!
|
|
|
|
Managing Settings
|
|
=================
|
|
|
|
You can save changes you made to
|
|
``openstack_dashboard/local/local_settings.py`` with the following command:
|
|
|
|
.. code-block:: console
|
|
|
|
$ python manage.py migrate_settings --gendiff
|
|
|
|
.. note::
|
|
|
|
This creates a ``local_settings.diff`` file which is a diff between
|
|
``local_settings.py`` and ``local_settings.py.example``
|
|
|
|
If you upgrade Horizon, you might need to update your
|
|
``openstack_dashboard/local/local_settings.py`` file with new parameters from
|
|
``openstack_dashboard/local/local_settings.py.example`` to do so, first update
|
|
Horizon
|
|
|
|
.. code-block:: console
|
|
|
|
$ git remote update && git pull --ff-only origin master
|
|
|
|
Then update your ``openstack_dashboard/local/local_settings.py`` file
|
|
|
|
.. code-block:: console
|
|
|
|
$ mv openstack_dashboard/local/local_settings.py openstack_dashboard/local/local_settings.py.old
|
|
$ python manage.py migrate_settings
|
|
|
|
.. note::
|
|
|
|
This applies ``openstack_dashboard/local/local_settings.diff`` on
|
|
``openstack_dashboard/local/local_settings.py.example`` to regenerate an
|
|
``openstack_dashboard/local/local_settings.py`` file.
|
|
The migration can sometimes have difficulties to migrate some settings, if
|
|
this happens you will be warned with a conflict message pointing to an
|
|
``openstack_dashboard/local/local_settings.py_Some_DateTime.rej`` file.
|
|
In this file, you will see the lines which could not be automatically
|
|
changed and you will have to redo only these few changes manually instead
|
|
of modifying the full
|
|
``openstack_dashboard/local/local_settings.py.example`` file.
|
|
|
|
When all settings have been migrated, it is safe to regenerate a clean diff in
|
|
order to prevent Conflicts for future migrations
|
|
|
|
.. code-block:: console
|
|
|
|
$ mv openstack_dashboard/local/local_settings.diff openstack_dashboard/local/local_settings.diff.old
|
|
$ python manage.py migrate_settings --gendiff
|
|
|
|
Editing Horizon's Source
|
|
========================
|
|
|
|
Although DevStack installs and configures an instance of Horizon when running
|
|
stack.sh, the preferred development setup follows the instructions above on the
|
|
server/VM running DevStack. There are several advantages to maintaining a
|
|
separate copy of the Horizon repo, rather than editing the DevStack installed
|
|
copy.
|
|
|
|
- Source code changes aren't as easily lost when running ``unstack.sh`` /
|
|
``stack.sh``
|
|
- The development server picks up source code changes while still running.
|
|
- Log messages and print statements go directly to the console.
|
|
- Debugging with ``pdb`` becomes much simpler to interact with.
|
|
|
|
.. note::
|
|
|
|
To ensure that JS and CSS changes are picked up without a server restart, you
|
|
can disable compression with ``COMPRESS_ENABLED = False`` in your local
|
|
settings file.
|
|
|
|
Horizon's Structure
|
|
===================
|
|
|
|
This project is a bit different from other OpenStack projects in that it has
|
|
two very distinct components underneath it: ``horizon``, and
|
|
``openstack_dashboard``.
|
|
|
|
The ``horizon`` directory holds the generic libraries and components that can
|
|
be used in any Django project.
|
|
|
|
The ``openstack_dashboard`` directory contains a reference Django project that
|
|
uses ``horizon``.
|
|
|
|
For development, both pieces share an environment which (by default) is
|
|
built with the ``tools/install_venv.py`` script. That script creates a
|
|
virtualenv and installs all the necessary packages.
|
|
|
|
If dependencies are added to either ``horizon`` or ``openstack_dashboard``,
|
|
they should be added to ``requirements.txt``.
|
|
|
|
Project Structure
|
|
=================
|
|
|
|
Dashboard configuration
|
|
-----------------------
|
|
|
|
To add a new dashboard to your project, you need to add a configuration file to
|
|
``openstack_dashboard/local/enabled`` directory. For more information on this,
|
|
see :ref:`pluggable-settings-label`.
|
|
|
|
URLs
|
|
----
|
|
|
|
Then you add a single line to your project's ``urls.py``
|
|
|
|
.. code-block:: python
|
|
|
|
url(r'', include(horizon.urls)),
|
|
|
|
Those urls are automatically constructed based on the registered Horizon apps.
|
|
If a different URL structure is desired it can be constructed by hand.
|
|
|
|
Templates
|
|
---------
|
|
|
|
Pre-built template tags generate navigation. In your ``nav.html``
|
|
template you might have the following
|
|
|
|
.. code-block:: htmldjango
|
|
|
|
{% load horizon %}
|
|
|
|
<div class='nav'>
|
|
{% horizon_main_nav %}
|
|
</div>
|
|
|
|
And in your ``sidebar.html`` you might have
|
|
|
|
.. code-block:: htmldjango
|
|
|
|
{% load horizon %}
|
|
|
|
<div class='sidebar'>
|
|
{% horizon_dashboard_nav %}
|
|
</div>
|
|
|
|
These template tags are aware of the current "active" dashboard and panel
|
|
via template context variables and will render accordingly.
|
|
|
|
Application Design
|
|
==================
|
|
|
|
Structure
|
|
---------
|
|
|
|
An application would have the following structure (we'll use project as
|
|
an example)
|
|
|
|
.. code-block:: console
|
|
|
|
project/
|
|
|---__init__.py
|
|
|---dashboard.py <-----Registers the app with Horizon and sets dashboard properties
|
|
|---overview/
|
|
|---images/
|
|
|-- images
|
|
|-- __init__.py
|
|
|---panel.py <-----Registers the panel in the app and defines panel properties
|
|
|-- snapshots/
|
|
|-- templates/
|
|
|-- tests.py
|
|
|-- urls.py
|
|
|-- views.py
|
|
...
|
|
...
|
|
|
|
Dashboard Classes
|
|
-----------------
|
|
|
|
Inside of ``dashboard.py`` you would have a class definition and the
|
|
registration process
|
|
|
|
.. code-block:: python
|
|
|
|
import horizon
|
|
|
|
....
|
|
# ObjectStorePanels is an example for a PanelGroup
|
|
# for panel classes in general, see below
|
|
class ObjectStorePanels(horizon.PanelGroup):
|
|
slug = "object_store"
|
|
name = _("Object Store")
|
|
panels = ('containers',)
|
|
|
|
|
|
class Project(horizon.Dashboard):
|
|
name = _("Project") # Appears in navigation
|
|
slug = "project" # Appears in URL
|
|
# panels may be strings or refer to classes, such as
|
|
# ObjectStorePanels
|
|
panels = (BasePanels, NetworkPanels, ObjectStorePanels)
|
|
default_panel = 'overview'
|
|
...
|
|
|
|
horizon.register(Project)
|
|
|
|
Panel Classes
|
|
-------------
|
|
|
|
To connect a :class:`~horizon.Panel` with a :class:`~horizon.Dashboard` class
|
|
you register it in a ``panel.py`` file
|
|
|
|
.. code-block:: python
|
|
|
|
import horizon
|
|
|
|
from openstack_dashboard.dashboards.project import dashboard
|
|
|
|
|
|
class Images(horizon.Panel):
|
|
name = "Images"
|
|
slug = 'images'
|
|
permissions = ('openstack.roles.admin', 'openstack.service.image')
|
|
policy_rules = (('endpoint', 'endpoint:rule'),)
|
|
|
|
# You could also register your panel with another application's dashboard
|
|
dashboard.Project.register(Images)
|
|
|
|
By default a :class:`~horizon.Panel` class looks for a ``urls.py`` file in the
|
|
same directory as ``panel.py`` to include in the rollup of url patterns from
|
|
panels to dashboards to Horizon, resulting in a wholly extensible, configurable
|
|
URL structure.
|
|
|
|
Policy rules are defined in ``horizon/openstack_dashboard/conf/``. Permissions
|
|
are inherited from Keystone and take either the form
|
|
'openstack.roles.role_name' or 'openstack.services.service_name' for the user's
|
|
roles in keystone and the services in their service catalog.
|