Skip to content

Instantly share code, notes, and snippets.

@themartorana
Created May 17, 2011 15:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save themartorana/976729 to your computer and use it in GitHub Desktop.
Save themartorana/976729 to your computer and use it in GitHub Desktop.
build.py
import os, sys
import datetime
import base64
import cloudservers
import cloudlb
import urllib2
#import paramiko
from time import sleep
from conf import settings
PGSQL_DATABASE_SERVER_ADDRESS = '10.XXX.XXX.XXX'
def get_server_image(cs, image_name):
i = cs.images.find(name=image_name)
return i
def get_flavor(cs, ram_size):
return cs.flavors.find(ram=ram_size)
def get_file_contents(file_name):
contents = open(file_name, 'r').read()
return contents
def create_server(cs, image_name, ram_size):
now = datetime.datetime.now()
server_name = 'HAE-%s' % (now.strftime('%Y%m%d-%H%M%S'))
print 'Creating server %s' % server_name
image = get_server_image(cs, image_name)
if not image:
raise Exception('Could not get server image "%s"' % image_name)
flavor = get_flavor(cs, ram_size)
if not flavor:
raise Exception('Could not get flavor with %s ram' % ram_size)
server = cs.servers.create(
server_name,
image,
flavor,
files={
'/etc/rc.local': get_file_contents('build/etc/rc.local'),
'/etc/rc.local.stage1': get_file_contents('build/etc/rc.local.stage1'),
'/etc/cron.d/initialrunner': get_file_contents('build/etc/cron.d/initialrunner'),
}
)
return server
def wait_for_server(cs, s, with_url_ping=False):
while s.status != 'ACTIVE':
sleep(10)
s = cs.servers.get(s.id)
print '%s: %s (%s%%)' % (s.id, s.status, s.progress)
if with_url_ping:
# Wait for a response
url = 'http://%s/content/images/logo.png' % s.public_ip
tries = 0
while True:
try:
print 'Attempting to connect to %s' % url
urllib2.urlopen(url)
print 'ping success, returning'
break
except urllib2.HTTPError, e:
print e
if e.code == 401:
print '401 not authorized'
elif e.code == 404:
print '404 not found... waiting...'
elif e.code == 503:
print '503 service unavailable'
else:
print 'unknown error: %s' % e
sleep(30)
except urllib2.URLError, u:
print u
print 'Connection refused for now...'
sleep(30)
tries += 1
if tries > 20: # 10 minutes
raise Exception('URL ping timed out')
def replace_servers(clb, cs, new_servers):
virtual_ip = None
virtual_ip_new = False
existing_load_balancers = clb.loadbalancers.list()
# New nodes
new_http_nodes = [cloudlb.Node(address=server.private_ip, port=80, condition="ENABLED") for server in new_servers]
new_https_nodes = [cloudlb.Node(address=server.private_ip, port=443, condition="ENABLED") for server in new_servers]
if len(existing_load_balancers) == 0:
print 'No load balancers, adding them'
virtual_ip = cloudlb.VirtualIP(type='PUBLIC')
virtual_ip_new = True
print 'Creating HTTP load balancer'
lb = clb.loadbalancers.create(
name='hae-web-http',
port=80,
protocol='HTTP',
nodes=new_http_nodes,
virtualIps=[virtual_ip]
)
if virtual_ip_new:
virtual_ip = lb.virtual_ips()[0]
print 'Virtual IP: %s' % virtual_ip
print 'Creating HTTPS load balancer'
lb = clb.loadbalancers.create(
name='hae-web-https',
port=443,
protocol='HTTPS',
nodes=new_https_nodes,
virtualIps=[virtual_ip]
)
else:
print 'Load balancers exist, adding/removing servers'
# Replace servers where necessary
http_lb = clb.loadbalancers.find(name='hae-web-http')
https_lb = clb.loadbalancers.find(name='hae-web-https')
existing_http_nodes = http_lb.nodes
existing_https_nodes = https_lb.nodes
if not http_lb or not https_lb:
raise Exception("Cannot find both the http and https load balancers!")
print '\nSwitching out HTTP servers'
print 'Adding nodes %s' % new_http_nodes
http_lb.add_nodes(new_http_nodes)
print '\nSwitching out HTTP servers'
print 'Adding nodes %s' % new_https_nodes
https_lb.add_nodes(new_https_nodes)
print 'Sleeping to allow the load balancers time to stat'
sleep(20)
print 'Deleting old nodes'
for node in existing_http_nodes:
print 'Deleting http node %s' % node
node.delete()
for node in existing_https_nodes:
print 'Deleting https node %s' % node
node.delete()
print 'Deleting old servers'
for node in existing_http_nodes:
server = cs.servers.find(private_ip=node.address)
server.delete()
if __name__ == '__main__':
cs = cloudservers.CloudServers(settings.CLOUDSERVERS_USERNAME, settings.CLOUDSERVERS_API_KEY)
s = create_server(cs, 'Ubuntu 10.10 (maverick)', 512)
wait_for_server(cs, s, with_url_ping=False)
print 'Server IP is %s (private: %s)' % (s.public_ip, s.private_ip)
sleep(20)
s.update(password='YOUR_PASSWORD_HERE')
try:
wait_for_server(cs, s, with_url_ping=True)
except:
# Kill the server
s.delete()
raise Exception('Server never finished')
if s:
clb = cloudlb.CloudLoadBalancer(
settings.CLOUDSERVERS_USERNAME,
settings.CLOUDSERVERS_API_KEY,
settings.CLOUDSERVERS_DATA_CENTER
)
replace_servers(clb, cs, [s])
print 'Exiting with 0'
sys.exit(0)
@ericcholis
Copy link

Found this from your blog post. Thanks, I'm defiantly going to rip the Cloud Load Balancer sections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment