kopf icon indicating copy to clipboard operation
kopf copied to clipboard

How to initialize the status of the resource on creation?

Open johnlinp opened this issue 1 year ago • 2 comments

Keywords

status, creation

Problem

I want to expose the current state of the underlying service via the field .status.serviceState of my custom resources. The field .status.serviceState may have one of the values: "PENDING", "READY", "ERROR".

Currently, I have tried this:

@kopf.on.create('example.com', 'v1', 'foo')
def on_create(spec, patch, **kwargs):
    patch.status['serviceState'] = 'PENDING' # tries to initialize the status

    result = create_underlying_service() # this runs very slow

    if result.success:
        patch.status['serviceState'] = 'READY'
    else:
        patch.status['serviceState'] = 'ERROR'

When the operator is busy creating the underlying service, I expect that .status.serviceState is already initialized with the value "PENDING". However, the field .status.serviceState didn't show up until the whole function is finished. This means that the users won't be able to see the "PENDING" state, only "READY" or "ERROR".

Did I miss something? Or should I use another way to initialize the status field? Thanks.

johnlinp avatar Sep 13 '22 00:09 johnlinp

I believe patch is only processed when the handler on_create(...) returns. If you want to update the status of your resource mid-flight (aka before your call to create_underlying_service() in order to set the status to PENDING, then you'll need to manually call the Kubernetes API to patch the status of your resource.

codewest avatar Sep 16 '22 17:09 codewest

I managed to find a way to do it:

@kopf.on.create('example.com', 'v1', 'foo')
def on_create(spec, patch, **kwargs):
    @kopf.subhandler(id='init_crd_status')
    def init_crd_status(**_):
        patch.status['serviceState'] = 'PENDING' # tries to initialize the status

    @kopf.subhandler(id='do_create_underlying_service')
    def do_create_underlying_service(**_):
        result = create_underlying_service() # this runs very slow

        if result.success:
            patch.status['serviceState'] = 'READY'
        else:
            patch.status['serviceState'] = 'ERROR'

I'm not sure it's a hack or not. Any advice is appreciated. Thanks.

johnlinp avatar Sep 30 '22 03:09 johnlinp