Gotcha when writing Kubernetes charms


#1

Charms such as databases which have a provides endpoint often need to set in relation data the IP address to which related charms can connect. The IP address is obtained using network-get, often something like this:

@when('mysql.configured')
@when('server.database.requested')
def provide_database(mysql):
    info = network_get('server', relation_id())

    for request, application in mysql.database_requests().items():
        database_name = get_state('database')
        user = get_state('user')
        password = get_state('password')

        mysql.provide_database(
            request_id=request,
            host=host,
            port=3306,
            database_name=database_name,
            user=user,
            password=password,
        )
        clear_flag('server.database.requested')

Unlike charms written for IAAS models running on clouds where the unit agent runs on the same host as the workload, for the Kubernetes case, the IP address of the service/pod is usually not immediately available. So an extra snippet of logic is required to ensure the relation data is correctly set up.

@when('mysql.configured')
@when('server.database.requested')
def provide_database(mysql):
    info = network_get('server', relation_id())

    # Wait until IP address becomes available
    host = info['ingress-addresses'][0]
    if host == "":
        return
    ....