This is a single large PR adding all the current build/install/run scripting
support. There are a few noteworthy caveats:
1) The primary build script (build_release.py) is an interim python script.
The intent is to replace this with a gradle build.
2) The main installation script (install_spinnaker.py) pulls the artifacts
from a directory or storage bucket (e.g. S3 or GCS). The expectation is
to run apt-get install spinnaker instead where the spinnaker debian package
does similar things but with more standard packaging.
3) There are a pair of scripts to install a development environment on a
machine (install_development.py) and set one up for a user
(bootstrap_dev.sh). This too is interim and should become
an apt-get install spinnaker-dev debian package.
4) There is a script to build a Google Image. It uses packer so should be
easy to add AMIs and other platform image support. In the end, it uses
the install script, which is independent of platform anyway.
5) There are runtime scripts for managing an instance (start/stop).
The validate script is minimal at the moment. I'll add rules back
in future PRs. For now it is representative. The reconfigure script
is intended to add customizations into the settings.js that have to be
static.
6) The pylib/yaml directory is a copy of the standard python YAML library
that is not included by default. It is here to avoid complexity managing
python libraries (since pip is not installed by default either) when
there is no other need for python here.
The dev/ directory is only intended for developers (stuff available in the
spinnaker-dev packaging). The others are intended for operational runtime
environments.
The scripts support running a standard installation (in the runtime directory)
or as a developer (straight out of gradle). The developer scripts are
generally separate so they can inject a different configuration for where
to locate components.
Minimal usage as a developer[*] would be:
mkdir build
cd build
../spinnaker/dev/refresh_source.sh --github_user=<user> --pull_origin
../spinnaker/dev/run_dev.sh (will build and run as a developer)
[*] Assuming you already have a machine setup.
If you dont then you could run
spinnaker/dev/install_development.py (to set up a machine)
spinnaker/dev/bootstrap_dev.sh (to setup user environments)
The bootstrap_dev.sh will create the build directory and refresh the sources
leaving you in ./build.
To use this in a production environment, you'd need to build a release.
RELEASE_PATH=<path or storage bucket>
../spinnaker/dev/refresh_source.sh --pull_origin
../spinnaker/dev/build_release --release_path=$RELEASE_PATH
That will create and write to the RELEASE_PATH and also a
install_spinnaker.py.zip file. You can then copy that .py.zip onto
the machine you want ot install spinnaker on, then
python install_spinnaker.py.zip \
--package_manager \
--release_path=$RELEASE_PATH
To complete the installation create a /root/.spinnaker/spinnaker-local.yml
file (from /opt/spinnaker/config/default-spinnaker-local.yml) and fine tune
it with your credentials and so forth. Be sure to enable a provider and
set credentials.
Then start spinnaker
sudo /opt/spinnaker/scripts/start_spinnaker.sh
These files are intended to be installed at the base of a spring config path.
The default-spinnaker-local.yml is intended to be copied into a
spinnaker-local.yml and modified for a custom deployment. The other files can
be modified as <subsystem>-local.yml as well if needed.
This PR is more about the structure and policy than the details though I
would like to get the basic namespace right. I'm primarily using "services"
but maybe this should be "spinnaker".
The spinnaker.yml file contains the system wide policy and values shared among
multiple systems. The individual system files contain the particular
configuration for a given subsystem. The namespace in the spinnaker.yml is
intentionally disjoint from those in the individual system files requiring
the systems to explicitly document their configuration -- both how it is
standard (by referencing spinnaker.yml values) and how it is non-standard
(by not referencing spinnaker.yml values).
There are future CLs that add more scripting and support of this but
fundamentally using this assumes setting the spring.config.location system
property to something like
$INSTALL/config/spinnaker.yml,\
$INSTALL/config/,\
$HOME/.spinnaker/spinnaker-local.yml,\
$HOME/.spinnaker/
Recently the module spring loader was changed to look for 'spinnaker.yml'
so the config location would be $INSTALL/config,$HOME/.spinnaker/
If the subsystems config yaml files in this PR were moved into the subsystems
themselves, then the spring location could remain the default $HOME/.spinnaker/
With this approach, users typically ovewrite a single spinnaker-local.yml file
for most needs. The spring expression language cannot handle "subtrees", only
values. Therefore configuration of repeated nodes requires overriding the
<subsystem>-local.yml in order to add the lists in. Otherwise, the
spinnaker.yml defines "primary" values and the <subsystem_local.yml provide
a list containing the "primary" value so that the spinnaker-local.yml can
still serve as a central configuration.
Deck is a different story.
I'm including a "settings.js" here as a placeholder. This is what I actively
use, but it is out of date from chris' current work. The only "interesting"
thing here is the use of variable declarations that reference the
spinnaker.yml namespace. There is a script (in a future CL) that can
substitute that block with current config values. For purposes of this CL,
the details of settings.js can be changed later without worry. It's the
policy of calling out key configuration variables that may be needed and
resolving them with a script (I'll provide later) that is of interest for
this PR.
CAVEAT:
I've been having trouble getting AWS to work.
I can get it to work using root credentials when I run out of debian packages
(on GCE) and use environment variables (with a launch script that sets them
based on the YAML file) but the same strategy does not work for gradlew runs.
The gradle runs complain that it does not know about the "default profile".
I can run out of gradle if I have an .aws/config [sic] file (e.g. from an
awscli). I can run the debian packages with an .aws/credentials file.
It seems user credentials need more attributes in clouddriver. For example a
role. However roles are not valid with root credentials and a null role is
not valid either, so it seems clouddriver-local.yml may have to exist for
maintaining aws credentials.
spinnaker.yml is now built into the components to look for which
caused a conflict with injecting this resulting in files loaded
out of order.
Also modified refresh sources to monitor output rather than batching
them to avoid potential deadlock on large changes.
If credentials are provided in spinnaker-local.yml then set environment variables
Support transferring of an .aws/credentials file elsewhere.
Net effect is that you can use an .aws/credentials file for standard AWS
usage, but if you want to set environment variables, you can use the YML file
for that.
Also, when copying files [in create_dev] always chmod their permissions.
Propagate aws access/secret key to clouddriver
Added services.default.primaryAccountName to spinnaker.yml as a single place
to update the default account to use. This avoids spreading the choice between
aws and google throughout and localizing it to one easy-to-find place.
Added docker and dockerRegistry to spinnaker-local.
Use baseUrl for docker and jenkins to simplify local yaml
Moved "server.jenkins" fields into "server.jenkins.defaultMaster"
to clarify that it's just a single instance. Added comments throughout
where multiple values are possible but require editing the -local.yml directly.
This is a spring config limitation.
Propagate echo.enabled
Fixed settings.js syntax.
Set vpcMigrator: false
When generating deck's start_dev, put a guard around installing npm
every time. This speeds startup significantly.
Dont stop_deck when restarting all.
This is intended to work out of the box.
Except that the providers are disabled by default.
So there needs to be platform-level installation to turn on the appropriate
platform (where credentials are implicit).
This requires reconfigure to inject the yaml settings into the javascript file.
To make this more manageable and clearer, there is a variable block at the
top of the file that is used to inject the bindings. The downside is that
this requires the variables be explicitly called out. The upside is that
the file maintains its integrity and can be regenerated.
Removed the hack from the gradle scripts, but clouddriver does not yet
start using the new configuration on gradle (but everything does work
on the production install).
The yaml library isnt included in standard python distributions, at
least not on OS-X. pip isnt necessarily available either (it isnt on OS-X)
Rather than introducing complexity in having to install pip (and needing root
to do that) we're going to include the yaml library in here, at least for now
to keep consumption of the scripts friction-free.
Add support to install/start/run with new config.
Brings up spinnaker in prod, assuming the /opt files have added
the spring.config.location
Add config/ to spring path in production and gradle
For this to work in dev, you need to say
../spinnaker/google/dev/refresh_sources.sh --nobuild --hack_gradle
from the build directory to change the spring path in the gradle files.
This is temporary until the files themselves are modified to accomodate
the new strategy.
The --hack_gradle is not required for production enablement.
Either old or new style is available for any release.
Except this CL requires deck be manually configured to use the new style.