Skip to content
Snippets Groups Projects

Sample notebook for EOSC

1 file
+ 55
36
Compare changes
  • Side-by-side
  • Inline
+ 55
36
%% Cell type:markdown id:f1d44b71-9709-467e-92d4-c1faa31a93e7 tags:
# Deploying Your First Virtual Machine on PSNC OpenStack
Welcome to this hands-on tutorial for launching and configuring your first Virtual Machine (VM) in the PSNC OpenStack cloud environment. This guide will walk you through each step of the deployment process—from authentication to full VM provisioning and access.
📚 **Further reading:** [PSNC OpenStack Virtual Machines](https://docs.psnc.pl/display/EOSCUserGuides/Virtual+Machines)
%% Cell type:markdown id:00e621e9-5493-45aa-8cea-dcbb14ab0df6 tags:
# Install the required libraries
%% Cell type:code id:0ce0f97a-a87b-4655-8f85-cfabb07172f7 tags:
%% Cell type:code id:0ce0f97a-a87b-4655-8f85-cfabb07172f7 tags:
``` python
``` python
pip install python-openstackclient python-keystoneclient ipywidgets paramiko
!pip install python-openstackclient python-keystoneclient ipywidgets paramiko
%% Cell type:code id:c3718348-c7df-44d3-9811-66b7fa7ec7fb tags:
%% Cell type:code id:c3718348-c7df-44d3-9811-66b7fa7ec7fb tags:
``` python
``` python
 
"""
 
Import the required libraries
 
"""
 
import time
import sys
import sys
import paramiko
import paramiko
import yaml
from keystoneauth1.session import Session
from keystoneauth1.session import Session
from keystoneauth1.identity.v3.oidc import OidcAccessToken
from keystoneauth1.identity.v3.oidc import OidcAccessToken
from keystoneauth1.identity.v3.application_credential import ApplicationCredential
from keystoneclient.v3.client import Client
from keystoneclient.v3.client import Client
from openstack.connection import Connection
from openstack.connection import Connection
 
from openstack.exceptions import SDKException
import ipywidgets as widgets
import ipywidgets as widgets
import base64
import time
from IPython.display import display, clear_output, Markdown
from IPython.display import display, clear_output, Markdown
from openstack.exceptions import ResourceNotFound, SDKException
%% Cell type:markdown id:f1d44b71-9709-467e-92d4-c1faa31a93e7 tags:
 
# Deploying Your First Virtual Machine on PSNC OpenStack
 
 
Welcome to this hands-on tutorial for launching and configuring your first Virtual Machine (VM) in the PSNC OpenStack cloud environment. This guide will walk you through each step of the deployment process—from authentication to full VM provisioning and access.
 
 
📚 **Further reading:** [PSNC OpenStack Virtual Machines](https://docs.psnc.pl/display/EOSCUserGuides/Virtual+Machines)
%% Cell type:markdown id:02aedafa-9276-4350-b60c-53fe216514c9 tags:
%% Cell type:markdown id:02aedafa-9276-4350-b60c-53fe216514c9 tags:
%% Cell type:code id:5bc6fac0-c5fa-44a7-9d29-38ea5164e4bc tags:
%% Cell type:code id:5bc6fac0-c5fa-44a7-9d29-38ea5164e4bc tags:
def load_access_token(token_file_path="/var/run/secrets/oidc/access_token"):
def load_access_token(token_file_path="/var/run/secrets/oidc/access_token"):
"""Reads access token from specified file"""
"""Reads access token from specified file"""
try:
try:
return open(token_file_path, "r").read()
return open(token_file_path, "r", encoding='utf-8').read()
except IOError:
except IOError:
print("Reading from access token file failed.", file=sys.stderr)
print("Reading from access token file failed.", file=sys.stderr)
 
return None
cloud_creds = OidcAccessToken(auth_url="https://api.cloud.psnc.pl:5000/v3/",
cloud_creds = OidcAccessToken(auth_url="https://api.cloud.psnc.pl:5000/v3/",
identity_provider="aai.open-science-cloud.ec.europa.eu",
identity_provider="aai.open-science-cloud.ec.europa.eu",
%% Cell type:code id:b871dc55-172a-43da-81d7-b7fa796a7c2c tags:
%% Cell type:code id:b871dc55-172a-43da-81d7-b7fa796a7c2c tags:
%% Cell type:code id:9a58d8c5-7dcd-4549-9b10-0456ccd66b30 tags:
%% Cell type:code id:9a58d8c5-7dcd-4549-9b10-0456ccd66b30 tags:
 
# pylint: disable=invalid-name, global-statement, unused-argument, protected-access
 
 
scoped_cloud_session = None
 
scoped_openstack_connection = None
clear_output(wait=True) # Clear previous output first
clear_output(wait=True) # Clear previous output first
display(Markdown("## Scope to one of your projects you are entitled to access"))
display(Markdown("## Scope to one of your projects you are entitled to access"))
project_dropdown = widgets.Dropdown(
project_dropdown = widgets.Dropdown(
options=[(project.name, idx) for idx, project in enumerate(my_projects)],
options=[(project.name, idx) for idx, project in enumerate(my_projects)],
description="Project:",
description="Project:",
def on_connect_clicked(b):
def on_connect_clicked(b):
 
"""Handle click event to connect to the selected OpenStack project."""
with output:
with output:
clear_output()
clear_output()
idx = project_dropdown.value
idx = project_dropdown.value
selected_project = my_projects[idx]
selected_project = my_projects[idx]
print(f"🔌 Connecting to project: {selected_project.name} (ID: {selected_project.id}, Domain: {selected_project.domain_id})")
print(f"🔌 Connecting to project: {selected_project.name} (ID: {selected_project.id}, \
 
Domain: {selected_project.domain_id})")
scoped_cloud_creds = OidcAccessToken(
scoped_cloud_creds = OidcAccessToken(
auth_url="https://api.cloud.psnc.pl:5000/v3/",
auth_url="https://api.cloud.psnc.pl:5000/v3/",
identity_provider="aai.open-science-cloud.ec.europa.eu",
identity_provider="aai.open-science-cloud.ec.europa.eu",
protocol="openid",
protocol="openid",
project_id=selected_project.id,
project_id=selected_project.id,
project_domain_id=selected_project.domain_id,
project_domain_id=selected_project.domain_id,
%% Output
%% Output
``` python
``` python
print("Your current project id: ", scoped_openstack_connection.current_project_id)
print("Your current project id:", scoped_openstack_connection.current_project_id)
%% Output
%% Output
Your current project id: db6b4eb2d6fe454191e8d39b088564cd
Your current project id: db6b4eb2d6fe454191e8d39b088564cd
%% Cell type:markdown id:5a8c4205-e524-44ca-96fb-d7577bc74d90 tags:
%% Cell type:markdown id:5a8c4205-e524-44ca-96fb-d7577bc74d90 tags:
key_name = "key"
KEY_NAME = "key"
new_keypair = scoped_openstack_connection.create_keypair(key_name)
new_keypair = scoped_openstack_connection.create_keypair(KEY_NAME)
#Generating key-pair using existing public key
#Generating key-pair using existing public key
#scoped_openstack_connection.create_keypair("mykey2", public_key="ssh-rsa ....")
#scoped_openstack_connection.create_keypair("mykey2", public_key="ssh-rsa ....")
#If you let OpenStack generate your key-pair you will need to save your
#If you let OpenStack generate your key-pair you will need to save your
#private and public keys for later use
#private and public keys for later use
with open(f"{key_name}.pem", "w") as priv_file:
with open(f"{KEY_NAME}.pem", "w", encoding="utf-8") as priv_file:
priv_file.write(new_keypair.private_key)
priv_file.write(new_keypair.private_key)
print(f"Private key saved to {key_name}.pem")
print(f"Private key saved to {KEY_NAME}.pem")
with open(f"{key_name}.pub", "w") as pub_file:
with open(f"{KEY_NAME}.pub", "w", encoding="utf-8") as pub_file:
pub_file.write(new_keypair.public_key)
pub_file.write(new_keypair.public_key)
print(f"Public key saved to {key_name}.pub")
print(f"Public key saved to {KEY_NAME}.pub")
%% Cell type:markdown id:809ce42b-b70f-4dfb-82a9-cb505477663c tags:
%% Cell type:markdown id:809ce42b-b70f-4dfb-82a9-cb505477663c tags:
def format_image_options(images):
def format_image_options(images):
 
"""Format a list of image objects for display in a dropdown."""
return [
return [
f"{image.name} (ID: {image.id}, Size: {format_size_gb(image.size)})"
f"{image.name} (ID: {image.id}, Size: {format_size_gb(image.size)})"
for image in images
for image in images
]
]
def format_generic_options(resources, label_attr='name', id_attr='id'):
def format_generic_options(resources, label_attr='name', id_attr='id'):
 
"""Format a list of OpenStack resources into label (ID) format."""
return [f"{getattr(res, label_attr)} (ID: {getattr(res, id_attr)})" for res in resources]
return [f"{getattr(res, label_attr)} (ID: {getattr(res, id_attr)})" for res in resources]
images = list(scoped_openstack_connection.compute.images())
available_images = list(scoped_openstack_connection.compute.images())
flavors = list(scoped_openstack_connection.compute.flavors())
flavors = list(scoped_openstack_connection.compute.flavors())
networks = list(scoped_openstack_connection.network.networks())
networks = list(scoped_openstack_connection.network.networks())
display(Markdown("### Available Images"))
display(Markdown("### Available Images"))
image_dropdown = widgets.Dropdown(
image_dropdown = widgets.Dropdown(
options=format_image_options(images),
options=format_image_options(available_images),
description='Image:',
description='Image:',
layout=widgets.Layout(width='85%')
layout=widgets.Layout(width='85%')
)
)
display(image_dropdown)
display(image_dropdown)
display(Markdown("### Available Flavors"))
display(Markdown("### Available Flavors"))
flavor_dropdown = widgets.Dropdown(
flavor_dropdown = widgets.Dropdown(
options=format_generic_options(flavors),
options=format_generic_options(flavors),
description='Flavor:',
description='Flavor:',
def get_selected_id(dropdown_value):
def get_selected_id(dropdown_value):
 
"""Extract the ID part from a dropdown value string formatted as 'Name (ID: id)'."""
return dropdown_value.split(" (ID: ")[1].split(")")[0]
return dropdown_value.split(" (ID: ")[1].split(")")[0]
 
selected_image = get_selected_name(image_dropdown.value)
selected_image = get_selected_name(image_dropdown.value)
selected_flavor = get_selected_name(flavor_dropdown.value)
selected_flavor = get_selected_name(flavor_dropdown.value)
selected_network = get_selected_name(network_dropdown.value)
selected_network = get_selected_name(network_dropdown.value)
selected_network_id = get_selected_id(network_dropdown.value)
selected_network_id = get_selected_id(network_dropdown.value)
%% Cell type:code id:616210a6-a2f4-4732-bdbe-b37684d9dd74 tags:
%% Cell type:code id:616210a6-a2f4-4732-bdbe-b37684d9dd74 tags:
%% Output
%% Output
apt-get install -y nginx
apt-get install -y nginx
echo 'Hello from my VM' > /var/www/html/index.html
echo 'Hello from my VM' > /var/www/html/index.html
"""
"""
vm_name = "new_vm"
VM_NAME = "new_vm"
server = scoped_openstack_connection.create_server(
server = scoped_openstack_connection.create_server(
name=vm_name,
name=VM_NAME,
image=selected_image,
image=selected_image,
flavor=selected_flavor,
flavor=selected_flavor,
network=network, # Use new private network
network=network, # Use new private network
userdata=cloud_init_script,
userdata=CLOUD_INIT_SCRIPT,
key_name="key",
key_name="key",
volumes=[new_volume],
volumes=[new_volume],
security_groups=[new_security_group.name]
security_groups=[new_security_group.name]
)
)
# Waiting until all is ready
# Waiting until all is ready
time.sleep(170)
time.sleep(170)
%% Cell type:markdown id:915cde8d-f668-44a1-913d-24436a93e4d4 tags:
%% Cell type:markdown id:915cde8d-f668-44a1-913d-24436a93e4d4 tags:
 
> It will take some time for `CLOUD_INIT_SCRIPT` to finish.
%% Cell type:code id:47ac6e4e-ee8d-413b-a7bf-a7f1562d01e7 tags:
%% Cell type:code id:47ac6e4e-ee8d-413b-a7bf-a7f1562d01e7 tags:
``` python
``` python
scoped_openstack_connection.network.delete_security_group(new_security_group)
scoped_openstack_connection.network.delete_security_group(new_security_group)
scoped_openstack_connection.network.delete_network(network)
scoped_openstack_connection.network.delete_network(network)
 
%% Cell type:code id:189c00ae-378d-4647-8226-bb5e1e5e0c03 tags:
 
``` python
 
%% Cell type:code id:31a05bda-47a1-4d00-abe5-3514cff6a7cb tags:
 
``` python
Loading