Search code examples
python-3.xopenstackopenstack-nova

Execute customized script when launching instance using openstacksdk


I'm new to Openstack and I'm trying to create a tool so that I can launch any number of instances in an Openstack cloud. This was easily done using the nova-client module of openstacksdk. Now the problem is that I want to make the instances execute a bash script as they are created by adding it as a userdata file, but it doesn't execute. This is confusing because I don't any error or warning message. Does anyone know what could it be?

Important parts of the code

The most important parts of the Python program are the function which gets the cloud info, the one that creates the instances and the main function, . I'll post them here as @Corey told.

"""
 Function that allow us to log at cloud with all the credentials needed. 
 Username and password are not read from env.
"""
def get_nova_credentials_v2():
    d = {}
    user = ""
    password = ""
    print("Logging in...")
    user = input("Username: ")
    password = getpass.getpass(prompt="Password: ", stream=None)
    while (user == "" or password == ""):
        print("User or password field is empty")
        user = input("Username: ")
        password = getpass.getpass(prompt="Password: ", stream=None)
    d['version'] = '2.65'
    d['username'] = user
    d['password'] = password
    d['project_id'] = os.environ['OS_PROJECT_ID']
    d['auth_url'] = os.environ['OS_AUTH_URL']
    d['user_domain_name'] = os.environ['OS_USER_DOMAIN_NAME']
    return d

Then we have the create_server function:

"""
 This function creates a server using the info we got from JSON file
"""

def create_server(server):
    s = {}
    print("Creating "+server['compulsory']['name']+"...")
    s['name'] = server['compulsory']['name']
    s['image'] = server['compulsory']['os']
    s['flavor'] = server['compulsory']['flavor']
    s['min_count'] = server['compulsory']['copyNumber']
    s['max_count'] = server['compulsory']['copyNumber']
    s['userdata'] = server['file']
    s['key_name'] = server['compulsory']['keyName']
    s['availability_zone'] = server['compulsory']['availabilityZone']
    s['nics'] = server['compulsory']['network']
    print(s['userdata'])
    if(exists("instalacion_k8s_docker.sh")):
        print("Exists")
        s['userdata'] = server['file']
        nova.servers.create(**s)

And now the main function:

"""
 Main process: First we create a connection to Openstack using our credentials.
 Once connected we cal get_serverdata function to get all instance objects we want to be created.
 We check that it is not empty and that we are not trying to create more instances than we are allowed.
 Lastly we create the instances and the program finishes.
"""
credentials = get_nova_credentials_v2()
nova = client.Client(**credentials)
instances = get_serverdata()
current_instances = len(nova.servers.list())
if not instances:
    print("No instance was writen. Check instances.json file.")
    exit(3)
num = 0
for i in instances:
    create_server(i)    
exit(0)

For the rest of the code you can access to this public repo on github. Thanks a lot!


Solution

  • Problem solved

    The problem was the content of the server['file'] as @Corey said. It cannot be the Path to the file where you wrote the data but the content of it or a file type object. In the case of OpenstackSDK it must be base64 encoded but it is not the case in Novaclient.

    Thanks a lot to @Corey for all the help! :)