~ya-bo-ng/juju-gui/bottom-bar-removed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
.. Run "make view-main-doc" to render this file and read it in the browser
   alongside the whole project documentation. To do this, you need the
   dependencies described in the "Documentation" section below.

=======
HACKING
=======

Here is how to develop on this codebase.

Developer Install
=================

Before you get the GUI, first you need to get Juju.  For PyJuju, the original
Python-based implementation, we use a custom branch of Juju that supplies the
websocket API we need.  (GoJuju, the newer Go-based implementation, will have
a websocket API provided for us directly as part of the software.)

::

  sudo apt-get install juju zookeeper

Next you will also need to get the Juju branch that has API access.
Currently that work resides in a pipeline of Juju branches. The
recommended branch to use as a server is ``rapi-rollup`` by hazmat::

  bzr branch lp:~hazmat/juju/rapi-rollup

For development, we always use a nice testing script in that branch that
allows you to interact with Juju without actually deploying real machines.  In
the rapi-rollup branch, run ``python improv.py -h`` to get an idea of its
capabilities.  Note that your Python needs Twisted and Zookeeper installed,
but the ``sudo apt-get install juju zookeeper`` command above should have
already taken care of that for you.

Go ahead and use the branch's ``sample.json`` file to pre-populate the
environment.  In the future, you might want to investigate the ``large.json``
also available there.

::

  python improv.py -f sample.json

Now it is time to actually get the GUI itself set up.  Juju GUI uses nodejs-
based development tools, so you will need ``nodejs`` and ``npm`` from Chris
Lea's node PPA. You also need ImageMagick for sprite generation, lbox to
propose branches, python-sphinx and python-yaml to build docs, PyTZ to make
releases, and python-virtualenv to build the Google Closure linter tools
locally::

  sudo add-apt-repository ppa:chris-lea/node.js
  sudo apt-get update
  sudo apt-get install nodejs npm imagemagick lbox python-sphinx python-yaml python-tz python-virtualenv

The jshint linter will be installed locally per branch, but if you want editor
integration, you may want to install ``jshint`` globally in your system.  More
importantly, to support testing from the command line, phantomjs and mocha-
phantomjs should be installed globally.

::

  sudo npm install -g jshint mocha-phantomjs phantomjs

If you receive an error installing phantomjs, you can manually download and
unpack the archive and then arrange for the "phantomjs" executable to be
located on your path (e.g., by linking it into ``~/bin``).

The Juju GUI can now be installed and run with::

  bzr branch lp:juju-gui trunk
  cd trunk
  make devel

It may take a while for the server to start the first time as npm will
need to download packages.  When ready, the server will print::

  Server listening on 8888

You can then access the GUI at <http://localhost:8888/>.

Note that the Makefile supports ``make help`` to try to introduce some of the
more important targets.  Also note that if you use the "make prod" target
while using the PyJuju rapi-rollup improv script, the password you should use
is "admin," despite the help text you see.

Working with a Real Juju
========================

The easiest way to work with a real Juju installation, as opposed to the
"improv" script described above, is to use the Juju charm.  See
<http://jujucharms.com/~juju-gui/precise/juju-gui> or
<http://jujucharms.com/charms/precise/juju-gui> for details.

Alternatively, you can try the instructions below, but be warned that they
have bit-rotted and we have not felt the need to update them.  If you get them
to work, please update the docs and submit a branch for review (see below).

Bit-Rotted Instructions
-----------------------

You can use the GUI with any environment, but for development purposes, a
local environment works well. One environment option specific to this branch
is the ``api-port``. An appropriate sample configuration::

  default: dev
  environments:
    dev:
      type: local
      data-dir: /home/kapil/.juju/local
      admin-secret: b3a5dee4fb8c4fc9a4db04751e5936f4
      default-series: precise
      juju-origin: ppa
      api-port: 8081

Note that ``juju-origin`` is set to the PPA, the API server runs outside of
the container, and it is launched using whichever branch you are using.

Also note that the ``api-port`` should be set at 8081, which the GUI's
initial environment connection currently defaults to.

You will need to bootstrap the local environment, and deploy one service.
The API server needs access to the provisioning credentials which are
lazily initialized in Juju upon usage.

``Juju-gui`` and ``rapi-rollup`` can communicate via an encrypted WebSocket
connection: to enable it, add the following line to the config above::

  api-secure: true

You will also need to edit ``app/config-debug.js`` and ``app/config-prod.js``
replacing ``ws://localhost:8081/ws`` with ``wss://localhost:8081/ws``.

By default, ``rapi-rollup`` uses a self-signed certificate; because of that you
will need to visit the <https://localhost:8081/ws> WebSocket URL with your
browser and accept the included self-signed certificate, or the WebSocket
encrypted connection will not work.

In order to use a different certificate you add an ``api-keys`` option to the
config above: its value will be the path of the directory containing the
certificate and the private key, whose filenames will have to be respectively
``juju.crt`` and ``juju.key``.

After this, the GUI should be functional (it automatically polls the
API server for establishing a websocket).

Running Unit Tests
==================

``make test-prod`` or ``make test-debug`` will run the CLI based test
runner. If you need to debug a test in the browser, use ``make test-server``.

Running Lint
============

Run the linters with ``make lint``.  ``make beautify`` will use the Google
Closure tools to try and force the code to conform to some of the guidelines,
with variable success.  It can help, but we suggest you first commit your code
to your branch and only then run make beautify, so you can easily see and
evaluate the changes it made.

If you have done a large refactoring and the yuidoc linter complains about a
lot of code that no longer exists or has been moved or renamed, note that
``make undocumented`` can reproduce the undocumented file so as to quiet the
linter. If you need to do this, please make sure that the length (``wc -l``)
of the new "undocumented" file is the same or smaller than it was before.

.. _all-docs:

Documentation
=============

The ``make docs`` command generates the code and the project documentation
together.

Code Documentation
------------------

Generated documentation for the JavaScript code is available in the ``yuidoc``
directory.  You can build and view the docs by running::

  make yuidoc
  xdg-open yuidoc/index.html

See the :ref:`style guide <embedded-docs>` document for details on how to
write the embedded documentation.

Project Documentation
---------------------

The project documentation is available in the ``docs/`` directory. As already
mentioned in the developer installation instructions above, it needs Sphinx
and Python-yaml.  To build and view the documentation, use these commands::

  make sphinx
  xdg-open docs/_build/html/index.html

Filing Bugs
===========

Please file bugs here:

https://bugs.launchpad.net/juju-gui/+filebug

Proposing Branches
==================

We use ``lbox`` to propose branches for review and submit them to the trunk.
Gustavo Niemeyer has `a helpful blogpost`_ about this tool.  See the process
document :ref:`(docs/process.rst) <preparing-reviews>` for a step-by-step
checklist on how to prepare branches for review.

.. _`a helpful blogpost`:
    http://blog.labix.org/2011/11/17/launchpad-rietveld-happycodereviews

Making Targets Quickly Without Bazaar
=====================================

Within a checkout, a lightweight checkout, or a branch, you may run make as
``NO_BZR=1 make [target]`` in order to prevent the Makefile from running any
Bazaar commands, all of which access the parent branch over the network. Where
Bazaar may have provided information such as the revno, sensible defaults are
used instead.  Because many of these Bazaar commands are used to populate
variables regardless of the target, defining NO_BZR will have an effect on all
targets, except ``dist``, which will refuse to complete.

Note that this allows one to run any make target from the working copy, even
if it is a lightweight checkout, by skipping steps that involve network access
through Bazaar.  Because of this, make will assume that the revno is
0 and that the branch is clean and up to date without checking that it is a
checkout of trunk.  The resulting tarball or build may be used to test
releases by hand or in the charm.

Making Releases
===============

See the Process document :ref:`(docs/process.rst) <make-releases>` for step-
by-step checklists to make developer and stable releases.  The following is
additional detail and an overview.

To make a release, you must either be in a checkout of ``lp:juju-gui``
without uncommitted changes, or you must override one of the
`pertinent variable names`_ to force a release.

.. _`pertinent variable names`:
    `Potentially Useful Release-Oriented Makefile Variables`_

To make the release tarball use ``make distfile``.

In order to make and upload the release (``make dist``), you also need to have
a GPG key, and the ``python-pytz`` package installed (as well as
``launchpadlib``, but that is installed by default in Ubuntu).

Potentially Useful Release-Oriented Makefile Variables
------------------------------------------------------

The following is a list of pertinent Makefile variables.

``FINAL``
  Set ``FINAL`` to any non-empty value to make a final release. This will cause
  the ``bzr revno`` to be omitted from the tarball name, and (if you use the
  release target) will cause the release to be uploaded to the stable series
  rather than the trunk series. Example usage::

    FINAL=1 make dist

``PROD``
  By default, releases will be uploaded to ``staging.launchpad.net``, which is
  a separate version of Launchpad that uses a temporary database.  This can be
  convenient for trying out the release process in the Makefile without
  affecting our actual production releases.  Set ``PROD`` to any non-empty
  value to send uploads to ``launchpad.net``, the production version of
  Launchpad, when you are ready to make a real release.

  Note that you may need to ask the webops to turn off the two-factor
  authentication on your Launchpad staging account in order for the staging to
  work. Go to the ``#launchpad-ops`` channel on the Canonical IRC server and
  ask something like "webops, could you disable 2FA on my staging account?".

  Example usage::

    PROD=1 make dist

``IS_TRUNK_BRANCH``
  Set this to any non-empty value to force the Makefile to believe it is
  working with a trunk checkout. Example usage::

    IS_TRUNK_BRANCH=1 make dist

``BRANCH_IS_CLEAN``
  Set this to any non-empty value to force the Makefile to believe that the
  current code tree has no changes. Example usage::

    BRANCH_IS_CLEAN=1 make dist

``BRANCH_IS_GOOD``
  Set this to any non-empty value to force the Makefile to bypass checks of
  ``IS_TRUNK_BRANCH`` and ``BRANCH_IS_CLEAN``. Example usage::

    BRANCH_IS_GOOD=1 make dist