Retire repository

Fuel (from openstack namespace) and fuel-ccp (in x namespace)
repositories are unused and ready to retire.

This change removes all content from the repository and adds the usual
README file to point out that the repository is retired following the
process from
https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project

See also
http://lists.openstack.org/pipermail/openstack-discuss/2019-December/011647.html

Depends-On: https://review.opendev.org/699362
Change-Id: Id36b11db5ae374cbf66606ad402a8ffe99fc7daa
This commit is contained in:
Andreas Jaeger 2019-12-18 09:35:49 +01:00
parent 7ff80d3469
commit 06af89f5bd
74 changed files with 8 additions and 4445 deletions

View File

@ -1,7 +0,0 @@
[run]
branch = True
source = fuel-dev-tools
omit = fuel-dev-tools/tests/*,fuel-dev-tools/openstack/*
[report]
ignore_errors = True

60
.gitignore vendored
View File

@ -1,60 +0,0 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
.eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
.testrepository
.venv
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# Complexity
output/*.html
output/*/index.html
# Sphinx
doc/build
# pbr generates these
AUTHORS
ChangeLog
# Editors
*~
.*.swp
.*sw?
# Vagrant
vagrant/.vagrant
# Fuel sources
vagrant/sources

View File

@ -1,3 +0,0 @@
# Format is:
# <preferred e-mail> <other e-mail 1>
# <preferred e-mail> <other e-mail 2>

View File

@ -1,7 +0,0 @@
[DEFAULT]
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -1,16 +0,0 @@
If you would like to contribute to the development of OpenStack,
you must follow the steps in this page:
http://docs.openstack.org/infra/manual/developers.html
Once those steps have been completed, changes to OpenStack
should be submitted for review via the Gerrit tool, following
the workflow documented at:
http://docs.openstack.org/infra/manual/developers.html#development-workflow
Pull requests submitted through GitHub will be ignored.
Bugs should be filed on Launchpad, not GitHub:
https://bugs.launchpad.net/fuel-dev-tools

View File

@ -1,4 +0,0 @@
fuel-dev-tools Style Commandments
===============================================
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/

176
LICENSE
View File

@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

View File

@ -1,38 +0,0 @@
---
description:
For Fuel team structure and contribution policy, see [1].
This is repository level MAINTAINERS file. All contributions to this
repository must be approved by one or more Core Reviewers [2].
If you are contributing to files (or create new directories) in
root folder of this repository, please contact Core Reviewers for
review and merge requests.
If you are contributing to subfolders of this repository, please
check 'maintainers' section of this file in order to find maintainers
for those specific modules.
It is mandatory to get +1 from one or more maintainers before asking
Core Reviewers for review/merge in order to decrease a load on Core Reviewers [3].
Exceptions are when maintainers are actually cores, or when maintainers
are not available for some reason (e.g. on vacation).
[1] https://review.openstack.org/#/c/225376/ (to be replaced by html link once merged)
[2] https://review.openstack.org/#/admin/groups/646,members
[3] http://lists.openstack.org/pipermail/openstack-dev/2015-August/072406.html
Please keep this file in YAML format in order to allow helper scripts
to read this as a configuration data.
maintainers:
- fuel_dev_tools/: &tools_maintainers
- name: Maciej Kwiek
email: mkwiek@mirantis.com
IRC: mkwiek
- name: Sylwester Brzeczkowski
email: sbrzeczkowski@mirantis.com
IRC: sylwesterB
- name: Michal Rostecki
email: mrostecki@mirantis.com
IRC: nihilifer
- vagrant: *tools_maintainers

View File

@ -1,20 +1,10 @@
===============================
fuel-dev-tools suite
===============================
This project is no longer maintained.
Tools that make it easier to develop and work with OpenStack Fuel.
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
* Free software: Apache license
* Bugs: http://bugs.launchpad.net/fuel-dev-tools
Features
--------
* Vagrant environment: https://github.com/stackforge/fuel-dev-tools/tree/master/vagrant
* fuel-dev-tools command: https://github.com/stackforge/fuel-dev-tools/tree/master/fuel_dev_tools
TODO
--------
* add commands for managing VirtualBoxes -- move them from https://github.com/stackforge/fuel-main/tree/master/virtualbox
* add tests for fuel-dev-tools command
For any further questions, please email
openstack-discuss@lists.openstack.org or join #openstack-dev on
Freenode.

View File

@ -1,2 +0,0 @@
[python: **.py]

View File

@ -1,252 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2015 Mirantis, Inc.
#
# 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.
from __future__ import print_function
import argparse
from ipaddress import ip_network
import os
import shutil
import sys
import tempfile
import paramiko
import psycopg2
import requests
import yaml
class EnvironmentDoesntExistException(Exception):
pass
def get_env_networks(name, host='localhost', user='fuel_devops',
database='fuel_devops', password='fuel_devops'):
conn = psycopg2.connect(host=host, user=user, database=database,
password=password)
cursor = conn.cursor()
cursor.execute('SELECT DISTINCT id FROM devops_environment WHERE name=%s',
[name])
env_id = cursor.fetchone()
if env_id is not None:
env_id = env_id[0]
else:
error = 'No environment named "{}" has been found.'.format(name)
raise EnvironmentDoesntExistException(error)
cursor.execute(('SELECT name,ip_network FROM devops_network'
' WHERE environment_id=%s'), [env_id])
env_networks = cursor.fetchall()
cursor.close()
conn.close()
return dict(env_networks)
def cidr_to_iprange(cidr, start=0, end=-1):
hosts = list(ip_network(cidr).hosts())
if start > 0:
start -= 1
if end != -1:
end -= 1
start_host = str(hosts[start])
end_host = str(hosts[end])
return (start_host, end_host)
class MasterNode(object):
def __init__(self, ipaddress, port=22, username='root', password='r00tme'):
self.command = '/usr/bin/fuel {subcommand} --env-id {env_id} {action}'
self.tmpdir = tempfile.mkdtemp()
self.transport = paramiko.Transport(ipaddress, port)
self.transport.connect(username=username, password=password)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
def __exec(self, command):
session = self.transport.open_session()
session.exec_command(command)
exit_code = session.recv_exit_status()
if exit_code != 0:
error = ('Command {cmd} failed to execute correctly. '
'Exit code: {exit_code}.')
raise RuntimeError(error.format(cmd=command, exit_code=exit_code))
def download(self, subcommand, env_id=1):
command = self.command.format(subcommand=subcommand, env_id=env_id,
action='--download')
self.__exec(command)
yamlfile = '{}_{}.yaml'.format(subcommand, env_id)
src = os.path.join('/root', yamlfile)
dest = os.path.join(self.tmpdir, yamlfile)
self.sftp.get(src, dest)
def upload(self, subcommand, env_id=1):
yamlfile = '{}_{}.yaml'.format(subcommand, env_id)
src = os.path.join(self.tmpdir, yamlfile)
dest = os.path.join('/root', yamlfile)
self.sftp.put(src, dest)
command = self.command.format(subcommand=subcommand, env_id=env_id,
action='--upload')
self.__exec(command)
def verify(self, env_id=1):
command = self.command.format(subcommand='network', env_id=env_id,
action='--verify')
self.__exec(command)
def close(self):
self.sftp.close()
self.transport.close()
shutil.rmtree(self.tmpdir)
class MasterNodeNetwork(MasterNode):
def update_yaml(self, networks, yamlfile):
fuel_networks = frozenset(['public', 'management', 'storage',
'private'])
with open(yamlfile, 'r') as f:
cluster = yaml.safe_load(f)
for network in cluster['networks']:
network_name = network['name']
if network_name not in fuel_networks:
continue
cidr = networks[network_name]
iprange = cidr_to_iprange(cidr)
if 'cidr' in network:
network['cidr'] = cidr
if 'cidr' in network['meta']:
network['meta']['cidr'] = cidr
if network_name == 'public':
public_iprange = cidr_to_iprange(cidr, start=2, end=126)
floating_range = cidr_to_iprange(cidr, start=130)
public_gateway = cidr_to_iprange(cidr)[0]
network['ip_ranges'] = [public_iprange]
network['meta']['ip_range'] = public_iprange
network['gateway'] = public_gateway
cluster['networking_parameters']['floating_ranges'] = \
[floating_range]
else:
network['ip_ranges'] = [iprange]
with open(yamlfile, 'w') as f:
yaml.safe_dump(cluster, f)
def update(self, env_id, networks):
subcommand = 'network'
yamlfile = os.path.join(self.tmpdir, '{}_{}.yaml'.format(subcommand,
env_id))
self.download(subcommand, env_id)
self.update_yaml(networks, yamlfile)
self.upload(subcommand, env_id)
class MasterNodeRepo(MasterNode):
def __init__(self, ipaddress, port=22, username='root', password='r00tme',
repo_ubuntu=False, repo_mos=False):
super(MasterNodeRepo, self).__init__(ipaddress, port,
username, password)
self.repo_ubuntu = os.environ.get('UBUNTU_LATEST', False)
self.repo_mos = os.environ.get('MOS_REPOS', False)
if self.repo_mos:
version = requests.get(
'http://{}:8000/api/v1/version'.format(ipaddress)
).json()['release']
self.repo_mos = '{}/ubuntu/{}'.format(self.repo_mos, version)
def update_yaml(self, yamlfile, repo_ubuntu, repo_mos):
with open(yamlfile, 'r') as f:
settings = yaml.safe_load(f)
for repo in settings['editable']['repo_setup']['repos']['value']:
if repo_ubuntu and repo['name'].startswith('ubuntu'):
repo['uri'] = repo_ubuntu
if repo_mos and repo['name'].startswith('mos'):
repo['uri'] = repo_mos
with open(yamlfile, 'w') as f:
yaml.safe_dump(settings, f)
def update(self, env_id, repo_ubuntu=None, repo_mos=None):
subcommand = 'settings'
yamlfile = os.path.join(self.tmpdir, '{}_{}.yaml'.format(subcommand,
env_id))
if repo_ubuntu is None:
repo_ubuntu = self.repo_ubuntu
if repo_mos is None:
repo_mos = self.repo_mos
self.download(subcommand, env_id)
self.update_yaml(yamlfile, repo_ubuntu, repo_mos)
self.upload(subcommand, env_id)
if __name__ == '__main__':
action_choices = ['network', 'repos', 'verify']
parser = argparse.ArgumentParser()
parser.add_argument('action',
help='available commands',
choices=action_choices)
parser.add_argument('-n', '--env',
help='name of the environment to configure')
parser.add_argument('-i', '--id', default='1',
help='ID of the cluster which network should be setup')
args = parser.parse_args()
networks = get_env_networks(args.env)
master_node_address = cidr_to_iprange(networks['admin'], start=2)[0]
if args.action == 'network':
master_node = MasterNodeNetwork(master_node_address)
master_node.update(args.id, networks)
elif args.action == 'repos':
master_node = MasterNodeRepo(master_node_address)
master_node.update(args.id)
elif args.action == 'verify':
master_node = MasterNode(master_node_address)
master_node.verify(args.id)
else:
print('Unknown action given', file=sys.stderr)
sys.exit(1)
master_node.close()

View File

@ -1,8 +0,0 @@
ecdsa==0.13
paramiko==1.16.0
psycopg2==2.6.1
py2-ipaddress>=3.4.1; python_version < '3'
pycrypto==2.6.1
PyYAML==3.11
requests==2.9.1
wheel==0.26.0

View File

@ -1,75 +0,0 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'sphinx.ext.autodoc',
#'sphinx.ext.intersphinx',
'oslosphinx'
]
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# The suffix of source filenames.
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'fuel-dev-tools'
copyright = u'2015, Mirantis Inc.'
# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# html_static_path = ['static']
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index',
'%s.tex' % project,
u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'),
]
# Example configuration for intersphinx: refer to the Python standard library.
#intersphinx_mapping = {'http://docs.python.org/': None}

View File

@ -1,4 +0,0 @@
============
Contributing
============
.. include:: ../../CONTRIBUTING.rst

View File

@ -1,25 +0,0 @@
.. fuel-dev-tools documentation master file, created by
sphinx-quickstart on Tue Jul 9 22:26:36 2013.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to fuel-dev-tools's documentation!
========================================================
Contents:
.. toctree::
:maxdepth: 2
readme
installation
usage
contributing
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,12 +0,0 @@
============
Installation
============
At the command line::
$ pip install fuel-dev-tools
Or, if you have virtualenvwrapper installed::
$ mkvirtualenv fuel-dev-tools
$ pip install fuel-dev-tools

View File

@ -1 +0,0 @@
.. include:: ../../README.rst

View File

@ -1,7 +0,0 @@
========
Usage
========
To use fuel-dev-tools in a project::
import fuel-dev-tools

View File

@ -1,63 +0,0 @@
===============================
fuel-dev-tools command
===============================
Command-line interface for interacting with Fuel Master node.
## Global options
### `--IP`, `-p|--port`, `-U|--user`
Specify IP, port and user of the Fuel master ISO (default is `10.20.0.2`).
### `-I`, `--identity-file`
Specify SSH identity file (default is `$HOME/.ssh/id_rsa.openstack`).
### `info` (`info.Info`)
### `astute-id` (`docker.astute.Id`)
### `astute-config` (`docker.astute.Config`)
### `astute-dir` (`docker.astute.Dir`)
### `astute-log` (`docker.astute.Log`)
### `astute-restart` (`docker.astute.Restart`)
### `astute-rsync` (`docker.astute.Rsync`)
### `astute-shell` (`docker.astute.Shell`)
### `astute-start` (`docker.astute.Start`)
### `astute-stop` (`docker.astute.Stop`)
### `astute-tail` (`docker.astute.Tail`)
### `astute-volumes` (`docker.astute.Volumes`)
### `nailgun-id` (`docker.nailgun.Id`)
### `nailgun-config` (`docker.nailgun.Config`)
### `nailgun-dir` (`docker.nailgun.Dir`)
### `nailgun-log` (`docker.nailgun.Log`)
### `nailgun-restart` (`docker.nailgun.Restart`)
### `nailgun-rsync` (`docker.nailgun.Rsync`)
### `nailgun-rsync-static` (`nginx.Rsync`)
### `nailgun-shell` (`docker.nailgun.Shell`)
### `nailgun-start` (`docker.nailgun.Start`)
### `nailgun-stop` (`docker.nailgun.Stop`)
### `nailgun-tail` (`docker.nailgun.Tail`)
### `nailgun-volumes` (`docker.nailgun.Volumes`)

View File

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import pbr.version
__version__ = pbr.version.VersionInfo(
'fuel-dev-tools').version_string()

View File

@ -1,37 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
class CmdParserMixin(object):
"""Mixin for parsing fuel CLI output."""
def parse_output(self, output):
ret = []
header = []
lines = output.split('\n')
# brutal
lines = [line for line in lines
if not line.startswith('DEPRECATION WARNING')]
for name in lines[0].split('|'):
header.append(name.strip())
# lines[1] is just '----'
for line in lines[2:]:
values = [v.strip() for v in line.split('|')]
ret.append(dict(zip(header, values)))
return ret

View File

@ -1,60 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from cliff import command
from fuel_dev_tools import debug
from fuel_dev_tools import rsync
class BaseCommand(debug.DebugMixin, command.Command):
pass
class RsyncCommand(rsync.RsyncMixin, BaseCommand):
def pre_sync(self, parsed_args):
pass
def post_sync(self, parsed_args):
pass
@property
def source_path(self):
raise NotImplementedError
@property
def target_path(self):
raise NotImplementedError
@property
def base_target_dir(self):
return '/'
def take_action(self, parsed_args):
self.pre_sync(parsed_args)
source_dir = parsed_args.source
base_target_dir = self.base_target_dir
source = os.path.join(source_dir, self.source_path)
# target is on the remote
target = os.path.join(base_target_dir, self.target_path)
target, args = self.build_app_args_target(target)
self.rsync(source, target, *args)
self.post_sync(parsed_args)

View File

@ -1,26 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
class DebugMixin(object):
def __init__(self, app, parsed_args):
super(DebugMixin, self).__init__(app, parsed_args)
self._debug = getattr(parsed_args, 'debug', False)
def print_debug(self, msg):
if self._debug:
six.print_(msg)

View File

@ -1,284 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import six
from fuel_dev_tools import command
from fuel_dev_tools import exc
from fuel_dev_tools import ssh
DOCKER_CONTAINER_PATH = '/var/lib/docker/containers/'
DOCKER_DEVICEMAPPER_PATH = '/var/lib/docker/devicemapper/mnt/'
class DockerMixin(ssh.SSHMixin):
container = None
default_command = None
def get_log_directory(self):
return ''
def container_command(self, *commands):
return [
# 'lxc-attach', '--name', self.get_full_docker_id()
'docker', 'exec', self.get_docker_id()
] + list(commands)
def container_command_interactive(self, *commands):
return [
# 'lxc-attach', '--name', self.get_full_docker_id()
'docker', 'exec', '-it', self.get_docker_id()
] + list(commands)
def get_container_config(self):
d = self.get_container_config_directory()
config = self.ssh_command('cat %s/config.json' % d).decode('utf-8')
return json.loads(config)
def get_container_config_directory(self):
iid = self.get_docker_id()
paths = self.ssh_command(
'ls %s | grep %s' % (DOCKER_CONTAINER_PATH, iid)
).decode('utf-8')
return os.path.join(DOCKER_CONTAINER_PATH, paths.split()[0])
def get_container_directory(self):
iid = self.get_docker_id()
if not iid:
raise exc.DockerError('Docker ID could not be fetched')
paths = self.ssh_command(
'ls %s | grep %s' % (DOCKER_DEVICEMAPPER_PATH, iid)
).decode('utf-8')
return os.path.join(DOCKER_DEVICEMAPPER_PATH, paths.split()[0])
def get_docker_id(self, get_exited=False):
"""Returns first 12 characters of LXC container ID.
(as returned by the 'docker ps' command)
:param get_exited:
:return:
"""
up = self.ssh_command(
'docker ps -a | grep -i %s | grep Up | cut -f 1 -d " "' %
self.container
).decode('utf-8')
self.print_debug('FOUND CONTAINERS: %r' % up)
if not up and get_exited:
self.print_debug('Container not Up, trying Exited')
up = self.ssh_command(
'docker ps -a | grep -i %s | grep Exited | cut -f 1 -d " "' %
self.container
).decode('utf-8')
self.print_debug('FOUND CONTAINERS: %r' % up)
if not up:
raise exc.DockerError(
"Container '%s' not found or not functional" %
self.container
)
return up
def get_full_docker_id(self, get_exited=False):
"""Returns full container ID.
:return:
"""
iid = self.get_docker_id(get_exited=get_exited)
iid = self.ssh_command(
"docker inspect -f '{{.Id}}' %s" % iid
).decode('utf-8').strip()
return iid
def get_log_files(self, args):
log_dir = self.get_log_directory()
files = '*.log'
if args.files:
if len(args.files) == 1:
files = '%s.log' % args.files[0]
else:
files = '{%s}.log' % ','.join(args.files)
return os.path.join(log_dir, files)
def restart_container(self):
result = self.ssh_command(
'docker restart %s' % self.get_docker_id()
)
self.print_debug(result)
def start_container(self):
result = self.ssh_command(
'docker start %s' % self.get_docker_id(get_exited=True)
)
self.print_debug(result)
def stop_container(self):
result = self.ssh_command(
'docker stop %s' % self.get_docker_id()
)
self.print_debug(result)
class IdCommand(command.BaseCommand):
def take_action(self, parsed_args):
six.print_(self.get_docker_id(get_exited=True))
class ConfigCommand(command.BaseCommand):
def take_action(self, parsed_args):
six.print_(json.dumps(self.get_container_config(), indent=2))
class DirCommand(command.BaseCommand):
def take_action(self, parsed_args):
six.print_(self.get_container_directory())
class LogCommand(command.BaseCommand):
def get_log_directory(self):
raise NotImplementedError('No log directory for this command')
def get_parser(self, prog_name):
parser = super(LogCommand, self).get_parser(prog_name)
parser.add_argument(
'files',
type=str,
nargs='*',
help='List of files to show (all by default).'
)
return parser
def take_action(self, parsed_args):
six.print_(
self.ssh_command(
'tail', '-n', '100000', self.get_log_files(parsed_args)
)
)
class RestartCommand(command.BaseCommand):
def take_action(self, parsed_args):
self.restart_container()
class RsyncCommand(command.RsyncCommand):
@property
def base_target_dir(self):
return os.path.join(
self.get_container_directory(),
'rootfs'
)
class ShellCommand(command.BaseCommand):
default_command = None
log = logging.getLogger(__name__)
def get_parser(self, prog_name):
parser = super(ShellCommand, self).get_parser(prog_name)
help_msg = 'Command to execute'
if self.default_command:
help_msg = '%s (default: %s)' % (help_msg, self.default_command)
parser.add_argument(
'-c', '--command',
default=None,
help=help_msg
)
return parser
def take_action(self, parsed_args):
command = parsed_args.command
if not command:
command = self.default_command
if not command:
command = '/bin/bash'
return self.ssh_command_interactive(
*self.container_command_interactive(command)
)
class StartCommand(command.BaseCommand):
def take_action(self, parsed_args):
self.start_container()
class StopCommand(command.BaseCommand):
def take_action(self, parsed_args):
self.stop_container()
class TailCommand(command.BaseCommand):
def get_log_directory(self):
raise NotImplementedError('No log directory for this command')
def get_parser(self, prog_name):
parser = super(TailCommand, self).get_parser(prog_name)
parser.add_argument(
'files',
type=str,
nargs='*',
help='List of files to show (all by default).'
)
return parser
def take_action(self, parsed_args):
self.ssh_command_interactive(
'tail', '-F', self.get_log_files(parsed_args)
)
class VolumesCommand(command.BaseCommand):
def take_action(self, parsed_args):
six.print_(
json.dumps(
self.get_container_config().get('Volumes', {}), indent=2
)
)

View File

@ -1,153 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
import subprocess
from fuel_dev_tools import docker
from fuel_dev_tools import info
class DockerAstuteMixin(docker.DockerMixin):
container = 'astute'
default_command = '/bin/bash'
def get_log_directory(self):
return '/var/log/docker-logs/astute'
class AstuteInfo(DockerAstuteMixin, info.BasicInfo):
@classmethod
def get_info(cls):
return """Admin token is stored in /etc/fuel/astute.yaml on Fuel Main.
If you want to send custom receiverd response from Astute:
http://sprunge.us/UJfb
"""
class Id(DockerAstuteMixin, docker.IdCommand):
"""Print Docker container id."""
class Config(DockerAstuteMixin, docker.ConfigCommand):
"""Print Docker container config."""
class Dir(DockerAstuteMixin, docker.DirCommand):
"""Print Docker container directory on master."""
class Log(DockerAstuteMixin, docker.LogCommand):
"""Display logs for container."""
class Restart(DockerAstuteMixin, docker.RestartCommand):
"""Restart Docker container."""
class Rsync(DockerAstuteMixin, docker.RsyncCommand, docker.ShellCommand):
"""Rsync local directory to the Docker container."""
gemspec = 'astute.gemspec'
gemfile_template = 'astute-{}.gem'
gemfile = 'astute-8.0.0.gem'
@property
def source_path(self):
return self.gemfile
@property
def target_path(self):
return 'tmp/%s' % self.gemfile
def pre_sync(self, parsed_args):
self._update_gemfile(parsed_args.astute_version)
self.build_gem(parsed_args.source)
def post_sync(self, parsed_args):
self.ssh_command(*self.container_command(
'gem install', '--local', '-q', '-f', self.target_path
))
self.restart_container()
def build_gem(self, source_dir):
cmd = (
'cd %(cwd)s && '
'gem build %(gemspec)s'
) % {
'cwd': source_dir,
'gemspec': self.gemspec,
}
try:
result = subprocess.check_output([
cmd
], shell=True)
self.print_debug(result)
except subprocess.CalledProcessError as e:
six.print_('GEM BUILD ERROR')
six.print_(e.output)
raise
def get_parser(self, prog_name):
parser = super(Rsync, self).get_parser(prog_name)
parser.add_argument(
'-a', '--astute-version',
default='8.0.0',
help=('Astute gem version (default: 8.0.0). '
'Change if master node version is changed.')
)
return parser
def _update_gemfile(self, version):
self.gemfile = self.gemfile_template.format(version)
class RsyncAgent(DockerAstuteMixin, docker.RsyncCommand):
"""Rsync files to the Docker container."""
@property
def source_path(self):
return '.'
@property
def target_path(self):
return 'usr/libexec/mcollective/mcollective/agent'
def post_sync(self, parsed_args):
self.restart_container()
class Start(DockerAstuteMixin, docker.StartCommand):
"""Start Docker container."""
class Stop(DockerAstuteMixin, docker.StopCommand):
"""Stop Docker container."""
class Shell(DockerAstuteMixin, docker.ShellCommand):
"""Shell into a nailgun Docker container."""
class Tail(DockerAstuteMixin, docker.TailCommand):
"""Display logs for container."""
class Volumes(DockerAstuteMixin, docker.VolumesCommand):
"""Print all volumes of a container."""

View File

@ -1,55 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import docker
class DockerMcollectiveMixin(docker.DockerMixin):
container = 'mcollective'
default_command = '/bin/bash'
def get_log_directory(self):
return '/var/log/docker-logs/mcollective'
class RsyncAgent(DockerMcollectiveMixin, docker.RsyncCommand):
"""Rsync mcagent files to the Docker container."""
@property
def source_path(self):
return '.'
@property
def target_path(self):
return 'usr/libexec/mcollective/mcollective/agent'
def post_sync(self, parsed_args):
self.restart_container()
class RsyncShotgun(DockerMcollectiveMixin, docker.RsyncCommand):
"""Rsync shotgun files to the Docker container."""
@property
def source_path(self):
return 'shotgun/shotgun'
@property
def target_path(self):
return 'usr/lib/python2.6/site-packages/shotgun'
def post_sync(self, parsed_args):
self.restart_container()
class Shell(DockerMcollectiveMixin, docker.ShellCommand):
"""Shell into the container."""

View File

@ -1,131 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import command
from fuel_dev_tools import docker
from fuel_dev_tools import info
class DockerNailgunMixin(docker.DockerMixin):
container = 'nailgun'
default_command = 'python'
def get_log_directory(self):
return '/var/log/docker-logs/nailgun'
class NailgunInfo(DockerNailgunMixin, info.BasicInfo):
@classmethod
def get_info(cls):
return ('If you login to the shell you have the possibility to '
'reset the database with commands\n'
'/usr/bin/nailgun_syncdb\n'
'/usr/bin/naligun_fixtures')
class Id(DockerNailgunMixin, docker.IdCommand):
"""Print Docker container id."""
class Config(DockerNailgunMixin, docker.ConfigCommand):
"""Print Docker container config."""
class DBReset(DockerNailgunMixin,
command.BaseCommand):
"""Reset the whole database to defaults."""
def take_action(self, parsed_args):
from fuel_dev_tools.docker import postgres
reset_sql = """
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE pid <> pg_backend_pid() AND datname = 'nailgun';
DROP DATABASE nailgun;
CREATE DATABASE nailgun WITH OWNER nailgun;
"""
p = postgres.Shell(self.app, self.app_args)
cmd = [
'echo', '"{}"'.format(reset_sql),
'> {}/rootfs/tmp/reset-db.sql'.format(p.get_container_directory()),
]
p.ssh_command(*cmd)
cmd = p.container_command(
'chown', 'postgres:postgres', '/tmp/reset-db.sql'
)
p.ssh_command(*cmd)
cmd = p.container_command(
'su', '-', 'postgres',
'-c', '"cat /tmp/reset-db.sql | psql -d nailgun"'
)
p.ssh_command(*cmd)
cmd = self.container_command('manage.py', 'syncdb')
p.ssh_command(*cmd)
self.container_command('manage.py', 'loaddefault')
class Dir(DockerNailgunMixin, docker.DirCommand):
"""Print Docker container directory on master."""
class Log(DockerNailgunMixin, docker.LogCommand):
"""Display logs for container."""
class Restart(DockerNailgunMixin, docker.RestartCommand):
"""Restart Docker container."""
class Rsync(DockerNailgunMixin, docker.RsyncCommand):
"""Rsync local directory to the Docker container."""
@property
def source_path(self):
return 'nailgun/nailgun/'
@property
def target_path(self):
return 'usr/lib/python2.6/site-packages/nailgun'
def build_app_args_target(self, target):
target, args = super(Rsync, self).build_app_args_target(target)
return target, ['--exclude=*.pyc', '--exclude=test'] + args
def post_sync(self, parsed_args):
self.restart_container()
class Start(DockerNailgunMixin, docker.StartCommand):
"""Start Docker container."""
class Stop(DockerNailgunMixin, docker.StopCommand):
"""Stop Docker container."""
class Shell(DockerNailgunMixin, docker.ShellCommand):
"""Shell into a nailgun Docker container."""
class Tail(DockerNailgunMixin, docker.TailCommand):
"""Display logs for container."""
class Volumes(DockerNailgunMixin, docker.VolumesCommand):
"""Print all volumes of a container."""

View File

@ -1,81 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from fabric import api as fabric_api
from fuel_dev_tools import docker
class DockerNginxMixin(docker.DockerMixin):
container = 'nginx'
default_command = '/bin/bash'
def get_log_directory(self):
return '/var/log/docker-logs/nginx'
class Rsync(DockerNginxMixin, docker.RsyncCommand):
"""Rsync static files to the Docker container."""
temporary_build_dir = 'built-static'
def get_parser(self, prog_name):
parser = super(Rsync, self).get_parser(prog_name)
parser.add_argument(
'--no-gulp',
action='store_true',
help=('Don\'t run Gulp building task (default: false; note that '
'by default the minified version is used.')
)
return parser
def take_action(self, parsed_args):
source_dir = parsed_args.source
# NOTE: slash at the end is important in source_path!
source_path = 'nailgun/%s/' % self.temporary_build_dir
if not parsed_args.no_gulp:
self.build_gulp_static(source_dir)
config = self.get_container_config()
target_dir = config['Volumes']['/usr/share/nailgun/static']
source = os.path.join(source_dir, source_path)
target, args = self.build_app_args_target(target_dir)
self.rsync(source, target, *args)
def build_gulp_static(self, source_dir):
cwd = os.path.join(source_dir, 'nailgun')
self.print_debug(
'Building gulp static in %s, temporary static dir is: %s...' % (
cwd,
self.temporary_build_dir
)
)
with fabric_api.lcd(cwd):
result = fabric_api.run(
fabric_api.local(
'gulp build --static-dir=%s' % self.temporary_build_dir
)
)
self.print_debug(result)

View File

@ -1,70 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import docker
from fuel_dev_tools import info
class DockerPostgresMixin(docker.DockerMixin):
container = 'postgres'
default_command = 'su - postgres -c "psql -d nailgun"'
def get_log_directory(self):
return '/var/log/docker-logs/postgres'
class PostgresInfo(DockerPostgresMixin, info.BasicInfo):
@classmethod
def get_info(cls):
return 'TODO: add info about DB recreation'
class Id(DockerPostgresMixin, docker.IdCommand):
"""Print Docker container id."""
class Config(DockerPostgresMixin, docker.ConfigCommand):
"""Print Docker container config."""
class Dir(DockerPostgresMixin, docker.DirCommand):
"""Print Docker container directory on master."""
class Log(DockerPostgresMixin, docker.LogCommand):
"""Display logs for container."""
class Restart(DockerPostgresMixin, docker.RestartCommand):
"""Restart Docker container."""
class Start(DockerPostgresMixin, docker.StartCommand):
"""Start Docker container."""
class Stop(DockerPostgresMixin, docker.StopCommand):
"""Stop Docker container."""
class Shell(DockerPostgresMixin, docker.ShellCommand):
"""Shell into a nailgun Docker container."""
class Tail(DockerPostgresMixin, docker.TailCommand):
"""Display logs for container."""
class Volumes(DockerPostgresMixin, docker.VolumesCommand):
"""Print all volumes of a container."""

View File

@ -1,70 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import docker
from fuel_dev_tools import info
class DockerRabbitMQMixin(docker.DockerMixin):
container = 'RabbitMQ'
default_command = '/bin/bash'
def get_log_directory(self):
return '/var/log/docker-logs/rabbitmq'
class RabbitMQInfo(DockerRabbitMQMixin, info.BasicInfo):
@classmethod
def get_info(cls):
return ''
class Id(DockerRabbitMQMixin, docker.IdCommand):
"""Print Docker container id."""
class Config(DockerRabbitMQMixin, docker.ConfigCommand):
"""Print Docker container config."""
class Dir(DockerRabbitMQMixin, docker.DirCommand):
"""Print Docker container directory on master."""
class Log(DockerRabbitMQMixin, docker.LogCommand):
"""Display logs for container."""
class Restart(DockerRabbitMQMixin, docker.RestartCommand):
"""Restart Docker container."""
class Start(DockerRabbitMQMixin, docker.StartCommand):
"""Start Docker container."""
class Stop(DockerRabbitMQMixin, docker.StopCommand):
"""Stop Docker container."""
class Shell(DockerRabbitMQMixin, docker.ShellCommand):
"""Shell into a nailgun Docker container."""
class Tail(DockerRabbitMQMixin, docker.TailCommand):
"""Display logs for container."""
class Volumes(DockerRabbitMQMixin, docker.VolumesCommand):
"""Print all volumes of a container."""

View File

@ -1,25 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
class ClientException(Exception):
pass
class DockerError(Exception):
pass
class SSHError(Exception):
pass

View File

@ -1,58 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import six
from fuel_dev_tools import command
class BasicInfo(object):
pass
class Info(command.BaseCommand):
"""Various useful information about the Fuel master node."""
log = logging.getLogger(__name__)
def take_action(self, parsed_args):
urls = [
('OpenStackAPI', 5000,
'http://developer.openstack.org/api-ref.html'),
('RabbitMQ', 5672, 'User/password: <empty>'),
('RabbitMQ Management', 15672, 'User/password: <empty>'),
]
six.print_('URLS:')
for name, port, info in urls:
six.print_('{name:{fill}{align}{width}}http://{ip}:{port:{fill}'
'{align}{width}}{info}'.format(
name=name,
ip=self.app_args.ip,
port=port,
info=info,
fill=' ',
width=20,
align='<')
)
classes = BasicInfo.__subclasses__()
for klass in sorted(classes, key=lambda k: k.__name__):
six.print_('-' * 20)
six.print_(klass.container.title())
if hasattr(klass, 'get_info'):
six.print_(klass.get_info())
six.print_('')

View File

@ -1,30 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import command
class Rsync(command.RsyncCommand):
@property
def source_path(self):
return 'fuelmenu/'
@property
def target_path(self):
return 'usr/lib/python2.6/site-packages/fuelmenu'
def build_app_args_target(self, target):
target, args = super(Rsync, self).build_app_args_target(target)
return target, ['--exclude=*.pyc', '--exclude=test'] + args

View File

@ -1,76 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from fuel_dev_tools import command
from fuel_dev_tools import docker
from fuel_dev_tools import info
from fuel_dev_tools import ssh
class PuppetInfo(info.BasicInfo):
@classmethod
def get_info(cls):
return ''
class Rsync(ssh.SSHMixin,
command.RsyncCommand):
"""Rsync local directory to the Docker container."""
def take_action(self, parsed_args):
source_dir = os.path.join(parsed_args.source, 'deployment', 'puppet/')
# Target is in /etc/puppet/<release-version>
release_version = self.ssh_command(
'ls', '/etc/puppet'
).decode('utf-8').split()[0]
target_dir = os.path.join(
'/etc', 'puppet', release_version, 'modules'
)
target, args = self.build_app_args_target(target_dir)
self.print_debug('Rsyncing to master')
self.rsync(source_dir, target, *args)
updated_containers = set([None])
# Get DockerMixin subclasses which are also subclasses of
# command.Basecommand -- only such classes can be used by
# SSHMixin which requires self.app IP, port and user data
command_mixins = []
for docker_mixin_klass in docker.DockerMixin.__subclasses__():
command_mixins.extend(docker_mixin_klass.__subclasses__())
for klass in command_mixins:
if not issubclass(klass, command.BaseCommand) or \
klass.container in updated_containers:
continue
self.print_debug('Rsyncing to container %s' % klass.container)
executor = klass(self.app, self.app_args)
target_dir = os.path.join(
executor.get_container_directory(),
'rootfs', 'etc', 'puppet', release_version, 'modules'
)
target, args = self.build_app_args_target(target_dir)
self.rsync(source_dir, target, *args)
updated_containers.add(klass.container)

View File

@ -1,41 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from fuel_dev_tools import command
from fuel_dev_tools import ssh
class Rsync(ssh.SSHMixin,
command.RsyncCommand):
"""Rsync local CLI directory to the main machine."""
def take_action(self, parsed_args):
source_dir = os.path.join(parsed_args.source, 'fuelclient/')
# Target is in /usr/lib/python2.6/site-packages/fuelclient
target_dir = os.path.join(
'/usr', 'lib', 'python2.6', 'site-packages', 'fuelclient'
)
target, args = self.build_app_args_target(target_dir)
self.print_debug('Rsyncing to master')
self.rsync(source_dir, target, *args)
def build_app_args_target(self, target):
target, args = super(Rsync, self).build_app_args_target(target)
return target, ['--exclude=*.pyc'] + args

View File

@ -1,50 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import subprocess
class RsyncMixin(object):
def get_parser(self, prog_name):
parser = super(RsyncMixin, self).get_parser(prog_name)
parser.add_argument(
'-s', '--source',
nargs='?',
default='.',
help='Source of the rsync-ed directory.'
)
return parser
def build_app_args_target(self, target):
target = '{}@{}:{}'.format(self.app_args.user,
self.app_args.ip, target)
args = ['-e', 'ssh -p {}'.format(self.app_args.port)]
return target, args
def rsync(self, source, target, *args):
self.print_debug('RSYNC: %s --> %s' % (source, target))
# result = project.rsync_project(
# local_dir=source,
# remote_dir=target
# )
result = subprocess.check_output(
['rsync', '-avz'] + list(args) + [source, target]
)
self.print_debug(result.decode('utf-8'))

View File

@ -1,185 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Mirantis, Inc.
#
# 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.
"""
Command-line utility to help developers work with Fuel master.
"""
import logging
import os
from oslo_utils import encodeutils
import six
import sys
import traceback
from cliff import app
from cliff import commandmanager
from fuel_dev_tools.docker import astute
from fuel_dev_tools.docker import mcollective
from fuel_dev_tools.docker import nailgun
from fuel_dev_tools.docker import nginx
from fuel_dev_tools.docker import postgres
from fuel_dev_tools.docker import rabbitmq
from fuel_dev_tools import exc
from fuel_dev_tools import info
from fuel_dev_tools.master import fuelmenu
from fuel_dev_tools import puppet
from fuel_dev_tools import pythonclient
from fuel_dev_tools.slaves import mcagent
from fuel_dev_tools import ssh
COMMANDS = {
'info': info.Info,
'send-identity': ssh.SendIdentity,
'ssh': ssh.SSH,
'astute-id': astute.Id,
'astute-config': astute.Config,
'astute-dir': astute.Dir,
'astute-log': astute.Log,
'astute-restart': astute.Restart,
'astute-rsync': astute.Rsync,
'astute-shell': astute.Shell,
'astute-start': astute.Start,
'astute-stop': astute.Stop,
'astute-tail': astute.Tail,
'astute-volumes': astute.Volumes,
'mcagent-rsync': mcagent.Rsync,
'mcollective-rsync-shotgun': mcollective.RsyncShotgun,
'mcollective-shell': mcollective.Shell,
'nailgun-id': nailgun.Id,
'nailgun-config': nailgun.Config,
'nailgun-db-reset': nailgun.DBReset,
'nailgun-dir': nailgun.Dir,
'nailgun-log': nailgun.Log,
'nailgun-restart': nailgun.Restart,
'nailgun-rsync': nailgun.Rsync,
'nailgun-rsync-static': nginx.Rsync,
'nailgun-shell': nailgun.Shell,
'nailgun-start': nailgun.Start,
'nailgun-stop': nailgun.Stop,
'nailgun-tail': nailgun.Tail,
'nailgun-volumes': nailgun.Volumes,
'postgres-id': postgres.Id,
'postgres-config': postgres.Config,
'postgres-dir': postgres.Dir,
'postgres-log': postgres.Log,
'postgres-restart': postgres.Restart,
'postgres-shell': postgres.Shell,
'postgres-start': postgres.Start,
'postgres-stop': postgres.Stop,
'postgres-tail': postgres.Tail,
'postgres-volumes': postgres.Volumes,
'puppet-rsync': puppet.Rsync,
'pythonclient-rsync': pythonclient.Rsync,
'rabbitmq-id': rabbitmq.Id,
'rabbitmq-config': rabbitmq.Config,
'rabbitmq-dir': rabbitmq.Dir,
'rabbitmq-log': rabbitmq.Log,
'rabbitmq-restart': rabbitmq.Restart,
'rabbitmq-shell': rabbitmq.Shell,
'rabbitmq-start': rabbitmq.Start,
'rabbitmq-stop': rabbitmq.Stop,
'rabbitmq-tail': rabbitmq.Tail,
'rabbitmq-volumes': rabbitmq.Volumes,
'fuelmenu-rsync': fuelmenu.Rsync
}
class ToolsApp(app.App):
log = logging.getLogger(__name__)
def __init__(self):
super(ToolsApp, self).__init__(
description=__doc__.strip(),
version='1.0',
command_manager=commandmanager.CommandManager('fuel.cli')
)
self.commands = COMMANDS
for k, v in self.commands.items():
self.command_manager.add_command(k, v)
def build_option_parser(self, description, version):
"""Return an argparse option parser for this application.
Subclasses may override this method to extend
the parser with more global options.
:param description: full description of the application
:paramtype description: str
:param version: version number for the application
:paramtype version: str
"""
parser = super(ToolsApp, self).build_option_parser(
description, version)
parser.add_argument(
'--ip',
default='10.20.0.2',
help='Fuel master node IP address'
)
parser.add_argument(
'-p', '--port',
default='22',
help='Fuel master node SSH port'
)
parser.add_argument(
'-U', '--user',
default='root',
help='Fuel master node SSH user'
)
parser.add_argument(
'-I', '--identity-file',
default=os.path.join(
os.environ['HOME'], '.ssh', 'id_rsa.openstack'),
help='SSH identity file'
)
return parser
def main(argv=sys.argv[1:]):
try:
return ToolsApp().run(
list(map(encodeutils.safe_decode, argv))
)
except KeyboardInterrupt:
six.print_("... terminating client", file=sys.stderr)
return 130
except exc.ClientException:
six.print_('ClientException')
return 1
except exc.SSHError:
six.print_('SSHError')
return 1
except Exception:
traceback.print_exc()
return 1
if __name__ == '__main__':
main()

View File

@ -1,51 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fabric import api as fabric_api
from fuel_dev_tools import cmd_parser
class SlavesMixin(cmd_parser.CmdParserMixin):
def discover_slaves(self):
slaves = self.ssh_command('fuel', 'node')
return self.parse_output(slaves)
def rsync_slave(self, slave, source, target):
self.print_debug('Syncing to slave {name} [{ip}]'.format(**slave))
target = ':{}'.format(target)
hop_args = [
'-e',
'ssh -A -t root@{} -p {} ssh -A -t root@{}'.format(
self.app_args.ip,
self.app_args.port,
slave['ip']
)
]
self.rsync(source, target, *hop_args)
def slave_command(self, slave, *cmd):
cmd = [
'ssh', '-A', '-t',
'{}@{}'.format(self.app_args.user, self.app_args.ip),
'-p', self.app_args.port,
'ssh', '-A', '-t',
'root@{ip}'.format(**slave)
] + list(cmd)
return fabric_api.run(' '.join(cmd))

View File

@ -1,49 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
from fuel_dev_tools import command
from fuel_dev_tools.docker import astute
from fuel_dev_tools.docker import mcollective
from fuel_dev_tools import slaves
from fuel_dev_tools import ssh
class Rsync(slaves.SlavesMixin,
ssh.SSHMixin,
command.RsyncCommand):
def target_for_slave(self, slave):
if slave['status'] in ['discover', 'error']:
return '/usr/libexec/mcollective/mcollective/agent'
raise Exception(
'Don\'t know target for status {status} for node {name}'.format(
**slave)
)
def take_action(self, parsed_args):
for slave in self.discover_slaves():
source = parsed_args.source
target = self.target_for_slave(slave)
self.rsync_slave(slave, source, target)
self.print_debug('Restarting mcollective')
self.slave_command(slave, '/etc/init.d/mcollective', 'restart')
mc = mcollective.RsyncAgent(self.app, self.app_args)
mc.take_action(parsed_args)
ac = astute.RsyncAgent(self.app, self.app_args)
ac.take_action(parsed_args)

View File

@ -1,137 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import six
import subprocess
import fabric
from fabric import api as fabric_api
from fuel_dev_tools import command
from fuel_dev_tools import exc
SSH_PASSWORD_CHECKED = False
# TODO(pkaminski): ssh_command should be in some utils, not necessarily
# in this class?
class SSHMixin(object):
def __init__(self, *args, **kwargs):
super(SSHMixin, self).__init__(*args, **kwargs)
if self.app_args:
fabric_api.env.host_string = '{0}:{1}'.format(self.app_args.ip,
self.app_args.port)
fabric_api.env.user = self.app_args.user
if not self.app_args.debug:
for key in fabric.state.output:
fabric.state.output[key] = False
def send_identity(self):
self.print_debug('Sending identity %s for passwordless '
'authentication' % self.app_args.identity_file)
with open('%s.pub' % self.app_args.identity_file) as f:
contents = f.read()
result = fabric_api.run(
"echo '%s' >> ~/.ssh/authorized_keys" % contents
)
self.print_debug(result)
# And while we're here, let's fix /etc/hosts for which 10.20.0.2
# points to some non-existing domain (with misconfigured reverse-DNS
# lookups each SSH connection can be quite slow)
result = fabric_api.run(
"sed -i 's/^%(ip)s.*/%(ip)s localhost/' /etc/hosts" % {
'ip': self.app_args.ip
}
)
self.print_debug(result)
# Need to restart after /etc/hosts change
result = fabric_api.run('service sshd restart')
self.print_debug(result)
return result
def ssh_command(self, *args):
global SSH_PASSWORD_CHECKED
if not SSH_PASSWORD_CHECKED:
# NOTE: test if key is added to .authorized_keys with
SSH_PASSWORD_CHECKED = True
try:
subprocess.check_output([
'ssh',
'-p',
self.app_args.port,
'-o',
'PasswordAuthentication=no',
'%s@%s' % (self.app_args.user, self.app_args.ip),
'echo 1'
], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
if 'remote host identification has changed' in \
six.u(e.output).decode('utf-8').lower():
# .ssh/known_hosts error
raise exc.SSHError(e.output)
# Exit code error -- send .pub key to host
self.send_identity()
return fabric_api.run(' '.join(args))
def ssh_command_interactive(self, *args):
self.print_debug("COMMAND: %r" % list(args))
# NOTE: fabric's open_shell is broken: it's TERM or something like
# that that breaks arrow keys for browsing history in Bash, etc.
# command = None
#
# if args:
# command = ' '.join(args)
#
# self.print_debug('interactive %s' % command)
#
# fabric_api.open_shell(command=command)
commands = [
'ssh', '-t',
'{}@{}'.format(self.app_args.user, self.app_args.ip),
'-p', self.app_args.port,
'-i', self.app_args.identity_file,
]
if args:
commands.append('-C')
commands.extend(list(args))
os.execvp('ssh', commands)
class SendIdentity(SSHMixin, command.BaseCommand):
def take_action(self, parsed_args):
self.send_identity()
class SSH(SSHMixin, command.BaseCommand):
def take_action(self, parsed_args):
self.ssh_command_interactive('')

View File

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Mirantis, Inc.
#
# 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.
from oslotest import base
class TestCase(base.BaseTestCase):
"""Test case base class for all unit tests."""

View File

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# 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.
"""
test_fuel_dev_tools
----------------------------------
Tests for `fuel_dev_tools` module.
"""
from fuel_dev_tools.tests import base
class TestFuelDevTools(base.TestCase):
def test_something(self):
pass

View File

@ -1,6 +0,0 @@
[DEFAULT]
# The list of modules to copy from oslo-incubator.git
# The base module to hold the copy of openstack.common
base=fuel-dev-tools

View File

@ -1,10 +0,0 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr>=0.6,!=0.7,<1.0
Babel>=1.3
cliff>=1.10.1
oslo.utils>=1.4.0
fabric>=1.10.1

View File

@ -1,50 +0,0 @@
[metadata]
name = fuel-dev-tools
summary = Tools that make it easier to develop and work with OpenStack Fuel.
description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
home-page = http://www.openstack.org/
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4
[files]
packages =
fuel_dev_tools
[entry_points]
console_scripts =
fuel-dev-tools = fuel_dev_tools.shell:main
[build_sphinx]
source-dir = doc/source
build-dir = doc/build
all_files = 1
[upload_sphinx]
upload-dir = doc/build/html
[compile_catalog]
directory = fuel_dev_tools/locale
domain = fuel_dev_tools
[update_catalog]
domain = fuel_dev_tools
output_dir = fuel_dev_tools/locale
input_file = fuel_dev_tools/locale/fuel-dev-tools.pot
[extract_messages]
keywords = _ gettext ngettext l_ lazy_gettext
mapping_file = babel.cfg
output_file = fuel_dev_tools/locale/fuel-dev-tools.pot

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import setuptools
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215
try:
import multiprocessing # noqa
except ImportError:
pass
setuptools.setup(
setup_requires=['pbr'],
pbr=True)

View File

@ -1,15 +0,0 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
coverage>=3.6
discover
python-subunit>=0.0.18
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
oslosphinx>=2.2.0 # Apache-2.0
oslotest>=1.2.0 # Apache-2.0
testrepository>=0.0.18
testscenarios>=0.4
testtools>=0.9.36,!=1.2.0

40
tox.ini
View File

@ -1,40 +0,0 @@
[tox]
minversion = 1.8
envlist = py27,pep8
skipsdist = True
[testenv]
usedevelop = True
install_command = pip install -U {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = python setup.py testr --slowest --testr-args='{posargs}'
[testenv:pep8]
deps = hacking==0.10.1
usedevelop = False
commands =
flake8
[testenv:venv]
commands = {posargs}
[testenv:cover]
commands = python setup.py testr --coverage --testr-args='{posargs}'
[testenv:docs]
commands = python setup.py build_sphinx
[testenv:debug]
commands = oslo_debug_helper {posargs}
[flake8]
# E123, E125 skipped as they are invalid PEP-8.
count = True
show-source = True
ignore = E123,E125
builtins = _
exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,vagrant/*

View File

@ -1,86 +0,0 @@
============================
Fuel development Vagrant box
============================
This is a definition of a Vagrant box tailored for development of Mirantis Fuel.
Configuration is done using [SaltStack](http://saltstack.com/).
Usage
-----
Clone and `cd` into this repo then run
```
vagrant up
```
to start the Vagrant box (with the Virtualbox provider) or
```
vagrant up --provider=libvirt
```
to start with the `libvirt` provider.
Then run
```
vagrant ssh
sudo su
salt-call state.highstate --local
```
to SSH into the machine and initially set up the environment. Then on the virtual machine as user `vagrant` you can do
```
workon fuel
```
to activate the Python virtualenv. To start the server type
```
/sources/fuel-web/nailgun/manage.py run --fake-tasks
```
and point your browser to [http://localhost:8200](http://localhost:8200) -- username/password for the test env is `admin`/`admin`.
Sometimes it might be necessary to repopulate the DB with fixtures, to do this just type (`dropdb` might be needed before):
```
./manage.py syncdb
./manage.py loaddefault # It loads all basic fixtures listed in settings.yaml
./manage.py loaddata nailgun/fixtures/sample_environment.json # Loads fake nodes
```
As a shortut, a script `nailgun_clean_db.sh` is provided to reinitialize the database using the above commands.
To run tests:
```
cd /sources/fuel-web
./run_tests.sh
```
The `sources` directory is mounted under `/sources` on the Vagrant machine using Rsync for better performance
(otherwise tests run incredibly slow). If you want Vagrant to automatically rsync your local directory to the virtualmachine run
```
vagrant rsync-auto
```
Note that this is a one-way sync, i.e. from your local machine to the virtual machine, not the other way around.
There is also the `/vagrant/sources` folder where `sources` are mounted too, but using the standard VirtualBox
Synchronized Folders which is extremely slow.
For more information see http://docs.mirantis.com/fuel-dev/develop/nailgun/development/env.html and
http://docs.mirantis.com/fuel-dev/develop/env.html
tmux
----
[tmux](http://tmux.sourceforge.net/) is installed by default. Each tmux window's output is logged
to a separate file for easier inspection of history. The file's name can be fetched in current
active window from the `TMUX_LOG_FILE` variable (see `/home/vagrant/.bash_profile`).
Astute
----
To run Ruby tests for `fuel-astute`:
```
cd /sources/fuel-astute
rvm gemset use astute
./run_tests.sh
```
TODO
----
* eliminate the need for running `rsync-auto` and instead install the `rsync` service inside the Vagrant box
that synchronizes `/vagrant/sources` into `/sources`
* add link (and Jenkins job?) to pre-generated Vagrant box

99
vagrant/Vagrantfile vendored
View File

@ -1,99 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "ubuntu/trusty64"
# The url from where the 'config.vm.box' box will be fetched if it
# doesn't already exist on the user's system.
config.vm.box_url = "https://atlas.hashicorp.com/ubuntu/boxes/trusty64"
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# config.vm.network :forwarded_port, guest: 80, host: 8080
config.vm.network :forwarded_port, guest: 80, host: 8280
config.vm.network :forwarded_port, guest: 8000, host: 8200
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network :private_network, ip: "192.168.60.10"
# run:
# vagrant rsync-auto
# to fire the service for automatic rsync synchronization
config.vm.synced_folder './sources', '/sources', type: "rsync", rsync__auto: true,
rsync__args: ["--verbose", "--archive", "-z", "--delete"],
rsync__exclude: [
'*.pyc',
'*.iso',
'*/.tox',
'nailgun/static/js/libs/bower',
'nailgun/node_modules',
'test_run'
],
create: true
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
config.vm.provider :virtualbox do |vb|
vb.name = "vagrant-mirantis-fuel"
# # Don't boot with headless mode
# vb.gui = true
#
# Use VBoxManage to customize the VM. For example to change memory:
vb.customize ["modifyvm", :id, "--ioapic", "on", "--memory", "1024"]
end
# Example for libvirt:
#
config.vm.provider :libvirt do |libvirt, override|
override.vm.box = "baremettle/ubuntu-14.04"
override.vm.box_url = "https://atlas.hashicorp.com/baremettle/boxes/ubuntu-14.04"
override.vm.synced_folder './', '/vagrant', nfs: true, mount_options: ['rw', 'vers=3', 'tcp']
libvirt.memory = 1024
end
## For masterless, mount your salt file root
config.vm.synced_folder "pillar/", "/srv/pillar/"
config.vm.synced_folder "salt/", "/srv/salt/"
## Make LC_ALL default to en_US.UTF-8 instead of en_US.
config.vm.provision "shell", inline: 'echo \'LC_ALL="en_US.UTF-8"\' > /etc/default/locale'
## Use all the defaults:
config.vm.provision :salt do |salt|
#salt.minion_config = "salt_minion"
salt.colorize = true
salt.log_level = "all"
salt.bootstrap_options = "-P"
#salt.run_highstate = true # Uncomment if you want to automatically provision the box
end
# Fix for Vagrant 1.7.5: https://github.com/mitchellh/vagrant/issues/5973
# Solution from https://github.com/mitchellh/vagrant/issues/5973#issuecomment-126102092
# After Vagrant is fixed, this can be removed and the line
# salt.minion_config = "salt_minion"
# uncommented above
config.vm.provision "shell",
inline: "sudo cp /etc/salt/minion{,-dist} && sudo cp /vagrant/salt_minion /etc/salt/minion"
end

View File

@ -1,3 +0,0 @@
GROUP: vagrant
USER: vagrant
HOME: /home/vagrant

View File

@ -1,3 +0,0 @@
base:
'*':
- env

View File

@ -1,5 +0,0 @@
SERVER_ADDRESS: "127.0.0.1"
SERVER_PORT: "8000"
KEYSTONE_USER: "admin"
KEYSTONE_PASS: "admin"
KEYSTONE_PORT: "5000"

View File

@ -1,25 +0,0 @@
#!/bin/bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
. /etc/bash_completion.d/virtualenvwrapper
workon fuel
cd /sources/fuel-web
python -c 'import json
from nailgun.task.task import DumpTask
f = open("/tmp/shotgun-config.json", "w")
f.write(json.dumps(DumpTask.conf(), indent=2))'

View File

@ -1,899 +0,0 @@
#!/usr/bin/env bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
shopt -s extglob
set -o errtrace
set -o errexit
rvm_install_initialize()
{
DEFAULT_SOURCES=(github.com/wayneeseguin/rvm bitbucket.org/mpapis/rvm)
BASH_MIN_VERSION="3.2.25"
if
[[ -n "${BASH_VERSION:-}" &&
"$(\printf "%b" "${BASH_VERSION:-}\n${BASH_MIN_VERSION}\n" | LC_ALL=C \sort -t"." -k1,1n -k2,2n -k3,3n | \head -n1)" != "${BASH_MIN_VERSION}"
]]
then
echo "BASH ${BASH_MIN_VERSION} required (you have $BASH_VERSION)"
exit 1
fi
export HOME PS4
export rvm_trace_flag rvm_debug_flag rvm_user_install_flag rvm_ignore_rvmrc rvm_prefix rvm_path
PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > "
}
log() { printf "%b\n" "$*"; }
debug(){ [[ ${rvm_debug_flag:-0} -eq 0 ]] || printf "%b\n" "Running($#): $*"; }
fail() { log "\nERROR: $*\n" ; exit 1 ; }
rvm_install_commands_setup()
{
\which which >/dev/null 2>&1 || fail "Could not find 'which' command, make sure it's available first before continuing installation."
if
[[ -z "${rvm_tar_command:-}" ]] && builtin command -v gtar >/dev/null
then
rvm_tar_command=gtar
elif
${rvm_tar_command:-tar} --help 2>&1 | GREP_OPTIONS="" \grep -- --strip-components >/dev/null
then
rvm_tar_command="${rvm_tar_command:-tar}"
else
case "$(uname)" in
(OpenBSD)
log "Trying to install GNU version of tar, might require sudo password"
if (( UID ))
then sudo pkg_add -z gtar-1
else pkg_add -z gtar-1
fi
rvm_tar_command=gtar
;;
(Darwin|FreeBSD|DragonFly) # it's not possible to autodetect on OSX, the help/man does not mention all flags
rvm_tar_command=tar
;;
(SunOS)
case "$(uname -r)" in
(5.10)
log "Trying to install GNU version of tar, might require sudo password"
if (( UID ))
then
if \which sudo >/dev/null 2>&1
then sudo_10=sudo
elif \which /opt/csw/bin/sudo >/dev/null 2>&1
then sudo_10=/opt/csw/bin/sudo
else fail "sudo is required but not found. You may install sudo from OpenCSW repository (http://opencsw.org/about)"
fi
pkginfo -q CSWpkgutil || $sudo_10 pkgadd -a $rvm_path/config/solaris/noask -d http://get.opencsw.org/now CSWpkgutil
sudo /opt/csw/bin/pkgutil -iy CSWgtar -t http://mirror.opencsw.org/opencsw/unstable
else
pkginfo -q CSWpkgutil || pkgadd -a $rvm_path/config/solaris/noask -d http://get.opencsw.org/now CSWpkgutil
/opt/csw/bin/pkgutil -iy CSWgtar -t http://mirror.opencsw.org/opencsw/unstable
fi
rvm_tar_command=/opt/csw/bin/gtar
;;
(*)
rvm_tar_command=tar
;;
esac
esac
builtin command -v ${rvm_tar_command:-gtar} >/dev/null ||
fail "Could not find GNU compatible version of 'tar' command, make sure it's available first before continuing installation."
fi
if
[[ " ${rvm_tar_options:-} " != *" --no-same-owner "* ]] &&
$rvm_tar_command --help 2>&1 | GREP_OPTIONS="" \grep -- --no-same-owner >/dev/null
then
rvm_tar_options="${rvm_tar_options:-}${rvm_tar_options:+ }--no-same-owner"
fi
}
usage()
{
printf "%b" "
Usage
rvm-installer [options] [action]
Options
[[--]version] <version>
The version or tag to install. Valid values are:
latest - The latest tagged version.
latest-minor - The latest minor version of the current major version.
latest-<x> - The latest minor version of version x.
latest-<x>.<y> - The latest patch version of version x.y.
<x>.<y>.<z> - Major version x, minor version y and patch z.
[--]branch <branch>
The name of the branch from which RVM is installed. This option can be used
with the following formats for <branch>:
<account>/
If account is wayneeseguin or mpapis, installs from one of the following:
https://github.com/wayneeseguin/rvm/archive/master.tar.gz
https://bitbucket.org/mpapis/rvm/get/master.tar.gz
Otherwise, installs from:
https://github.com/<account>/rvm/archive/master.tar.gz
<account>/<branch>
If account is wayneeseguin or mpapis, installs from one of the following:
https://github.com/wayneeseguin/rvm/archive/<branch>.tar.gz
https://bitbucket.org/mpapis/rvm/get/<branch>.tar.gz
Otherwise, installs from:
https://github.com/<account>/rvm/archive/<branch>.tar.gz
[/]<branch>
Installs the branch from one of the following:
https://github.com/wayneeseguin/rvm/archive/<branch>.tar.gz
https://bitbucket.org/mpapis/rvm/get/<branch>.tar.gz
[--]source <source>
Defines the repository from which RVM is retrieved and installed in the format:
<domain>/<account>/<repo>
Where:
<domain> - Is bitbucket.org, github.com or a github enterprise site serving
an RVM repository.
<account> - Is the user account in which the RVM repository resides.
<repo> - Is the name of the RVM repository.
Note that when using the [--]source option, one should only use the [/]branch format
with the [--]branch option. Failure to do so will result in undefined behavior.
--trace
Provides debug logging for the installation script.
Actions
master - Installs RVM from the master branch at wayneeseguin/rvm on github or mpapis/rvm
on bitbucket.org.
stable - Installs RVM from the stable branch a wayneeseguin/rvm on github or mpapis/rvm
on bitbucket.org.
help - Displays this output.
"
}
## duplication marker 32fosjfjsznkjneuera48jae
__rvm_curl_output_control()
{
if
(( ${rvm_quiet_curl_flag:-0} == 1 ))
then
__flags+=( "--silent" "--show-error" )
elif
[[ " $*" == *" -s"* || " $*" == *" --silent"* ]]
then
# make sure --show-error is used with --silent
[[ " $*" == *" -S"* || " $*" == *" -sS"* || " $*" == *" --show-error"* ]] ||
{
__flags+=( "--show-error" )
}
fi
}
## duplication marker 32fosjfjsznkjneuera48jae
# -S is automatically added to -s
__rvm_curl()
(
__rvm_which curl >/dev/null ||
{
rvm_error "RVM requires 'curl'. Install 'curl' first and try again."
return 200
}
typeset -a __flags
__flags=( --fail --location --max-redirs 10 )
[[ "$*" == *"--max-time"* ]] ||
[[ "$*" == *"--connect-timeout"* ]] ||
__flags+=( --connect-timeout 30 --retry-delay 2 --retry 3 )
if [[ -n "${rvm_proxy:-}" ]]
then __flags+=( --proxy "${rvm_proxy:-}" )
fi
__rvm_curl_output_control
unset curl
__rvm_debug_command \curl "${__flags[@]}" "$@" || return $?
)
rvm_error() { printf "ERROR: %b\n" "$*"; }
__rvm_which(){ which "$@" || return $?; true; }
__rvm_debug_command()
{
debug "Running($#): $*"
"$@" || return $?
true
}
rvm_is_a_shell_function()
{
[[ -t 0 && -t 1 ]] || return $?
return ${rvm_is_not_a_shell_function:-0}
}
# Searches the tags for the highest available version matching a given pattern.
# fetch_version (github.com/wayneeseguin/rvm bitbucket.org/mpapis/rvm) 1.10. -> 1.10.3
# fetch_version (github.com/wayneeseguin/rvm bitbucket.org/mpapis/rvm) 1.10. -> 1.10.3
# fetch_version (github.com/wayneeseguin/rvm bitbucket.org/mpapis/rvm) 1. -> 1.11.0
# fetch_version (github.com/wayneeseguin/rvm bitbucket.org/mpapis/rvm) "" -> 2.0.1
fetch_version()
{
typeset _account _domain _pattern _repo _sources _values _version
_sources=(${!1})
_pattern=$2
for _source in "${_sources[@]}"
do
IFS='/' read -r _domain _account _repo <<< "${_source}"
_version="$(
fetch_versions ${_domain} ${_account} ${_repo} |
GREP_OPTIONS="" \grep "^${_pattern:-}" | tail -n 1
)"
if
[[ -n ${_version} ]]
then
echo "${_version}"
return 0
fi
done
}
# Returns a sorted list of all version tags from a repository
fetch_versions()
{
typeset _account _domain _repo _url
_domain=$1
_account=$2
_repo=$3
case ${_domain} in
(bitbucket.org)
_url=https://${_domain}/api/1.0/repositories/${_account}/${_repo}/branches-tags
;;
(github.com)
_url=https://api.${_domain}/repos/${_account}/${_repo}/tags
;;
(*)
_url=https://${_domain}/api/v3/repos/${_account}/${_repo}/tags
;;
esac
__rvm_curl -s ${_url} |
\awk -v RS=',' -v FS='"' '$2=="name"{print $4}' |
sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n
}
install_release()
{
typeset _source _sources _url _version _verify_pgp
_sources=(${!1})
_version=$2
debug "Downloading RVM version ${_version}"
for _source in "${_sources[@]}"
do
case ${_source} in
(bitbucket.org*)
_url="https://${_source}/get/${_version}.tar.gz"
_verify_pgp="https://${_source}/downloads/${_version}.tar.gz.asc"
;;
(*)
_url="https://${_source}/archive/${_version}.tar.gz"
_verify_pgp="https://${_source}/releases/download/${_version}/${_version}.tar.gz.asc"
;;
esac
get_and_unpack "${_url}" "rvm-${_version}.tgz" "$_verify_pgp" && return
done
return $?
}
install_head()
{
typeset _branch _source _sources _url
_sources=(${!1})
_branch=$2
debug "Selected RVM branch ${_branch}"
for _source in "${_sources[@]}"
do
case ${_source} in
(bitbucket.org*)
_url=https://${_source}/get/${_branch}.tar.gz
;;
(*)
_url=https://${_source}/archive/${_branch}.tar.gz
;;
esac
get_and_unpack "${_url}" "rvm-${_branch//\//_}.tgz" && return
done
return $?
}
# duplication marker dfkjdjngdfjngjcszncv
# Drop in cd which _doesn't_ respect cdpath
__rvm_cd()
{
typeset old_cdpath ret
ret=0
old_cdpath="${CDPATH}"
CDPATH="."
chpwd_functions="" builtin cd "$@" || ret=$?
CDPATH="${old_cdpath}"
return $ret
}
get_package()
{
typeset _url _file
_url="$1"
_file="$2"
log "Downloading ${_url}"
__rvm_curl -sS ${_url} -o ${rvm_archives_path}/${_file} ||
{
_return=$?
case $_return in
# duplication marker lfdgzkngdkjvnfjknkjvcnbjkncvjxbn
(60)
log "
Could not download '${_url}', you can read more about it here:
https://rvm.io/support/fixing-broken-ssl-certificates/
To continue in insecure mode run 'echo insecure >> ~/.curlrc'.
"
;;
# duplication marker lfdgzkngdkjvnfjknkjvcnbjkncvjxbn
(77)
log "
It looks like you have old certificates, you can read more about it here:
https://rvm.io/support/fixing-broken-ssl-certificates/
"
;;
# duplication marker lfdgzkngdkjvnfjknkjvcnbjkncvjxbn
(141)
log "
Curl returned 141 - it is result of a segfault which means it's Curls fault.
Try again and if it crashes more than a couple of times you either need to
reinstall Curl or consult with your distribution manual and contact support.
"
;;
(*)
log "
Could not download '${_url}'.
curl returned status '$_return'.
"
;;
esac
return $_return
}
}
# duplication marker flnglfdjkngjndkfjhsbdjgfghdsgfklgg
rvm_install_gpg_setup()
{
export rvm_gpg_command
{
rvm_gpg_command="$( \which gpg2 2>/dev/null )" &&
[[ rvm_gpg_command != "/cygdrive/"* ]]
} ||
rvm_gpg_command="$( \which gpg 2>/dev/null )" ||
rvm_gpg_command=""
debug "Detected GPG program: '$rvm_gpg_command'"
[[ -n "$rvm_gpg_command" ]] || return $?
}
# duplication marker rdjgndfnghdfnhgfdhbghdbfhgbfdhbn
verify_package_pgp()
{
if
"${rvm_gpg_command}" --verify "$2" "$1"
then
log "GPG verified '$1'"
else
typeset _ret=$?
log "\
Warning, RVM 1.26.0 introduces signed releases and \
automated check of signatures when GPG software found.
Assuming you trust Michal Papis import the mpapis public \
key (downloading the signatures).
GPG signature verification failed for '$1' - '$3'!
try downloading the signatures:
${SUDO_USER:+sudo }${rvm_gpg_command##*/} --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
or if it fails:
command curl -sSL https://rvm.io/mpapis.asc | ${SUDO_USER:+sudo }${rvm_gpg_command##*/} --import -
the key can be compared with:
https://rvm.io/mpapis.asc
https://keybase.io/mpapis
"
exit $_ret
fi
}
verify_pgp()
{
[[ -n "${1:-}" ]] ||
{
debug "No PGP url given, skipping."
return 0
}
get_package "$1" "$2.asc" ||
{
debug "PGP url given but does not exist: '$1'"
return 0
}
rvm_install_gpg_setup ||
{
log "Found PGP signature at: '$1',
but no GPG software exists to validate it, skipping."
return 0
}
verify_package_pgp "${rvm_archives_path}/$2" "${rvm_archives_path}/$2.asc" "$1"
}
get_and_unpack()
{
typeset _url _file _patern _return _verify_pgp
_url="$1"
_file="$2"
_verify_pgp="$3"
get_package "$_url" "$_file" || return $?
verify_pgp "$_verify_pgp" "$_file" || return $?
[[ -d "${rvm_src_path}/rvm" ]] || \mkdir -p "${rvm_src_path}/rvm"
__rvm_cd "${rvm_src_path}/rvm" ||
{
_return=$?
log "Could not change directory '${rvm_src_path}/rvm'."
return $_return
}
rm -rf ${rvm_src_path}/rvm/*
__rvm_debug_command $rvm_tar_command xzf ${rvm_archives_path}/${_file} ${rvm_tar_options:-} --strip-components 1 ||
{
_return=$?
log "Could not extract RVM sources."
return $_return
}
}
rvm_install_default_settings()
{
# Tracing, if asked for.
if
[[ "$*" == *--trace* ]] || (( ${rvm_trace_flag:-0} > 0 ))
then
set -o xtrace
rvm_trace_flag=1
fi
# Variable initialization, remove trailing slashes if they exist on HOME
true \
${rvm_trace_flag:=0} ${rvm_debug_flag:=0}\
${rvm_ignore_rvmrc:=0} HOME="${HOME%%+(\/)}"
if
(( rvm_ignore_rvmrc == 0 ))
then
for rvmrc in /etc/rvmrc "$HOME/.rvmrc"
do
if
[[ -s "$rvmrc" ]]
then
if
GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1
then
printf "%b" "
Error: $rvmrc is for rvm settings only.
rvm CLI may NOT be called from within $rvmrc.
Skipping the loading of $rvmrc
"
exit 1
else
source "$rvmrc"
fi
fi
done
fi
if
[[ -z "${rvm_path:-}" ]]
then
if
(( UID == 0 ))
then
rvm_user_install_flag=0
rvm_prefix="/usr/local"
rvm_path="${rvm_prefix}/rvm"
else
rvm_user_install_flag=1
rvm_prefix="$HOME"
rvm_path="${rvm_prefix}/.rvm"
fi
fi
if [[ -z "${rvm_prefix}" ]]
then rvm_prefix=$( dirname $rvm_path )
fi
# duplication marker kkdfkgnjfndgjkndfjkgnkfjdgn
[[ -n "${rvm_user_install_flag:-}" ]] ||
case "$rvm_path" in
(/usr/local/rvm) rvm_user_install_flag=0 ;;
($HOME/*|/${USER// /_}*) rvm_user_install_flag=1 ;;
(*) rvm_user_install_flag=0 ;;
esac
}
rvm_install_parse_params()
{
install_rubies=()
install_gems=()
flags=( ./scripts/install )
forwarded_flags=()
while
(( $# > 0 ))
do
token="$1"
shift
case "$token" in
(--trace)
set -o xtrace
rvm_trace_flag=1
flags=( -x "${flags[@]}" "$token" )
forwarded_flags+=( "$token" )
;;
(--debug|--quiet-curl)
flags+=( "$token" )
forwarded_flags+=( "$token" )
token=${token#--}
token=${token//-/_}
export "rvm_${token}_flag"=1
printf "%b" "Turning on ${token/_/ } mode.\n"
;;
(--path)
if [[ -n "${1:-}" ]]
then
rvm_path="$1"
shift
else
fail "--path must be followed by a path."
fi
;;
(--branch|branch) # Install RVM from a given branch
if [[ -n "${1:-}" ]]
then
case "$1" in
(/*)
branch=${1#/}
;;
(*/)
branch=master
if [[ "${1%/}" -ne wayneeseguin ]] && [[ "${1%/}" -ne mpapis ]]
then sources=(github.com/${1%/}/rvm)
fi
;;
(*/*)
branch=${1#*/}
if [[ "${1%%/*}" -ne wayneeseguin ]] && [[ "${1%%/*}" -ne mpapis ]]
then sources=(github.com/${1%%/*}/rvm)
fi
;;
(*)
branch="$1"
;;
esac
shift
else
fail "--branch must be followed by a branchname."
fi
;;
(--source|source)
if [[ -n "${1:-}" ]]
then
if [[ "$1" = */*/* ]]
then
sources=($1)
shift
else
fail "--source must be in the format <domain>/<account>/<repo>."
fi
else
fail "--source must be followed by a source."
fi
;;
(--user-install|--ignore-dotfiles)
token=${token#--}
token=${token//-/_}
export "rvm_${token}_flag"=1
printf "%b" "Turning on ${token/_/ } mode.\n"
;;
(--auto-dotfiles)
flags+=( "$token" )
export "rvm_auto_dotfiles_flag"=1
printf "%b" "Turning on auto dotfiles mode.\n"
;;
(--auto)
export "rvm_auto_dotfiles_flag"=1
printf "%b" "Warning, --auto is deprecated in favor of --auto-dotfiles.\n"
;;
(--verify-downloads)
if [[ -n "${1:-}" ]]
then
export rvm_verify_downloads_flag="$1"
forwarded_flags+=( "$token" "$1" )
shift
else
fail "--verify-downloads must be followed by level(0|1|2)."
fi
;;
(--autolibs=*)
flags+=( "$token" )
export rvm_autolibs_flag="${token#--autolibs=}"
forwarded_flags+=( "$token" )
;;
(--without-gems=*|--with-gems=*|--with-default-gems=*)
flags+=( "$token" )
value="${token#*=}"
token="${token%%=*}"
token="${token#--}"
token="${token//-/_}"
export "rvm_${token}"="${value}"
printf "%b" "Installing RVM ${token/_/ }: ${value}.\n"
;;
(--version|version)
version="$1"
shift
;;
(head|master)
version="head"
branch="master"
;;
(stable)
version="latest"
;;
(latest|latest-*|+([[:digit:]]).+([[:digit:]]).+([[:digit:]]))
version="$token"
;;
(--ruby)
install_rubies+=( ruby )
;;
(--ruby=*)
token=${token#--ruby=}
install_rubies+=( ${token//,/ } )
;;
(--rails)
install_gems+=( rails )
;;
(--gems=*)
token=${token#--gems=}
install_gems+=( ${token//,/ } )
;;
(--add-to-rvm-group)
export rvm_add_users_to_rvm_group="$1"
shift
;;
(help|usage)
usage
exit 0
;;
(*)
usage
exit 1
;;
esac
done
if (( ${#install_gems[@]} > 0 && ${#install_rubies[@]} == 0 ))
then install_rubies=( ruby )
fi
true "${version:=head}"
true "${branch:=master}"
if [[ -z "${sources[@]}" ]]
then sources=("${DEFAULT_SOURCES[@]}")
fi
rvm_src_path="$rvm_path/src"
rvm_archives_path="$rvm_path/archives"
rvm_releases_url="https://rvm.io/releases"
}
rvm_install_validate_rvm_path()
{
case "$rvm_path" in
(*[[:space:]]*)
printf "%b" "
It looks you are one of the happy *space* users(in home dir name),
RVM is not yet fully ready for it, use this trick to fix it:
sudo mkdir -p /${USER// /_}.rvm
sudo chown -R \"$USER:\" /${USER// /_}.rvm
echo \"export rvm_path=/${USER// /_}.rvm\" >> \"$HOME/.rvmrc\"
and start installing again.
"
exit 2
;;
(/usr/share/ruby-rvm)
printf "%b" "
It looks you are one of the happy Ubuntu users,
RVM packaged by Ubuntu is old and broken,
follow this link for details how to fix:
http://stackoverflow.com/a/9056395/497756
"
[[ "${rvm_uses_broken_ubuntu_path:-no}" == "yes" ]] || exit 3
;;
esac
if [[ "$rvm_path" != "/"* ]]
then fail "The rvm install path must be fully qualified. Tried $rvm_path"
fi
}
rvm_install_select_and_get_version()
{
typeset _version_release
for dir in "$rvm_src_path" "$rvm_archives_path"
do
[[ -d "$dir" ]] || mkdir -p "$dir"
done
_version_release="${version}"
case "${version}" in
(head)
_version_release="${branch}"
install_head sources[@] ${branch:-master} || exit $?
;;
(latest)
install_release sources[@] $(fetch_version sources[@]) || exit $?
;;
(latest-minor)
version="$(\cat "$rvm_path/VERSION")"
install_release sources[@] $(fetch_version sources[@] ${version%.*}) || exit $?
;;
(latest-*)
install_release sources[@] $(fetch_version sources[@] ${version#latest-}) || exit $?
;;
(+([[:digit:]]).+([[:digit:]]).+([[:digit:]])) # x.y.z
install_release sources[@] ${version} || exit $?
;;
(*)
fail "Something went wrong, unrecognized version '$version'"
;;
esac
echo "${_version_release}" > "$rvm_path/RELEASE"
}
rvm_install_main()
{
[[ -f ./scripts/install ]] ||
{
log "'./scripts/install' can not be found for installation, something went wrong, it usally means your 'tar' is broken, please report it here: https://github.com/wayneeseguin/rvm/issues"
return 127
}
# required flag - path to install
flags+=( --path "$rvm_path" )
\command bash "${flags[@]}"
}
rvm_install_ruby_and_gems()
(
if
(( ${#install_rubies[@]} > 0 ))
then
source ${rvm_scripts_path:-${rvm_path}/scripts}/rvm
source ${rvm_scripts_path:-${rvm_path}/scripts}/version
__rvm_version
for _ruby in ${install_rubies[@]}
do command rvm "${forwarded_flags[@]}" install ${_ruby} -j 2
done
# set the first one as default, skip rest
for _ruby in ${install_rubies[@]}
do
rvm "${forwarded_flags[@]}" alias create default ${_ruby}
break
done
for _gem in ${install_gems[@]}
do rvm "${forwarded_flags[@]}" all do gem install ${_gem}
done
printf "%b" "
* To start using RVM you need to run \`source $rvm_path/scripts/rvm\`
in all your open shell windows, in rare cases you need to reopen all shell windows.
"
if
[[ "${install_gems[*]}" == *"rails"* ]]
then
printf "%b" "
* To start using rails you need to run \`rails new <project_dir>\`.
"
fi
fi
)
rvm_install()
{
rvm_install_initialize
rvm_install_commands_setup
rvm_install_default_settings
rvm_install_parse_params "$@"
rvm_install_validate_rvm_path
rvm_install_select_and_get_version
rvm_install_main
rvm_install_ruby_and_gems
}
rvm_install "$@"

View File

@ -1,105 +0,0 @@
nailgun-log-directory:
file.directory:
- name: /var/log/nailgun
- makedirs: True
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
remote-log-directory:
file.directory:
- name: /var/log/remote
- makedirs: True
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
nailgun-user:
postgres_user.present:
- name: nailgun
- createdb: True
- createroles: True
- superuser: True
- password: nailgun
- require:
- pkg: packages
nailgun-db:
postgres_database.present:
- name: nailgun
- db_user: nailgun
- db_password: nailgun
- require:
- pkg: packages
- postgres_user: nailgun-user
/usr/bin/nailgun_clean_db.sh:
file.managed:
- source: salt://nailgun/nailgun_clean_db.sh
- mode: 0777
raemon-source:
git.latest:
- name: https://github.com/nulayer/raemon.git
- rev: b78eaae57c8e836b8018386dd96527b8d9971acc
- target: /home/vagrant/raemon
- user: vagrant
- group: vagrant
- unless: ls /home/vagrant/raemon
rvm-keys:
cmd.run:
- name: gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
get-rvm-io:
cmd.script:
- name: salt://nailgun/get-rvm-io.sh stable
- source: salt://nailgun/get-rvm-io.sh
- shell: /bin/bash
- unless: ls /usr/local/rvm
- require:
- cmd: rvm-keys
packages-ruby-2.1:
cmd.run:
- name: source /etc/profile.d/rvm.sh && rvm install 2.1
- unless: ls /usr/local/rvm/rubies/ruby-2.1.5/bin/ruby
- require:
- cmd: get-rvm-io
raemon-gem:
cmd.run:
- name: source /etc/profile.d/rvm.sh && rvm user gemsets && rvm gemset create astute && rvm use 2.1@astute && gem build raemon.gemspec && gem install raemon-0.3.0.gem && gem install bundler
- user: vagrant
- group: vagrant
- cwd: /home/vagrant/raemon
- unless: /home/vagrant/raemon/raemon-0.3.0.gem
- require:
- cmd: packages-ruby-2.1
- git: raemon-source
python-fuel-command:
cmd.run:
- name: python setup.py develop
- cwd: /sources/python-fuelclient
python-fuel-command-config-dir:
file.directory:
- name: /etc/fuel/client
- makedirs: True
python-fuel-command-config:
file.managed:
- name: /etc/fuel/client/config.yaml
- source: salt://nailgun/client-config.yaml
- require:
- file: python-fuel-command-config-dir
python-shotgun-command:
cmd.run:
- name: python setup.py develop
- cwd: /sources/fuel-web/shotgun
generate-shotgun-config-command:
file.managed:
- name: /usr/bin/generate_shotgun_config
- source: salt://nailgun/generate_shotgun_config
- mode: 0777

View File

@ -1,28 +0,0 @@
#!/bin/bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
sudo su postgres -c "psql -c \"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND datname = 'nailgun';\""
sudo su postgres -c "psql -c \"DROP DATABASE nailgun;\""
sudo su postgres -c "psql -c \"CREATE DATABASE nailgun WITH OWNER nailgun;\""
. /etc/bash_completion.d/virtualenvwrapper
workon fuel
cd /sources/fuel-web/nailgun
./manage.py syncdb
./manage.py loaddefault # It loads all basic fixtures listed in settings.yaml
./manage.py loaddata nailgun/fixtures/sample_environment.json # Loads fake nodes

View File

@ -1,20 +0,0 @@
#!/bin/bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
cd $HOME
git clone git://github.com/n1k0/casperjs.git
cd casperjs
git checkout tags/1.0.0-RC4
sudo ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs

View File

@ -1,41 +0,0 @@
npm-gulp:
cmd.run:
- name: npm install -g gulp
- unless: npm ls -g gulp
phantomjs:
cmd.run:
- name: npm install -g phantomjs
- unless: npm ls -g phantomjs
casperjs:
cmd.script:
- name: salt://npm/casperjs.sh
- cwd: {{ pillar['HOME'] }}
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
- creates: {{ pillar['HOME'] }}/casperjs
fuel-web-npm-install:
cmd.run:
- name: npm install
- cwd: /sources/fuel-web/nailgun
- require:
#- git: fuel-web-source
- cmd: npm-gulp
fuel-web-gulp:
cmd.run:
- name: gulp
- cwd: /sources/fuel-web/nailgun
- require:
- cmd: fuel-web-npm-install
fuel-web-owner:
file.directory:
- name: /sources/fuel-web
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
- recurse:
- user
- group

View File

@ -1,17 +0,0 @@
[alias]
co = checkout
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
gr = log --oneline --abbrev-commit --all --graph --decorate --color
grs = log --oneline --abbrev-commit --all --graph --decorate --color --simplify-by-decoration
hist = log --graph --full-history --all --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short
st = status
[color]
ui = true
diff = true
status = true
branch = true
[push]
default = upstream

View File

@ -1,77 +0,0 @@
packages-initial:
pkg.latest:
- pkgs:
- curl
pkgrepos:
cmd.run:
- name: curl -sL https://deb.nodesource.com/setup | bash -
- user: root
- group: root
- unless: ls /etc/apt/sources.list.d/nodesource.list
- shell: /bin/bash
- require:
- pkg: packages-initial
packages:
pkg.latest:
- pkgs:
- bundler
- build-essential
- debootstrap
- extlinux
- genisoimage
- git
- htop
- imagemagick
- isomd5sum
- kpartx
- libmysqlclient-dev
- libvirt-bin
- make
- nginx
- nodejs
- postgresql
- postgresql-server-dev-9.3
- python-dev
- python-ipaddr
- python-paramiko
- python-pip
- python-nose
- python-software-properties
- python-virtualenv
- python-yaml
- rsync
- ruby2.0
- ruby-dev
- rubygems-integration
- screen
- silversearcher-ag
- software-properties-common
- tmux
- unzip
- vim
- vim-nox
- virtualenvwrapper
- yum
- yum-utils
- require:
- cmd: pkgrepos
py26-fake-interpreter:
file.symlink:
- name: /usr/bin/python2.6
- target: /usr/bin/python2.7
gitconfig:
file.managed:
- name: {{ pillar['HOME'] }}/.gitconfig
- source: salt://packages/gitconfig
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
/etc/tmux.conf:
file.managed:
- source: salt://packages/tmux.conf
- require:
- pkg: packages

View File

@ -1,2 +0,0 @@
set -g default-command "$SHELL --login"
set -g default-shell $SHELL

View File

@ -1,15 +0,0 @@
postgresql-pg_hba:
file.managed:
- name: /etc/postgresql/9.3/main/pg_hba.conf
- source: salt://postgresql/pg_hba.conf
- require:
- pkg: packages
postgresql-service:
service:
- running
- name: postgresql
- enable: True
- reload: True
- watch:
- file: /etc/postgresql/9.3/main/pg_hba.conf

View File

@ -1,100 +0,0 @@
# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# Refer to the "Client Authentication" section in the PostgreSQL
# documentation for a complete description of this file. A short
# synopsis follows.
#
# This file controls: which hosts are allowed to connect, how clients
# are authenticated, which PostgreSQL user names they can use, which
# databases they can access. Records take one of these forms:
#
# local DATABASE USER METHOD [OPTIONS]
# host DATABASE USER ADDRESS METHOD [OPTIONS]
# hostssl DATABASE USER ADDRESS METHOD [OPTIONS]
# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS]
#
# (The uppercase items must be replaced by actual values.)
#
# The first field is the connection type: "local" is a Unix-domain
# socket, "host" is either a plain or SSL-encrypted TCP/IP socket,
# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a
# plain TCP/IP socket.
#
# DATABASE can be "all", "sameuser", "samerole", "replication", a
# database name, or a comma-separated list thereof. The "all"
# keyword does not match "replication". Access to replication
# must be enabled in a separate record (see example below).
#
# USER can be "all", a user name, a group name prefixed with "+", or a
# comma-separated list thereof. In both the DATABASE and USER fields
# you can also write a file name prefixed with "@" to include names
# from a separate file.
#
# ADDRESS specifies the set of hosts the record matches. It can be a
# host name, or it is made up of an IP address and a CIDR mask that is
# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
# specifies the number of significant bits in the mask. A host name
# that starts with a dot (.) matches a suffix of the actual host name.
# Alternatively, you can write an IP address and netmask in separate
# columns to specify the set of hosts. Instead of a CIDR-address, you
# can write "samehost" to match any of the server's own IP addresses,
# or "samenet" to match any address in any subnet that the server is
# directly connected to.
#
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that
# "password" sends passwords in clear text; "md5" is preferred since
# it sends encrypted passwords.
#
# OPTIONS are a set of options for the authentication in the format
# NAME=VALUE. The available options depend on the different
# authentication methods -- refer to the "Client Authentication"
# section in the documentation for a list of which options are
# available for which authentication methods.
#
# Database and user names containing spaces, commas, quotes and other
# special characters must be quoted. Quoting one of the keywords
# "all", "sameuser", "samerole" or "replication" makes the name lose
# its special character, and just match a database or username with
# that name.
#
# This file is read on server startup and when the postmaster receives
# a SIGHUP signal. If you edit the file on a running system, you have
# to SIGHUP the postmaster for the changes to take effect. You can
# use "pg_ctl reload" to do that.
# Put your actual configuration here
# ----------------------------------
#
# If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.
# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local all postgres peer
local all nailgun md5
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres peer
#host replication postgres 127.0.0.1/32 md5
#host replication postgres ::1/128 md5

View File

@ -1,111 +0,0 @@
sources-directory:
file.directory:
- name: /vagrant/sources
- makedirs: true
- require:
- pkg: packages
fuel-astute-source:
git.latest:
- name: https://github.com/stackforge/fuel-astute
- target: /vagrant/sources/fuel-astute
- unless: ls /vagrant/sources/fuel-astute
- require:
- file: sources-directory
fuel-devops-source:
git.latest:
- name: https://github.com/stackforge/fuel-devops
- target: /vagrant/sources/fuel-devops
- unless: ls /vagrant/sources/fuel-devops
- require:
- file: sources-directory
fuel-docs-source:
git.latest:
- name: https://github.com/stackforge/fuel-docs
- target: /vagrant/sources/fuel-docs
- unless: ls /vagrant/sources/fuel-docs
- require:
- file: sources-directory
fuel-library-source:
git.latest:
- name: https://github.com/stackforge/fuel-library
- target: /vagrant/sources/fuel-library
- unless: ls /vagrant/sources/fuel-library
- require:
- file: sources-directory
fuel-main-source:
git.latest:
- name: https://github.com/stackforge/fuel-main
- target: /vagrant/sources/fuel-main
- unless: ls /vagrant/sources/fuel-main
- require:
- file: sources-directory
fuel-ostf-source:
git.latest:
- name: https://github.com/stackforge/fuel-ostf
- target: /vagrant/sources/fuel-ostf
- unless: ls /vagrant/sources/fuel-ostf
- require:
- file: sources-directory
fuel-plugins-source:
git.latest:
- name: https://github.com/stackforge/fuel-plugins
- target: /vagrant/sources/fuel-plugins
- unless: ls /vagrant/sources/fuel-plugins
- require:
- file: sources-directory
fuel-qa-source:
git.latest:
- name: https://github.com/stackforge/fuel-qa
- target: /vagrant/sources/fuel-qa
- unless: ls /vagrant/sources/fuel-qa
- require:
- file: sources-directory
fuel-specs-source:
git.latest:
- name: https://github.com/stackforge/fuel-specs
- target: /vagrant/sources/fuel-specs
- unless: ls /vagrant/sources/fuel-specs
- require:
- file: sources-directory
fuel-web-source:
git.latest:
- name: https://github.com/stackforge/fuel-web
- target: /vagrant/sources/fuel-web
- unless: ls /vagrant/sources/fuel-web
- require:
- file: sources-directory
python-fuelclient:
git.latest:
- name: https://github.com/stackforge/python-fuelclient
- target: /vagrant/sources/python-fuelclient
- unless: ls /vagrant/sources/python-fuelclient
- require:
- file: sources-directory
rsync-sources:
cmd.run:
- name: rsync -az /vagrant/sources/ /sources
- creates: /sources/fuel-web # creates more but I think Salt doesn't support this
- require:
- git: fuel-astute-source
- git: fuel-docs-source
- git: fuel-devops-source
- git: fuel-library-source
- git: fuel-main-source
- git: fuel-ostf-source
- git: fuel-plugins-source
- git: fuel-qa-source
- git: fuel-specs-source
- git: fuel-web-source
- git: python-fuelclient

View File

@ -1,9 +0,0 @@
base:
'*':
- packages
- postgresql
- sources
- nailgun
- user
- virtualenv
- npm

View File

@ -1,21 +0,0 @@
vagrant-virtualenv-path:
file.append:
- name: {{ pillar['HOME'] }}/.bashrc
- text: export WORKON_HOME={{ pillar['HOME'] }}/.virtualenvs
- require:
- pkg: packages
vagrant-virtualenv-bash-source:
file.append:
- name: {{ pillar['HOME'] }}/.bashrc
- text: . /etc/bash_completion.d/virtualenvwrapper
- require:
- pkg: packages
- file: vagrant-virtualenv-path
vagrant-bash-profile:
file.managed:
- name: {{ pillar['HOME'] }}/.bash_profile
- source: salt://user/vagrant-bash-profile
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}

View File

@ -1,27 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# 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.
case $- in *i*) . ~/.bashrc;; esac
# Log tmux output to $HOME/logs. Current log name can be fetched by getting
# the value of TMUX_LOG_FILE variable in a tmux window
if [[ $TERM = "screen" ]] && [[ $(ps -p $PPID -o comm=) = "tmux" ]]; then
mkdir $HOME/logs 2> /dev/null
logname="$(date '+%d%m%Y%H%M%S').tmux.log"
export TMUX_LOG_FILE=$HOME/logs/${logname}
script -f $TMUX_LOG_FILE
exit
fi

View File

@ -1,34 +0,0 @@
fuel-virtualenv-dir:
file.directory:
- name: {{ pillar['HOME'] }}/.virtualenvs
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
- makedirs: True
fuel-virtualenv:
virtualenv.managed:
- name: {{ pillar['HOME'] }}/.virtualenvs/fuel
- user: {{ pillar['USER'] }}
- require:
- file: fuel-virtualenv-dir
fuel-virtualenv-requirements:
cmd.script:
- name: salt://virtualenv/virtualenv-requirements.sh
- shell: /bin/bash
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
- cwd: {{ pillar['HOME'] }}
#- creates: {{ pillar['HOME'] }}/.virtualenvs/fuel
- require:
- virtualenv: fuel-virtualenv
fuel-virtualenv-postactivate-script:
file.managed:
- name: {{ pillar['HOME'] }}/.virtualenvs/fuel/bin/postactivate
- source: salt://virtualenv/postactivate
- group: {{ pillar['GROUP'] }}
- user: {{ pillar['USER'] }}
- mode: 744
- require:
- virtualenv: fuel-virtualenv

View File

@ -1,22 +0,0 @@
#!/bin/bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
export WORK_DIR=/sources/fuel-web
export PYTHONPATH=$WORK_DIR/nailgun
. /etc/profile.d/rvm.sh
cd $WORK_DIR

View File

@ -1,25 +0,0 @@
#!/bin/bash
# Copyright 2015 Mirantis, Inc.
#
# 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.
. /etc/bash_completion.d/virtualenvwrapper
workon fuel
pip install /sources/fuel-web/shotgun # this Fuel project is listed in setup.py requirements
pip install -r /sources/fuel-web/nailgun/requirements.txt
pip install tox
pip install ipython
pip install pudb

View File

@ -1,5 +0,0 @@
file_client: local
pillar_roots:
base:
- /srv/pillar