Browse Source

adapted demos for new Charmed OpenStack environment

pull/4/head
Sebastian Rieger 3 weeks ago
parent
commit
f63e5ebd8d
  1. 47
      CloudComp-openrc
  2. 144
      demo1_getting_started.py
  3. 268
      demo2_instance_with_init_script.py
  4. 317
      demo3_microservice.py
  5. 126
      destroy_all_demo_instances.py
  6. 21
      root-ca.crt

47
CloudComp-openrc

@ -0,0 +1,47 @@
#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
# unset all OPENSTACK ENV VARS
unset $(env | grep OS_ | cut -d "=" -f 1)
export OS_CACERT=./root-ca.crt
export GROUP_NUMBER=0
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
export OS_AUTH_URL=https://10.32.4.182:5000/v3
# With the addition of Keystone we have standardized on the term **project**
# as the entity that owns the resources.
#export OS_PROJECT_ID=bba62cf6bf0b447491829d207e1b05f9
export OS_PROJECT_NAME="CloudComp$GROUP_NUMBER"
unset OS_DOMAIN_NAME
export OS_USER_DOMAIN_NAME="Default"
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
export OS_PROJECT_DOMAIN_ID="default"
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
# unset v2.0 items in case set
unset OS_TENANT_ID
unset OS_TENANT_NAME
# In addition to the owning entity (tenant), OpenStack stores the entity
# performing the action as the **user**.
export OS_USERNAME="CloudComp$GROUP_NUMBER"
# With Keystone you pass the keystone password.
#echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
#read -sr OS_PASSWORD_INPUT
#export OS_PASSWORD=$OS_PASSWORD_INPUT
export OS_PASSWORD="demo"
# If your configuration has multiple regions, we set that information here.
# OS_REGION_NAME is optional and only valid in certain environments.
export OS_REGION_NAME="RegionOne"
# Don't leave a blank variable, unset it if it was empty
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3

144
demo1_getting_started.py

@ -0,0 +1,144 @@
"""Example for Cloud Computing Course Master AI / GSD"""
# This script demonstrates how to use libcloud to start an instance in an OpenStack environment.
# The script will start an instance, list all instances, and then destroy the instance again.
#
# The script uses the libcloud library to interact with the OpenStack API.
# Need to install libcloud first: pip install apache-libcloud
#
# libCloud: https://libcloud.apache.org/
# libCloud API documentation: https://libcloud.readthedocs.io/en/latest/
# OpenStack API documentation: https://developer.openstack.org/
# this code was initially based on the former tutorial:
# https://developer.openstack.org/firstapp-libcloud/
# Only needed for the password prompt:
# import getpass
from libcloud.compute.providers import get_driver
from libcloud.compute.types import Provider
# For our new Charmed OpenStack private cloud, we need to specify the path to the
# root CA certificate
import libcloud.security
libcloud.security.CA_CERTS_PATH = ['./root-ca.crt']
# Disable SSL certificate verification (not recommended for production)
# libcloud.security.VERIFY_SSL_CERT = False
# Please use 1-29 for 0 in the following variable to specify your group number.
# (will be used for the username, project etc., as coordinated in the lab sessions)
GROUP_NUMBER = 0
###############################################################################################
#
# no changes necessary below this line in this example
#
###############################################################################################
# web service endpoint of the private cloud infrastructure
# auth_url = 'https://private-cloud.informatik.hs-fulda.de:5000'
AUTH_URL = 'https://10.32.4.182:5000'
# auth_url = 'https://private-cloud2.informatik.hs-fulda.de:5000'
# your username in OpenStack
AUTH_USERNAME = 'CloudComp' + str(GROUP_NUMBER)
# your project in OpenStack
PROJECT_NAME = 'CloudComp' + str(GROUP_NUMBER)
# A network in the project the started instance will be attached to
PROJECT_NETWORK = 'CloudComp' + str(GROUP_NUMBER) + '-net'
# The image to look for and use for the started instance
# ubuntu_image_name = "Ubuntu 18.04 - Bionic Beaver - 64-bit - Cloud Based Image"
UBUNTU_IMAGE_NAME = "auto-sync/ubuntu-jammy-22.04-amd64-server-20240319-disk1.img"
# default region
REGION_NAME = 'RegionOne'
# domain to use, "default" for local accounts, formerly "hsfulda" for LDAP accounts etc.
# domain_name = "default"
def main(): # noqa: C901 pylint: disable=too-many-branches,too-many-statements,too-many-locals,missing-function-docstring
# get the password from user
# auth_password = getpass.getpass("Enter your OpenStack password:")
auth_password = "demo"
# instantiate a connection to the OpenStack private cloud
# make sure to include ex_force_auth_version='3.x_password', as needed in our environment
provider = get_driver(Provider.OPENSTACK)
print(f"Opening connection to {AUTH_URL} as {AUTH_USERNAME}...")
conn = provider(AUTH_USERNAME,
auth_password,
ex_force_auth_url=AUTH_URL,
ex_force_auth_version='3.x_password',
ex_tenant_name=PROJECT_NAME,
ex_force_service_region=REGION_NAME)
# ex_domain_name=domain_name)
print("Getting images and selecting desired one...")
print("=========================================================================")
# get a list of images offered in the cloud context (e.g. Ubuntu 20.04, cirros, ...)
images = conn.list_images()
image = ''
for img in images:
if img.name == UBUNTU_IMAGE_NAME:
image = img
print(img)
print("Getting flavors...")
print("=========================================================================")
# get a list of flavors offered in the cloud context (e.g. m1.small, m1.medium, ...)
flavors = conn.list_sizes()
for flavor in flavors:
print(flavor)
print("Selecting desired flavor...")
print("=========================================================================")
# get the flavor with id 2
flavor_id = '2'
flavor = conn.ex_get_size(flavor_id)
print(flavor)
print("Selecting desired network...")
print("=========================================================================")
# get a list of networks in the cloud context
networks = conn.ex_list_networks()
network = ''
for net in networks:
if net.name == PROJECT_NETWORK:
network = net
print("Create instance 'testing'...")
print("=========================================================================")
# create a new instance with the name "testing"
# make sure to provide networks (networks={network}) the instance should be attached to
instance_name = 'testing'
testing_instance = conn.create_node(name=instance_name, image=image, size=flavor,
networks={network})
print(testing_instance)
print("Showing all running instances...")
print("=========================================================================")
# show all instances (running nodes) in the cloud context
instances = conn.list_nodes()
for instance in instances:
print(instance)
print("Destroying instance...")
print("=========================================================================")
# destroy the instance we have just created
conn.destroy_node(testing_instance)
# method that is called when the script is started from the command line
if __name__ == '__main__':
main()

268
demo2_instance_with_init_script.py

@ -0,0 +1,268 @@
"""Example for Cloud Computing Course Master AI / GSD"""
# This script demonstrates how to use libcloud to start an instance in an OpenStack environment.
# The script will create and install a new SSH key pair, create a security group, start an instance
# and deploy a demo app (faafo) using cloud-init and assign a floating IP to the instance.
#
# cloud-init is a multi-distribution package that handles early initialization of a cloud instance.
# It is supported by many major cloud providers, including OpenStack.
# cloud-init documentation: https://cloudinit.readthedocs.io/en/latest/
# Needed if the password should be prompted for:
# import getpass
import os
import sys
from libcloud.compute.providers import get_driver
from libcloud.compute.types import Provider
# For our new Charmed OpenStack private cloud, we need to specify the path to the root
# CA certificate
import libcloud.security
libcloud.security.CA_CERTS_PATH = ['./root-ca.crt']
# Disable SSL certificate verification (not recommended for production)
# libcloud.security.VERIFY_SSL_CERT = False
# Please use 1-29 as environment variable GROUP_NUMBER to specify your group number.
# (will be used for the username, project etc., as coordinated in the lab sessions)
group_number = os.environ.get('GROUP_NUMBER')
if group_number is None:
sys.exit('Please set the GROUP_NUMBER environment variable to your group number,\n'
'e.g., on Windows:\n'
' "$env:GROUP_NUMBER=0" or "set GROUP_NUMBER=0"\n'
'or on Linux/MacOS:\n'
' "export GROUP_NUMBER=0" or "set GROUP_NUMBER=0"')
# web service endpoint of the private cloud infrastructure
# auth_url = 'https://private-cloud.informatik.hs-fulda.de:5000'
AUTH_URL = 'https://10.32.4.182:5000'
# auth_url = 'https://private-cloud2.informatik.hs-fulda.de:5000'
# your username in OpenStack
AUTH_USERNAME = 'CloudComp' + str(group_number)
print(f'Using username: {AUTH_USERNAME}\n')
# your project in OpenStack
PROJECT_NAME = 'CloudComp' + str(group_number)
# A network in the project the started instance will be attached to
PROJECT_NETWORK = 'CloudComp' + str(group_number) + '-net'
# The image to look for and use for the started instance
# ubuntu_image_name = "Ubuntu 18.04 - Bionic Beaver - 64-bit - Cloud Based Image"
UBUNTU_IMAGE_NAME = "auto-sync/ubuntu-jammy-22.04-amd64-server-20240319-disk1.img"
# The public key to be used for SSH connection, please make sure, that you have the
# corresponding private key
#
# id_rsa.pub should look like this (standard sshd pubkey format):
# ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAw+J...F3w2mleybgT1w== user@HOSTNAME
KEYPAIR_NAME = 'srieger-pub'
PUB_KEY_FILE = '~/.ssh/id_rsa.pub'
FLAVOR_NAME = 'm1.small'
# default region
REGION_NAME = 'RegionOne'
# domain to use, "default" for local accounts, formerly "hsfulda" for LDAP accounts etc.
# domain_name = "default"
def main(): # noqa: C901 pylint: disable=too-many-branches,too-many-statements,too-many-locals,missing-function-docstring
###########################################################################
#
# get credentials
#
###########################################################################
# if "OS_PASSWORD" in os.environ:
# auth_password = os.environ["OS_PASSWORD"]
# else:
# auth_password = getpass.getpass("Enter your OpenStack password:")
auth_password = "demo"
###########################################################################
#
# create connection
#
###########################################################################
provider = get_driver(Provider.OPENSTACK)
conn = provider(AUTH_USERNAME,
auth_password,
ex_force_auth_url=AUTH_URL,
ex_force_auth_version='3.x_password',
ex_tenant_name=PROJECT_NAME,
ex_force_service_region=REGION_NAME)
# ex_domain_name=domain_name)
###########################################################################
#
# get image, flavor, network for instance creation
#
###########################################################################
images = conn.list_images()
image = ''
for img in images:
if img.name == UBUNTU_IMAGE_NAME:
image = img
flavors = conn.list_sizes()
flavor = ''
for flav in flavors:
if flav.name == FLAVOR_NAME:
flavor = conn.ex_get_size(flav.id)
networks = conn.ex_list_networks()
network = ''
for net in networks:
if net.name == PROJECT_NETWORK:
network = net
###########################################################################
#
# create keypair dependency
#
###########################################################################
print('Checking for existing SSH key pair...')
keypair_exists = False
for keypair in conn.list_key_pairs():
if keypair.name == KEYPAIR_NAME:
keypair_exists = True
if keypair_exists:
print('Keypair ' + KEYPAIR_NAME + ' already exists. Skipping import.')
else:
print('adding keypair...')
conn.import_key_pair_from_file(KEYPAIR_NAME, PUB_KEY_FILE)
for keypair in conn.list_key_pairs():
print(keypair)
###########################################################################
#
# create security group dependency
#
###########################################################################
print('Checking for existing security group...')
security_group_name = 'all-in-one'
security_group_exists = False
all_in_one_security_group = ''
for security_group in conn.ex_list_security_groups():
if security_group.name == security_group_name:
all_in_one_security_group = security_group
security_group_exists = True
if security_group_exists:
print('Security Group ' + all_in_one_security_group.name + ' already exists. '
'Skipping creation.')
else:
all_in_one_security_group = conn.ex_create_security_group(security_group_name,
'network access for '
'all-in-one application.')
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22)
for security_group in conn.ex_list_security_groups():
print(security_group)
###########################################################################
#
# create all-in-one instance
#
###########################################################################
hsfd_faafo_cloud_init_script = 'https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-examples/raw/master/faafo/contrib/install.sh' # noqa: E501 pylint: disable=line-too-long
# testing / faafo dev branch:
# hsfd_faafo_cloud_init_script = 'https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-examples/raw/branch/dev_faafo/faafo/contrib/install.sh' # noqa: E501 pylint: disable=line-too-long
userdata = '#!/usr/bin/env bash\n' \
f'curl -L -s {hsfd_faafo_cloud_init_script} | bash -s -- ' \
'-i faafo -i messaging -r api -r worker -r demo\n'
print('\nUsing cloud-init userdata:\n"' + userdata + '"\n')
print('Checking for existing instance...')
instance_name = 'all-in-one'
instance_exists = False
testing_instance = ''
for instance in conn.list_nodes():
if instance.name == instance_name:
testing_instance = instance
instance_exists = True
if instance_exists:
print('Instance ' + testing_instance.name + ' already exists. Skipping creation.')
exit()
else:
print('Starting new all-in-one instance and wait until it is running...')
testing_instance = conn.create_node(name=instance_name,
image=image,
size=flavor,
networks=[network],
ex_keyname=KEYPAIR_NAME,
ex_userdata=userdata,
ex_security_groups=[all_in_one_security_group])
conn.wait_until_running(nodes=[testing_instance], timeout=120, ssh_interface='private_ips')
###########################################################################
#
# assign all-in-one instance floating ip
#
###########################################################################
private_ip = None
if len(testing_instance.private_ips):
private_ip = testing_instance.private_ips[0]
print(f'Private IP found: {private_ip}')
public_ip = None
if len(testing_instance.public_ips):
public_ip = testing_instance.public_ips[0]
print(f'Public IP found: {public_ip}')
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
if not floating_ip.node_id:
unused_floating_ip = floating_ip
break
if not unused_floating_ip and len(conn.ex_list_floating_ip_pools()):
pool = conn.ex_list_floating_ip_pools()[0]
print(f'Allocating new Floating IP from pool: {pool}')
unused_floating_ip = pool.create_floating_ip()
if public_ip:
print('Instance ' + testing_instance.name + ' already has a public ip. Skipping attachment.')
elif unused_floating_ip:
conn.ex_attach_floating_ip_to_node(testing_instance, unused_floating_ip)
actual_ip_address = None
if public_ip:
actual_ip_address = public_ip
elif unused_floating_ip:
actual_ip_address = unused_floating_ip.ip_address
elif private_ip:
actual_ip_address = private_ip
print('\n\n#### Deployment finished\n\n')
print('After some minutes, as soon as cloud-init installed required packages and the\n'
'faafo app, (First App Application For OpenStack) fractals demo will be available\n'
f'at http://{actual_ip_address}\n')
print('You can use ssh to login to the instance using your private key. Default user name for official Ubuntu\n'
f'Cloud Images is: ubuntu, so you can use, e.g.: "ssh -i ~/.ssh/id_rsa ubuntu@{actual_ip_address}" if your\n'
'private key is in the default location.\n\n'
'After login, you can list available fractals using "faafo list". \n'
'To request the generation of new fractals, you can use "faafo create".\n\n'
'You can also see other options to use the faafo example cloud service using "faafo -h".\n\n'
'If you cannot start faafo command and/or do not see the webpage, you can check the Instance Console Log of\n'
'the instance, e.g., in OpenStack web interface or look at "tail -f /var/log/cloud-init*.log" for the\n'
'cloud-init log files.\n')
if __name__ == '__main__':
main()

317
demo3_microservice.py

@ -0,0 +1,317 @@
"""Example for Cloud Computing Course Master AI / GSD"""
# This script demonstrates how to use libcloud to start an instance in an OpenStack environment.
# The script will create start multiple instances splitting up the faafo monolithic application into
# a (minimalistic but already scalable) microservice architecture.
# Also introduces the concept of different security groups and corresponding frontend/backend
# separation.
# Needed if the password should be prompted for:
# import getpass
import os
import sys
from libcloud.compute.providers import get_driver
from libcloud.compute.types import Provider
# For our new Charmed OpenStack private cloud, we need to specify the path to the root
# CA certificate
import libcloud.security
libcloud.security.CA_CERTS_PATH = ['./root-ca.crt']
# Disable SSL certificate verification (not recommended for production)
# libcloud.security.VERIFY_SSL_CERT = False
# Please use 1-29 as environment variable GROUP_NUMBER to specify your group number.
# (will be used for the username, project etc., as coordinated in the lab sessions)
group_number = os.environ.get('GROUP_NUMBER')
if group_number is None:
sys.exit('Please set the GROUP_NUMBER environment variable to your group number,\n'
'e.g., on Windows:\n'
' "$env:GROUP_NUMBER=0" or "set GROUP_NUMBER=0"\n'
'or on Linux/MacOS:\n'
' "export GROUP_NUMBER=0" or "set GROUP_NUMBER=0"')
# web service endpoint of the private cloud infrastructure
# auth_url = 'https://private-cloud.informatik.hs-fulda.de:5000'
AUTH_URL = 'https://10.32.4.182:5000'
# auth_url = 'https://private-cloud2.informatik.hs-fulda.de:5000'
# your username in OpenStack
AUTH_USERNAME = 'CloudComp' + str(group_number)
print(f'Using username: {AUTH_USERNAME}\n')
# your project in OpenStack
PROJECT_NAME = 'CloudComp' + str(group_number)
# A network in the project the started instance will be attached to
PROJECT_NETWORK = 'CloudComp' + str(group_number) + '-net'
# The image to look for and use for the started instance
# ubuntu_image_name = "Ubuntu 18.04 - Bionic Beaver - 64-bit - Cloud Based Image"
UBUNTU_IMAGE_NAME = "auto-sync/ubuntu-jammy-22.04-amd64-server-20240319-disk1.img"
# The public key to be used for SSH connection, please make sure, that you have the
# corresponding private key
#
# id_rsa.pub should look like this (standard sshd pubkey format):
# ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAw+J...F3w2mleybgT1w== user@HOSTNAME
KEYPAIR_NAME = 'srieger-pub'
PUB_KEY_FILE = '~/.ssh/id_rsa.pub'
FLAVOR_NAME = 'm1.small'
# default region
REGION_NAME = 'RegionOne'
# domain to use, "default" for local accounts, formerly "hsfulda" for LDAP accounts etc.
# domain_name = "default"
def main(): # noqa: C901 pylint: disable=too-many-branches,too-many-statements,too-many-locals,missing-function-docstring
###########################################################################
#
# get credentials
#
###########################################################################
# if "OS_PASSWORD" in os.environ:
# auth_password = os.environ["OS_PASSWORD"]
# else:
# auth_password = getpass.getpass("Enter your OpenStack password:")
auth_password = "demo"
###########################################################################
#
# create connection
#
###########################################################################
provider = get_driver(Provider.OPENSTACK)
conn = provider(AUTH_USERNAME,
auth_password,
ex_force_auth_url=AUTH_URL,
ex_force_auth_version='3.x_password',
ex_tenant_name=PROJECT_NAME,
ex_force_service_region=REGION_NAME)
# ex_domain_name=domain_name)
###########################################################################
#
# get image, flavor, network for instance creation
#
###########################################################################
images = conn.list_images()
image = ''
for img in images:
if img.name == UBUNTU_IMAGE_NAME:
image = img
flavors = conn.list_sizes()
flavor = ''
for flav in flavors:
if flav.name == FLAVOR_NAME:
flavor = conn.ex_get_size(flav.id)
networks = conn.ex_list_networks()
network = ''
for net in networks:
if net.name == PROJECT_NETWORK:
network = net
###########################################################################
#
# create keypair dependency
#
###########################################################################
print('Checking for existing SSH key pair...')
keypair_exists = False
for keypair in conn.list_key_pairs():
if keypair.name == KEYPAIR_NAME:
keypair_exists = True
if keypair_exists:
print('Keypair ' + KEYPAIR_NAME + ' already exists. Skipping import.')
else:
print('adding keypair...')
conn.import_key_pair_from_file(KEYPAIR_NAME, PUB_KEY_FILE)
for keypair in conn.list_key_pairs():
print(keypair)
###########################################################################
#
# create security group dependency
#
###########################################################################
print('Checking for existing worker security group...')
security_group_name = 'worker'
security_group_exists = False
worker_security_group = ''
for security_group in conn.ex_list_security_groups():
if security_group.name == security_group_name:
worker_security_group = security_group
security_group_exists = True
if security_group_exists:
print('Worker Security Group ' + worker_security_group.name + ' already exists. '
'Skipping creation.')
else:
worker_security_group = conn.ex_create_security_group('worker', 'for services '
'that run on a worker node')
conn.ex_create_security_group_rule(worker_security_group, 'TCP', 22, 22)
print('Checking for existing controller security group...')
security_group_name = 'control'
security_group_exists = False
controller_security_group = ''
for security_group in conn.ex_list_security_groups():
if security_group.name == security_group_name:
controller_security_group = security_group
security_group_exists = True
if security_group_exists:
print('Controller Security Group ' + controller_security_group.name + ' already exists. '
'Skipping creation.')
else:
controller_security_group = conn.ex_create_security_group('control', 'for services that '
'run on a control node')
conn.ex_create_security_group_rule(controller_security_group, 'TCP', 22, 22)
conn.ex_create_security_group_rule(controller_security_group, 'TCP', 80, 80)
conn.ex_create_security_group_rule(controller_security_group, 'TCP', 5672, 5672,
source_security_group=worker_security_group)
for security_group in conn.ex_list_security_groups():
print(security_group)
###########################################################################
#
# create app-controller
#
###########################################################################
# https://git.openstack.org/cgit/openstack/faafo/plain/contrib/install.sh
# is currently broken, hence the "rabbitctl" lines were added in the example
# below, see also https://bugs.launchpad.net/faafo/+bug/1679710
#
# Thanks to Stefan Friedmann for finding this fix ;)
# TODO: still needed for new version of faafo and Ubuntu 22.04?
userdata = '#!/usr/bin/env bash\n' \
'curl -L -s https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-' \
'examples/raw/master/faafo/contrib/install.sh | bash -s -- ' \
'-i messaging -i faafo -r api\n' \
'rabbitmqctl add_user faafo guest\n' \
'rabbitmqctl set_user_tags faafo administrator\n' \
'rabbitmqctl set_permissions -p / faafo ".*" ".*" ".*"\n'
print('\nUsing cloud-init userdata:\n"' + userdata + '"\n')
print('Starting new app-controller instance and wait until it is running...')
instance_controller_1 = conn.create_node(name='app-controller',
image=image,
size=flavor,
networks=[network],
ex_keyname=KEYPAIR_NAME,
ex_userdata=userdata,
ex_security_groups=[controller_security_group])
conn.wait_until_running(nodes=[instance_controller_1], timeout=120, ssh_interface='private_ips')
###########################################################################
#
# assign app-controller floating ip
#
###########################################################################
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
if not floating_ip.node_id:
unused_floating_ip = floating_ip
break
if not unused_floating_ip:
pool = conn.ex_list_floating_ip_pools()[0]
print(f'Allocating new Floating IP from pool: {pool}')
unused_floating_ip = pool.create_floating_ip()
conn.ex_attach_floating_ip_to_node(instance_controller_1, unused_floating_ip)
print(f'Controller Application will be deployed to http://{unused_floating_ip.ip_address}')
actual_ip_address = unused_floating_ip.ip_address
###########################################################################
#
# getting id and ip address of app-controller instance
#
###########################################################################
# instance should not have a public ip? floating ips are assigned later
instance_controller_1 = conn.ex_get_node_details(instance_controller_1.id)
ip_controller = ''
if instance_controller_1.public_ips:
ip_controller = instance_controller_1.public_ips[0]
else:
ip_controller = instance_controller_1.private_ips[0]
###########################################################################
#
# create app-worker-1
#
###########################################################################
userdata = '#!/usr/bin/env bash\n' \
'curl -L -s https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-' \
'examples/raw/master/faafo/contrib/install.sh | bash -s -- ' \
f'-i faafo -r worker -e "http://{ip_controller}" -m "amqp://faafo:guest@' \
f'{ip_controller}:5672/\n'
print('\nUsing cloud-init userdata:\n"' + userdata + '"\n')
print('Starting new app-worker-1 instance and wait until it is running...')
instance_worker_1 = conn.create_node(name='app-worker-1',
image=image,
size=flavor,
networks=[network],
ex_keyname=KEYPAIR_NAME,
ex_userdata=userdata,
ex_security_groups=[worker_security_group])
conn.wait_until_running(nodes=[instance_worker_1], timeout=120, ssh_interface='private_ips')
###########################################################################
#
# assign app-worker floating ip
#
###########################################################################
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
if not floating_ip.node_id:
unused_floating_ip = floating_ip
break
if not unused_floating_ip:
pool = conn.ex_list_floating_ip_pools()[0]
print(f'Allocating new Floating IP from pool: {pool}')
unused_floating_ip = pool.create_floating_ip()
conn.ex_attach_floating_ip_to_node(instance_worker_1, unused_floating_ip)
print(f'The worker will be available for SSH at {unused_floating_ip.ip_address}')
print('\n\n#### Deployment finished\n\n')
print('After some minutes, as soon as cloud-init installed required packages and the\n'
'faafo app, (First App Application For OpenStack) fractals demo will be available\n'
f'at http://{actual_ip_address}\n')
print('You can use ssh to login to the controller using your private key.\n'
f'E.g., "ssh -i ~/.ssh/id_rsa ubuntu@{actual_ip_address}". After login,\n'
'you can list available fractals using "faafo list". To request the generation of\n'
'new fractals, you can use "faafo create". \n'
'You can also see other options to use the faafo example cloud service using '
'"faafo -h".')
if __name__ == '__main__':
main()

126
destroy_all_demo_instances.py

@ -0,0 +1,126 @@
"""Example for Cloud Computing Course Master AI / GSD"""
# This script demonstrates how to use libcloud to cleanup all instances used in the demos
# for our OpenStack private cloud environment.
# import getpass
import os
import sys
import time
from libcloud.compute.providers import get_driver
from libcloud.compute.types import Provider
# For our new Charmed OpenStack private cloud, we need to specify the path to the
# root CA certificate
import libcloud.security
libcloud.security.CA_CERTS_PATH = ['./root-ca.crt']
# Disable SSL certificate verification (not recommended for production)
# libcloud.security.VERIFY_SSL_CERT = False
# Please use 1-29 for X in the following variable to specify your group number.
# (will be used for the username, project etc., as coordinated in the lab sessions)
group_number = os.environ.get('GROUP_NUMBER')
if group_number is None:
sys.exit('Please set the GROUP_NUMBER environment variable to your group number,\n'
'e.g., on Windows:\n'
' "$env:GROUP_NUMBER=0" or "set GROUP_NUMBER=0"\n'
'or on Linux/MacOS:\n'
' "export GROUP_NUMBER=0" or "set GROUP_NUMBER=0"')
###############################################################################################
#
# no changes necessary below this line in this example
#
###############################################################################################
# web service endpoint of the private cloud infrastructure
# auth_url = 'https://private-cloud.informatik.hs-fulda.de:5000'
AUTH_URL = 'https://10.32.4.182:5000'
# auth_url = 'https://private-cloud2.informatik.hs-fulda.de:5000'
# your username in OpenStack
AUTH_USERNAME = 'CloudComp' + str(group_number)
# your project in OpenStack
PROJECT_NAME = 'CloudComp' + str(group_number)
# A network in the project the started instance will be attached to
PROJET_NETWORK = 'CloudComp' + str(group_number) + '-net'
# The image to look for and use for the started instance
# ubuntu_image_name = "Ubuntu 18.04 - Bionic Beaver - 64-bit - Cloud Based Image"
UBUNTU_IMAGE_NAME = "auto-sync/ubuntu-jammy-22.04-amd64-server-20240319-disk1.img"
# default region
REGION_NAME = 'RegionOne'
# domain to use, "default" for local accounts, formerly "hsfulda" for LDAP accounts etc.
# domain_name = "default"
def main(): # noqa: C901 pylint: disable=too-many-branches,too-many-statements,too-many-locals,missing-function-docstring
###########################################################################
#
# get credentials
#
###########################################################################
# if "OS_PASSWORD" in os.environ:
# auth_password = os.environ["OS_PASSWORD"]
# else:
# auth_password = getpass.getpass("Enter your OpenStack password:")
auth_password = "demo"
###########################################################################
#
# create connection
#
###########################################################################
# libcloud.security.VERIFY_SSL_CERT = False
provider = get_driver(Provider.OPENSTACK)
conn = provider(AUTH_USERNAME,
auth_password,
ex_force_auth_url=AUTH_URL,
ex_force_auth_version='3.x_password',
ex_tenant_name=PROJECT_NAME,
ex_force_service_region=REGION_NAME)
# ex_domain_name=domain_name)
###########################################################################
#
# clean up resources from previous demos
#
###########################################################################
# destroy running demo instances
for instance in conn.list_nodes():
if instance.name in ['all-in-one', 'app-worker-1', 'app-worker-2', 'app-worker-3',
'app-controller',
'app-services', 'app-api-1', 'app-api-2']:
print(f'Destroying Instance: {instance.name}')
conn.destroy_node(instance)
# wait until all nodes are destroyed to be able to remove depended security groups
nodes_still_running = True
while nodes_still_running:
nodes_still_running = False
time.sleep(3)
instances = conn.list_nodes()
for instance in instances:
# if we see any demo instances still running continue to wait for them to stop
if instance.name in ['all-in-one', 'app-worker-1', 'app-worker-2', 'app-worker-3',
'app-controller', 'app-services', 'app-api-1', 'app-api-2']:
nodes_still_running = True
print('There are still instances running, waiting for them to be destroyed...')
# delete security groups
for group in conn.ex_list_security_groups():
if group.name in ['control', 'worker', 'api', 'services']:
print(f'Deleting security group: {group.name}')
conn.ex_delete_security_group(group)
if __name__ == '__main__':
main()

21
root-ca.crt

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUEQjSqiZ86fhawQU09G8hn3i9dIwwDQYJKoZIhvcNAQEL
BQAwPTE7MDkGA1UEAxMyVmF1bHQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkg
KGNoYXJtLXBraS1sb2NhbCkwHhcNMjQwMzI1MTMxNDU0WhcNMzQwMzIzMTIxNTIz
WjA9MTswOQYDVQQDEzJWYXVsdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAo
Y2hhcm0tcGtpLWxvY2FsKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALcax5l2zU1ELCtF/k6yq3HUv7gFq6f/sl8rX0VRhzZyEy4hcMgRSZDAM14viTVZ
8d7+ptY3+GwuLSpEY2UUlX5kJSDb4pUNRXDhxzRatbByG8pr5FQE8pX9W7y4C0TU
3PQA4uIjAsPFKayFxXjJjOQN0HX3K6MCQz/BTV81U3fmdFrKma3x/PXyUYndjQH6
zlIiQSdYh7FMTbS2FlpvwWbT9zKOpp+2M0odI8Y8fjCSUdSdKDFhVu02zQTq6/h0
Q1/sNHz2IP9F83sNW+ro0bvv5CJ2iCyAk/RiFoB+RoSO6HncOtYHxa/guwTy4eHh
VQVJXkEI2PutCw6S3lWqLEcCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFDKQHfpVHJgge6RRC5uDwMByLbV3MB8GA1Ud
IwQYMBaAFDKQHfpVHJgge6RRC5uDwMByLbV3MA0GCSqGSIb3DQEBCwUAA4IBAQCa
ajIRi/+7Yy7l46yFURLyELMWayRpdx2KCxIuAiSkTlNSVOPCmwZvgnYLPVffXWpt
IXJGQk//9+5q18LiZat5MbvUU3ffLc/ZCxIeQiWNuYKziLYNFHmpfMvxNxzAJ6Pi
2fj5ZP/cA4Vie3M1iHfdSXmYPvyw76i9/sA2+F7Wy8fzK53S1OaMaeADNGljHTaW
ovRxreLKJZybqe/YWlcEiP4dC4VMHLl+H5RmZ5ojrRiy1c3uUssNnIJU+ilkY8TP
0VV17+wQBaJbbp4jh8acwvOJbN8Y1EHQWhxkEf3PfjJRv+b1NI/Iai27DfYto7Dm
rZvaFnAMCcyFXyJv3WdJ
-----END CERTIFICATE-----
Loading…
Cancel
Save