epics-containers / ibek

IOC Builder for EPICS and Kubernetes
https://epics-containers.github.io/ibek
Apache License 2.0
10 stars 4 forks source link

allow object ids in Arg defaults #215

Closed gilesknap closed 1 month ago

gilesknap commented 1 month ago

This is intended to support the Vacuum Space requirement of supplying a set of args that refer to objects but that the default for all but the first is to point back to the first.

@coretl please can you verify that this is supporting what we discussed yesterday. I suggest you look at the yaml and generated startup script as follows:

coretl commented 1 month ago

This makes sense, but do we need {{gauge1.name}}? Wouldn't {{gauge}} render as the same and produce the same string output, so be converted to the object in the same way?

gilesknap commented 1 month ago

Well no 😀

There are two steps.The Jinja renders using the current context and always creates a string because that's what Jinja does.

At whole model validation time I then check for objects currently showing as strings and look them up by ID.

If I turn on field validation for defaults it does not work. I end up getting the string representation of the object.

Having looked at field/model validation all day today to get Collections working I may now understand why and might have a fix for this.

Will report back.

gilesknap commented 1 month ago

@coretl I think this is the cause of needing .name:

When the pre_init script is being rendered in Jinja it is given all of the Entities as its context with the Entity's id as the index into that context.

When an argument is being rendered it is given all its other arguments as the jinja context. Because Object Arg is not an Entity it looks like a dictionary instead and renders as {key:value ... ...}. I'm not quite sure where that conversion happens, but looking in the debugger shows ObjectArg values as dictionaries - not as Entities. The object is assigned to the ObjArg value by the Entity field validator and I guess it is doing some coercion on the return value from the validator.

gilesknap commented 1 month ago

Might just accept that we need .(id name) in arg defaults that ref other object args for now ...

gilesknap commented 1 month ago

OK I fully understand the issue. This is the offending line https://github.com/epics-containers/ibek/blob/a1631b681f1e18f8df175e4192cae192ed01226c/src/ibek/ioc_factory.py#L148

We create an Entity class with object arguments of type object rather than Entity. We can't make them Entity at this stage because then schema validation would happen against the base class of Entity but we want to just supply a string id and have that converted to Entity object during field validation.