diff --git a/firstapp/samples/shade/scaling_out.py b/firstapp/samples/shade/scaling_out.py new file mode 100644 index 000000000..a02b42e90 --- /dev/null +++ b/firstapp/samples/shade/scaling_out.py @@ -0,0 +1,107 @@ +# step-1 +for instance in conn.list_servers(): + if instance.name in ['all-in-one','app-worker-1', 'app-worker-2', 'app-controller']: + print('Destroying Instance: %s' % instance.name) + conn.delete_server(instance.id, wait=True) + +for group in conn.list_security_groups(): + if group['name'] in ['control', 'worker', 'api', 'services']: + print('Deleting security group: %s' % group['name']) + conn.delete_security_group(group['name']) + +# step-2 +api_group = conn.create_security_group('api', 'for API services only') +conn.create_security_group_rule(api_group['name'], 80, 80, 'TCP') +conn.create_security_group_rule(api_group['name'], 22, 22, 'TCP') + +worker_group = conn.create_security_group('worker', 'for services that run on a worker node') +conn.create_security_group_rule(worker_group['name'], 22, 22, 'TCP') + +services_group = conn.create_security_group('services', 'for DB and AMQP services only') +conn.create_security_group_rule(services_group['name'], 22, 22, 'TCP') +conn.create_security_group_rule(services_group['name'], 3306, 3306, 'TCP', remote_group_id=api_group['id']) +conn.create_security_group_rule(services_group['name'], 5672, 5672, 'TCP', remote_group_id=worker_group['id']) +conn.create_security_group_rule(services_group['name'], 5672, 5672, 'TCP', remote_group_id=api_group['id']) + +# step-3 +def get_floating_ip(conn): + '''A helper function to re-use available Floating IPs''' + return conn.available_floating_ip() + +# step-4 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i database -i messaging +''' + +instance_services = conn.create_server(wait=True, auto_ip=False, + name='app-services', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[services_group['name']], + userdata=userdata) + +services_ip = conn.get_server_private_ip(instance_services) + +# step-5 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -r api -m 'amqp://guest:guest@%(services_ip)s:5672/' \ + -d 'mysql+pymysql://faafo:password@%(services_ip)s:3306/faafo' +''' % { 'services_ip': services_ip } + +instance_api_1 = conn.create_server(wait=True, auto_ip=False, + name='app-api-1', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[api_group['name']], + userdata=userdata) +instance_api_2 = conn.create_server(wait=True, auto_ip=False, + name='app-api-2', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[api_group['name']], + userdata=userdata) + +api_1_ip = conn.get_server_private_ip(instance_api_1) +api_2_ip = conn.get_server_private_ip(instance_api_2) + +for instance in [instance_api_1, instance_api_2]: + floating_ip = get_floating_ip(conn) + conn.attach_ip_to_server(instance['id'], floating_ip['id']) + print('allocated %(ip)s to %(host)s' % {'ip': floating_ip['floating_ip_address'], 'host': instance['name']}) + +# step-6 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -r worker -e 'http://%(api_1_ip)s' -m 'amqp://guest:guest@%(services_ip)s:5672/' +''' % {'api_1_ip': api_1_ip, 'services_ip': services_ip} + +instance_worker_1 = conn.create_server(wait=True, auto_ip=False, + name='app-worker-1', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[worker_group['name']], + userdata=userdata) + +instance_worker_2 = conn.create_server(wait=True, auto_ip=False, + name='app-worker-2', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[worker_group['name']], + userdata=userdata) + +instance_worker_3 = conn.create_server(wait=True, auto_ip=False, + name='app-worker-3', + image=image_id, + flavor=flavor_id, + key_name='demokey', + security_groups=[worker_group['name']], + userdata=userdata) + +# step-7 diff --git a/firstapp/source/scaling_out.rst b/firstapp/source/scaling_out.rst index 9f9e7b3cd..fc8f10c15 100644 --- a/firstapp/source/scaling_out.rst +++ b/firstapp/source/scaling_out.rst @@ -155,6 +155,13 @@ Go ahead and delete the existing instances and security groups you created in previous sections. Remember, when instances in the cloud are no longer working, remove them and re-create something new. +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-1 + :end-before: step-2 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -169,6 +176,13 @@ As you change the topology of your applications, you will need to update or create new security groups. Here, we will re-create the required security groups. +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-2 + :end-before: step-3 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -182,6 +196,13 @@ Define a short function to locate unused IPs or allocate a new floating IP. This saves a few lines of code and prevents you from reaching your Floating IP quota too quickly. +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-3 + :end-before: step-4 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -197,6 +218,13 @@ called :code:`app-services`. The database and messaging queue will be used to track the state of the fractals and to coordinate the communication between the services. +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-4 + :end-before: step-5 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -214,6 +242,13 @@ thousands of users trying to connect to our API to generate fractals. Armed with our security group, image and flavor size we can now add multiple API services: +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-5 + :end-before: step-6 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -242,6 +277,13 @@ Scaling the workers To increase the overall capacity, we will now add 3 workers: +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + :start-after: step-6 + :end-before: step-7 + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py @@ -398,6 +440,11 @@ and run the code as a single script. Before you run this script, confirm that you have set your authentication information, the flavor ID, and image ID. +.. only:: shade + + .. literalinclude:: ../samples/shade/scaling_out.py + :language: python + .. only:: libcloud .. literalinclude:: ../samples/libcloud/scaling_out.py