| ID | Name | Status | Task State | Power State | Networks |
+----+------------+--------+------------+-------------+-------------------------+
+----+------------+--------+------------+-------------+-------------------------+
-* upload your ssh public key with::
+* create a passwordless ssh public key with::
- $ openstack keypair create --public-key ~/.ssh/id_rsa.pub myself
+ $ openstack keypair create myself > myself.pem
+-------------+-------------------------------------------------+
| Field | Value |
+-------------+-------------------------------------------------+
| name | myself |
| user_id | 5cf9fa21b2e9406b9c4108c42aec6262 |
+-------------+-------------------------------------------------+
+ $ chmod 600 myself.pem
Usage
-----
-* Run the dummy suite as a test (``myself`` is a keypair created as
- explained in the previous section)::
+* Create a passwordless ssh public key::
- $ teuthology-openstack --key-name myself --suite dummy
+ $ openstack keypair create myself > myself.pem
+ $ chmod 600 myself.pem
+
+* Run the dummy suite (it does nothing useful but shows all works as
+ expected)::
+
+ $ teuthology-openstack --key-filename myself.pem --key-name myself --suite dummy
Job scheduled with name ubuntu-2015-07-24_09:03:29-dummy-master---basic-openstack and ID 1
2015-07-24 09:03:30,520.520 INFO:teuthology.suite:ceph sha1: dedda6245ce8db8828fdf2d1a2bfe6163f1216a1
2015-07-24 09:03:31,620.620 INFO:teuthology.suite:ceph version: v9.0.2-829.gdedda62
* The virtual machine running the suite will persist for forensic
analysis purposes. To destroy it run::
- $ teuthology-openstack --key-name myself --teardown
+ $ teuthology-openstack --key-filename myself.pem --key-name myself --teardown
+
+* The test results can be uploaded to a publicly accessible location
+ with the ``--upload`` flag::
+
+ $ teuthology-openstack --key-filename myself.pem --key-name myself \
+ --suite dummy --upload
+
Running the OpenStack backend integration tests
-----------------------------------------------
The easiest way to run the integration tests is to first run a dummy suite::
$ teuthology-openstack --key-name myself --suite dummy
+ ...
+ ssh access : ssh ubuntu@167.114.242.13
-This will create a virtual machine suitable for running the
-integration tests. Once logged in the virtual machine:
+This will create a virtual machine suitable for the integration
+test. Login wih the ssh access displayed at the end of the
+``teuthology-openstack`` command and run the following::
$ pkill -f teuthology-worker
$ cd teuthology ; pip install "tox>=1.9"
action='store_true', default=None,
help='destroy the cluster, if it exists',
)
+ parser.add_argument(
+ '--upload',
+ action='store_true', default=False,
+ help='upload archives to an rsync server',
+ )
+ parser.add_argument(
+ '--archive-upload',
+ help='rsync destination to upload archives',
+ default='ubuntu@integration.ceph.dachary.org:./',
+ )
# copy/pasted from scripts/suite.py
parser.add_argument(
'config_yaml',
--filter-out KEYWORDS Do not run jobs whose description contains any of
the keywords in the comma separated keyword
string specified.
+ --archive-upload RSYNC_DEST Rsync destination to upload archives.
""".format(default_machine_type=config.default_machine_type,
default_results_timeout=config.results_timeout)
yaml_path = os.path.join(os.path.expanduser('~/.teuthology.yaml'))
_defaults = {
'archive_base': '/var/lib/teuthworker/archive',
+ 'archive_upload': None,
+ 'archive_upload_key': None,
'automated_scheduling': False,
'reserve_machines': 5,
'ceph_git_base_url': 'https://github.com/ceph/',
a['RAM'] - b['RAM'] or
a['Disk'] - b['Disk'])
sorted_flavor = sorted(found, cmp=sort_flavor)
- log.info("sorted flavor = " + str(sorted_flavor))
+ log.debug("sorted flavor = " + str(sorted_flavor))
return sorted_flavor[0]['Name']
def cloud_init_wait(self, name_or_ip):
ip = self.setup()
if self.args.suite:
self.run_suite()
+ if self.args.key_filename:
+ identity = '-i ' + self.args.key_filename + ' '
+ else:
+ identity = ''
+ if self.args.upload:
+ upload = 'upload to : ' + self.args.archive_upload
+ else:
+ upload = ''
log.info("""
web interface: http://{ip}:8081/
-ssh access : ssh {username}@{ip} # logs in /usr/share/nginx/html
- """.format(ip=ip,
- username=self.username))
+ssh access : ssh {identity}{username}@{ip} # logs in /usr/share/nginx/html
+{upload}""".format(ip=ip,
+ username=self.username,
+ identity=identity,
+ upload=upload))
if self.args.teardown:
self.teardown()
argv = []
while len(original_argv) > 0:
if original_argv[0] in ('--name',
+ '--archive-upload',
'--key-name',
'--key-filename',
'--simultaneous-jobs'):
del original_argv[0:2]
- elif original_argv[0] in ('--teardown'):
+ elif original_argv[0] in ('--teardown',
+ '--upload'):
del original_argv[0]
else:
argv.append(original_argv.pop(0))
for (var, value) in os.environ.iteritems():
if var.startswith('OS_'):
openrc += ' ' + var + '=' + value
+ if self.args.upload:
+ upload = '--archive-upload ' + self.args.archive_upload
+ else:
+ upload = ''
log.debug("OPENRC = " + openrc + " " +
"TEUTHOLOGY_USERNAME = " + self.username + " " +
+ "UPLOAD = " + upload + " " +
"NWORKERS = " + str(self.args.simultaneous_jobs))
content = (template.
replace('OPENRC', openrc).
replace('TEUTHOLOGY_USERNAME', self.username).
+ replace('UPLOAD', upload).
replace('NWORKERS', str(self.args.simultaneous_jobs)))
open(path, 'w').write(content)
log.debug("get_user_data: " + content + " written to " + path)
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAvLz+sao32JL/yMgwTFDTnQVZK3jyXlhQJpHLsgwgHWHQ/27L
+fwEbGFVYsJNBGntZwCZvH/K4c0IevbnX/Y69qgmAc9ZpZQLIcIF0A8hmwVYRU+Ap
+TAK2qAvadThWfiRBA6+SGoRy6VV5MWeq+hqlGf9axRKqhECNhHuGBuBeosUOZOOH
+NVzvFIbp/4842yYrZUDnDzW7JX2kYGi6kaEAYeR8qYJgT/95Pm4Bgu1V7MI36rx1
+O/5BSPF3LvDSnnaZyHCDZtwzC50lBnS2nx8kKPmmdKBSEJoTdNRPIXZ/lMq5pzIW
+QPDjI8O5pbX1BJcxfFlZ/h+bI6u8IX3vfTGHWwIDAQABAoIBAG5yLp0rHfkXtKT7
+OQA/wEW/znmZEkPRbD3VzZyIafanuhTv8heFPyTTNM5Hra5ghpniI99PO07/X1vp
+OBMCB81MOCYRT6WzpjXoG0rnZ/I1enhZ0fDQGbFnFlTIPh0c/Aq7IEVyQoh24y/d
+GXm4Q+tdufFfRfeUivv/CORXQin/Iugbklj8erjx+fdVKPUXilmDIEVleUncer5/
+K5Fxy0lWbm6ZX1fE+rfJvCwNjAaIJgrN8TWUTE8G72F9Y0YU9hRtqOZe6MMbSufy
+5+/yj2Vgp+B8Id7Ass2ylDQKsjBett/M2bNKt/DUVIiaxKi0usNSerLvtbkWEw9s
+tgUI6ukCgYEA6qqnZwkbgV0lpj1MrQ3BRnFxNR42z2MyEY5xRGaYp22ByxS207z8
+mM3EuLH8k2u6jzsGoPpBWhBbs97MuGDHwsMEO5rBpytnTE4Hxrgec/13Arzk4Bme
+eqg1Ji+lNkoLzEHkuihskcZwnQ8uaOdqrnH/NRGuUhA9hjeh+lQzBy8CgYEAzeV1
+zYsw8xIBFtbmFhBQ8imHr0SQalTiQU2Qn46LORK0worsf4sZV5ZF3VBRdnCUwwbm
+0XaMb3kE2UBlU8qPqLgxXPNjcEKuqtVlp76dT/lrXIhYUq+Famrf20Lm01kC5itz
+QF247hnUfo2uzxpatuEr2ggs2NjuODn57tVw95UCgYEAv0s+C5AxC9OSzWFLEAcW
+dwYi8toedBC4z/b9/nRkHJf4JkRMhW6ZuzaCFs2Ax+wZuIi1bqSSgYi0OHx3BhZe
+wTWYTb5p/owzONCjJisRKByG14SETuqTdgmIyggs9YSG+Yr9mYM6fdr2EhI+EuYS
+4QGsuOYg5GS4wqC3OglJT6ECgYA8y28QRPQsIXnO259OjnzINDkLKGyX6P5xl8yH
+QFidfod/FfQk6NaPxSBV67xSA4X5XBVVbfKji5FB8MC6kAoBIHn63ybSY+4dJSuB
+70eV8KihxuSFbawwMuRsYoGzkAnKGrRKIiJTs67Ju14NatO0QiJnm5haYxtb4MqK
+md1kTQKBgDmTxtSBVOV8eMhl076OoOvdnpb3sy/obI/XUvurS0CaAcqmkVSNJ6c+
+g1O041ocTbuW5d3fbzo9Jyle6qsvUQd7fuoUfAMrd0inKsuYPPM0IZOExbt8QqLI
+KFJ+r/nQYoJkmiNO8PssxcP3CMFB6TpUx0BgFcrhH//TtKKNrGTl
+-----END RSA PRIVATE KEY-----
--- /dev/null
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8vP6xqjfYkv/IyDBMUNOdBVkrePJeWFAmkcuyDCAdYdD/bst/ARsYVViwk0Eae1nAJm8f8rhzQh69udf9jr2qCYBz1mllAshwgXQDyGbBVhFT4ClMAraoC9p1OFZ+JEEDr5IahHLpVXkxZ6r6GqUZ/1rFEqqEQI2Ee4YG4F6ixQ5k44c1XO8Uhun/jzjbJitlQOcPNbslfaRgaLqRoQBh5HypgmBP/3k+bgGC7VXswjfqvHU7/kFI8Xcu8NKedpnIcINm3DMLnSUGdLafHyQo+aZ0oFIQmhN01E8hdn+UyrmnMhZA8OMjw7mltfUElzF8WVn+H5sjq7whfe99MYdb loic@fold
packages:
- python-virtualenv
- git
+ - rsync
runcmd:
- su - -c '(set -x ; git clone -b wip-6502-openstack-v3 http://github.com/dachary/teuthology && cd teuthology && ./bootstrap install)' TEUTHOLOGY_USERNAME >> /tmp/init.out 2>&1
- echo 'export OPENRC' | tee /home/TEUTHOLOGY_USERNAME/openrc.sh
- - su - -c '(set -x ; source openrc.sh ; cd teuthology ; source virtualenv/bin/activate ; openstack keypair delete teuthology || true ; teuthology/openstack/setup-openstack.sh --nworkers NWORKERS --setup-all)' TEUTHOLOGY_USERNAME >> /tmp/init.out 2>&1
+ - su - -c '(set -x ; source openrc.sh ; cd teuthology ; source virtualenv/bin/activate ; openstack keypair delete teuthology || true ; teuthology/openstack/setup-openstack.sh --nworkers NWORKERS UPLOAD --setup-all)' TEUTHOLOGY_USERNAME >> /tmp/init.out 2>&1
- /etc/init.d/teuthology restart
final_message: "teuthology is up and running after $UPTIME seconds"
local labdomain="$4"
local ip="$5"
local flavor_select="$6"
+ local archive_upload="$7"
if test "$flavor_select" ; then
flavor_select="flavor-select-regexp: $flavor_select"
network="network: $network"
fi
+ if test "$archive_upload" ; then
+ archive_upload="archive_upload: $archive_upload"
+ fi
+
cat > ~/.teuthology.yaml <<EOF
+$archive_upload
+archive_upload_key: teuthology/openstack/archive-key
lock_server: http://localhost:8080/
results_server: http://localhost:8080/
queue_port: 11300
fi
}
+function setup_authorized_keys() {
+ cat teuthology/openstack/archive-key.pub >> ~/.ssh/authorized_keys
+ chmod 600 teuthology/openstack/archive-key
+ echo "APPEND to ~/.ssh/authorized_keys"
+}
+
function setup_bootscript() {
local nworkers=$1
local nworkers=2
local flavor_select
local keypair=teuthology
+ local archive_upload
local do_setup_keypair=false
local do_create_config=false
shift
nworkers=$1
;;
+ --archive-upload)
+ shift
+ archive_upload=$1
+ ;;
--install)
do_install_packages=true
;;
: ${nameserver:=$ip}
if $do_create_config ; then
- create_config "$network" "$subnet" "$nameserver" "$labdomain" "$ip" "$flavor_select" || return 1
+ create_config "$network" "$subnet" "$nameserver" "$labdomain" "$ip" "$flavor_select" "$archive_upload" || return 1
setup_ansible $subnet $labdomain || return 1
setup_ssh_config || return 1
+ setup_authorized_keys || return 1
setup_bashrc || return 1
setup_bootscript $nworkers || return 1
fi
import scripts.schedule
import scripts.lock
import scripts.suite
+from teuthology.config import config as teuth_config
class Integration(object):
def test_suite_noop(self):
cwd = os.getcwd()
+ os.mkdir(self.d + '/upload', 0o755)
+ upload = 'localhost:' + self.d + '/upload'
args = ['--suite', 'noop',
'--suite-dir', cwd + '/teuthology/openstack/test',
'--machine-type', 'openstack',
+ '--archive-upload', upload,
'--verbose']
logging.info("TestSuite:test_suite_noop")
scripts.suite.main(args)
log = self.get_teuthology_log()
assert "teuthology.run:pass" in log
assert "Well done" in log
+ upload_key = teuth_config.archive_upload_key
+ if upload_key:
+ ssh = "RSYNC_RSH='ssh -i " + upload_key + "'"
+ else:
+ ssh = ''
+ assert 'teuthology.log' in teuthology.misc.sh(ssh + " rsync -av " + upload)
def test_suite_nuke(self):
cwd = os.getcwd()
misc.sh("openstack ip floating delete " + ip_id)
self.can_create_floating_ips = True
else:
- self.can_create_floating_ips = True
+ self.can_create_floating_ips = False
def setup(self):
self.key_filename = tempfile.mktemp()
'--filter', 'trasher',
'--filter-out', 'erasure-code',
]
- argv = self.options + teuthology_argv
+ argv = (self.options +
+ ['--upload',
+ '--archive-upload', 'user@archive:/tmp'] +
+ teuthology_argv)
args = scripts.openstack.parse_args(argv)
teuthology = TeuthologyOpenStack(args, None, argv)
teuthology.user_data = 'teuthology/openstack/test/user-data-test1.txt'
variables = teuthology.ssh("grep 'substituded variables' /var/log/cloud-init.log")
assert "nworkers=" + str(args.simultaneous_jobs) in variables
assert "username=" + teuthology.username in variables
+ assert "upload=--archive-upload user@archive:/tmp" in variables
assert os.environ['OS_AUTH_URL'] in variables
out, err = capsys.readouterr()
system_info:
default_user:
name: ubuntu
-final_message: "teuthology is up and running after $UPTIME seconds, substituded variables nworkers=NWORKERS openrc=OPENRC username=TEUTHOLOGY_USERNAME"
+final_message: "teuthology is up and running after $UPTIME seconds, substituded variables nworkers=NWORKERS openrc=OPENRC username=TEUTHOLOGY_USERNAME upload=UPLOAD"
{'internal.base': None},
{'internal.archive': None},
{'internal.coredump': None},
+ {'internal.archive_upload': None},
{'internal.sudo': None},
{'internal.syslog': None},
{'internal.timer': None},
email = args['--email']
if email:
config.results_email = email
+ if args['--archive-upload']:
+ config.archive_upload = args['--archive-upload']
+ log.info('Will upload archives to ' + args['--archive-upload'])
timeout = args['--timeout']
filter_in = args['--filter']
filter_out = args['--filter-out']
teuthology_branch=teuthology_branch,
machine_type=machine_type,
distro=distro,
+ archive_upload=config.archive_upload,
+ archive_upload_key=config.archive_upload_key,
)
conf_dict = substitute_placeholders(dict_templ, config_input)
conf_dict.update(kernel_dict)
'branch': Placeholder('ceph_branch'),
'sha1': Placeholder('ceph_hash'),
'teuthology_branch': Placeholder('teuthology_branch'),
+ 'archive_upload': Placeholder('archive_upload'),
+ 'archive_upload_key': Placeholder('archive_upload_key'),
'machine_type': Placeholder('machine_type'),
'nuke-on-error': True,
'os_type': Placeholder('distro'),
'Found coredumps on {rem}'.format(rem=rem)
+@contextlib.contextmanager
+def archive_upload(ctx, config):
+ """
+ Upload the archive directory to a designated location
+ """
+ try:
+ yield
+ finally:
+ upload = ctx.config.get('archive_upload')
+ archive_path = ctx.config.get('archive_path')
+ if upload and archive_path:
+ log.info('Uploading archives ...')
+ upload_key = ctx.config.get('archive_upload_key')
+ if upload_key:
+ ssh = "RSYNC_RSH='ssh -i " + upload_key + "'"
+ else:
+ ssh = ''
+ split_path = archive_path.split('/')
+ split_path.insert(-2, '.')
+ misc.sh(ssh + " rsync -avz --relative /" +
+ os.path.join(*split_path) + " " +
+ upload)
+ else:
+ log.info('Not uploading archives.')
+
@contextlib.contextmanager
def syslog(ctx, config):
"""
teuthology_branch='teuthology_branch',
machine_type='machine_type',
distro='distro',
+ archive_upload='archive_upload',
+ archive_upload_key='archive_upload_key',
)
output_dict = suite.substitute_placeholders(suite.dict_templ,
input_dict)
ceph_hash='ceph_hash',
teuthology_branch='teuthology_branch',
machine_type='machine_type',
+ archive_upload='archive_upload',
+ archive_upload_key='archive_upload_key',
distro=None,
)
output_dict = suite.substitute_placeholders(suite.dict_templ,