Use libcloud just to get a very basic node. Then use paramiko ssh and scp commands to do the rest of the bootstrap. Also, split the auth variables to allow for different DNS auth. Change-Id: I634388ff5ed42e624021fc930a4e95812fe516f2
165 lines
6.1 KiB
Python
165 lines
6.1 KiB
Python
#!/usr/bin/env python
|
|
|
|
# Turn over a devstack configured machine to the developer who
|
|
# proposed the change that is being tested.
|
|
|
|
# Copyright (C) 2011 OpenStack LLC.
|
|
#
|
|
# 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 libcloud.compute.base import NodeImage, NodeSize, NodeLocation
|
|
from libcloud.compute.types import Provider
|
|
from libcloud.compute.providers import get_driver
|
|
from libcloud.compute.deployment import MultiStepDeployment, ScriptDeployment, SSHKeyDeployment
|
|
from libcloud.dns.types import Provider as DnsProvider
|
|
from libcloud.dns.types import RecordType
|
|
from libcloud.dns.providers import get_driver as dns_get_driver
|
|
import os, sys
|
|
import getopt
|
|
import paramiko
|
|
|
|
CLOUD_SERVERS_DRIVER = os.environ.get('CLOUD_SERVERS_DRIVER','rackspace')
|
|
CLOUD_SERVERS_USERNAME = os.environ['CLOUD_SERVERS_USERNAME']
|
|
CLOUD_SERVERS_API_KEY = os.environ['CLOUD_SERVERS_API_KEY']
|
|
CLOUD_SERVERS_HOST = os.environ.get('CLOUD_SERVERS_HOST', None)
|
|
CLOUD_SERVERS_PATH = os.environ.get('CLOUD_SERVERS_PATH', None)
|
|
DNS_CLOUD_SERVERS_USERNAME = os.environ.get('DNS_CLOUD_SERVERS_USERNAME',
|
|
CLOUD_SERVERS_USERNAME)
|
|
DNS_CLOUD_SERVERS_API_KEY = os.environ.get('DNS_CLOUD_SERVERS_API_KEY',
|
|
CLOUD_SERVERS_API_KEY)
|
|
def ssh(action, x):
|
|
stdin, stdout, stderr = client.exec_command(x)
|
|
print x
|
|
output = ''
|
|
for x in stdout:
|
|
output += x
|
|
sys.stdout.write(x)
|
|
ret = stdout.channel.recv_exit_status()
|
|
print stderr.read()
|
|
if ret:
|
|
raise Exception("Unable to %s" % action)
|
|
return output
|
|
|
|
def scp(source, dest):
|
|
print 'copy', source, dest
|
|
ftp = client.open_sftp()
|
|
ftp.put(source, dest)
|
|
ftp.close()
|
|
|
|
(option_pairs, args) = getopt.getopt(sys.argv[1:], '', ["image=", "nodns"])
|
|
|
|
DNS = True
|
|
for o,v in option_pairs:
|
|
if o=='--nodns':
|
|
DNS = False
|
|
|
|
if len(args) == 0:
|
|
print "Node Name required!"
|
|
sys.exit(1)
|
|
host_name = args[0]
|
|
node_name = "%s.slave.openstack.org" % host_name
|
|
|
|
|
|
node_size = '3'
|
|
image_name = 'Ubuntu 11.10'
|
|
if CLOUD_SERVERS_DRIVER == 'rackspace':
|
|
for (name, value) in option_pairs:
|
|
if name == "--image":
|
|
image_name = value
|
|
|
|
Driver = get_driver(Provider.RACKSPACE)
|
|
conn = Driver(CLOUD_SERVERS_USERNAME, CLOUD_SERVERS_API_KEY)
|
|
images = conn.list_images()
|
|
|
|
size = [sz for sz in conn.list_sizes() if sz.id == node_size][0]
|
|
image = [img for img in conn.list_images() if img.name == image_name][0]
|
|
|
|
elif CLOUD_SERVERS_DRIVER == 'eucalyptus':
|
|
node_type = 'ami-000004da'
|
|
node_size = 'standard.small'
|
|
Driver = get_driver(Provider.EUCALYPTUS)
|
|
conn = Driver(CLOUD_SERVERS_USERNAME, CLOUD_SERVERS_API_KEY,
|
|
host=CLOUD_SERVERS_HOST, path=CLOUD_SERVERS_PATH)
|
|
image = NodeImage(id=node_type, name="", driver="")
|
|
size = NodeSize(id=node_size, name="", ram=None, disk=None,
|
|
bandwidth=None, price=None, driver="")
|
|
|
|
|
|
# a task that first installs the ssh key, and then runs the script
|
|
if CLOUD_SERVERS_DRIVER == 'rackspace':
|
|
# read your public key in
|
|
keypath = os.path.expanduser("~/.ssh/id_rsa.pub")
|
|
if not os.path.exists(keypath):
|
|
keypath = os.path.expanduser("~/.ssh/authorized_keys")
|
|
sd = SSHKeyDeployment(open(keypath).read())
|
|
else:
|
|
private_key_path = os.path.expanduser("~/.ssh/%s.pem" % node_name)
|
|
if not os.path.exists(private_key_path):
|
|
resp = conn.ex_create_keypair(name=node_name)
|
|
key_material = resp.get('keyMaterial')
|
|
if not key_material:
|
|
print "Couldn't create keypair"
|
|
sys.exit(1)
|
|
with open(private_key_path, 'w') as private_key:
|
|
private_key.write(key_material + '\n')
|
|
os.chmod(private_key_path, 0600)
|
|
|
|
# deploy_node takes the same base keyword arguments as create_node.
|
|
if CLOUD_SERVERS_DRIVER == 'rackspace':
|
|
print "Deploying %s" % node_name
|
|
node = conn.deploy_node(name=node_name, image=image, size=size, deploy=sd)
|
|
else:
|
|
node = conn.create_node(name=node_name, image=image, size=size,
|
|
ex_keyname=node_name, ex_userdata=launch_script)
|
|
|
|
if DNS:
|
|
dns_provider = dns_get_driver(DnsProvider.RACKSPACE_US)
|
|
dns_ctx = dns_provider(DNS_CLOUD_SERVERS_USERNAME,
|
|
DNS_CLOUD_SERVERS_API_KEY)
|
|
|
|
host_shortname= "%s.slave" % host_name
|
|
domain = [z for z in dns_ctx.list_zones() if z.domain == 'openstack.org'][0]
|
|
|
|
records = [z for z in domain.list_records() if z == host_shortname]
|
|
if len(records) == 0:
|
|
domain.create_record(host_shortname, RecordType.A, node.public_ip[0])
|
|
else:
|
|
records[0].update(data=node.public_ip[0])
|
|
|
|
with open("%s.node.sh" % node_name,"w") as node_file:
|
|
node_file.write("ipAddr=%s\n" % node.public_ip[0])
|
|
node_file.write("nodeId=%s\n" % node.id)
|
|
|
|
client = paramiko.SSHClient()
|
|
client.load_system_host_keys()
|
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
client.connect(node.public_ip[0])
|
|
|
|
if CLOUD_SERVERS_DRIVER == 'eucalyptus':
|
|
ssh("set hostname", "hostname %s" % node_name)
|
|
|
|
ssh("update apt cache", "apt-get update")
|
|
ssh("upgrading system packages", "apt-get -y --force-yes upgrade")
|
|
ssh("install git and puppet", "apt-get install -y --force-yes git puppet")
|
|
ssh("clone puppret repo",
|
|
"git clone https://review.openstack.org/p/openstack/openstack-ci-puppet.git /root/openstack-ci-puppet")
|
|
|
|
for key in ("slave_private_key", "slave_gpg_key", "slave_tarmac_key",
|
|
"glance_s3.conf", "glance_swift.conf"):
|
|
scp(key, "/root/openstack-ci-puppet/modules/jenkins_slave/files/%s" % key)
|
|
ssh("run puppet", "puppet apply --modulepath=/root/openstack-ci-puppet/modules /root/openstack-ci-puppet/manifests/site.pp")
|
|
|
|
client.close()
|