Circular dependencies with export CDIST_ORDER_DEPENDENCY=1 #99

Closed
opened 2021-11-20 13:23:53 +00:00 by ungleich-gitea · 2 comments

Created by: darko-poljak

In mailing list the following case was reported as not working, resulting in circular dependency.

Init manifest

__foo

__foo type manifest:

export CDIST_ORDER_DEPENDENCY=1

__group ...
__user ...

Error

The requirements of the following objects could
not be resolved:
__user/... requires:
         __group/...
__user/... autorequires:

__group/... requires:
         __foo/...
__group/... autorequires:

__foo/... requires:

__foo/... autorequires:
         __user/... 

__user/... requires:
__group/...
is the result of injecting last created type requirement
__group/... requires:
__foo/...
is the result of injecting last created type requirement
__foo/... autorequires:
__user/...
is the result of autorequirement.

foo autorequires group is not set since group requires foo was injected.

*Created by: darko-poljak* In mailing list the following case was reported as not working, resulting in circular dependency. Init manifest ``` __foo ``` __foo type manifest: ``` export CDIST_ORDER_DEPENDENCY=1 __group ... __user ... ``` Error ``` The requirements of the following objects could not be resolved: __user/... requires: __group/... __user/... autorequires: __group/... requires: __foo/... __group/... autorequires: __foo/... requires: __foo/... autorequires: __user/... ``` __user/... requires: __group/... is the result of injecting last created type requirement __group/... requires: __foo/... is the result of injecting last created type requirement __foo/... autorequires: __user/... is the result of autorequirement. foo autorequires group is not set since group requires foo was injected.
Author
Owner

Created by: darko-poljak

@telmich I will try to clarify the case better.

Let we have the following init manifest:

__foo

and foo type manifest:

export CDIST_ORDER_DEPENDENCY=1

__group ...
__user ...

So this means that we want dependency in type's manifest based on the order of types.
Here we want that __user type requires __group type.

What cdist determines is that

__group/... requires: __foo/...
__user/... requires: __group/...
__foo/... requires:  __user/...

So, __user requires __group, which requires __foo, which requires __user, and we have circle here.

How we came to that dependency tree?

  1. __foo type should depend on all types it uses in its manifest.
    When __foo type is executed, first __group type is executed.
  2. cdist sess that CDIST_ORDER_DEPENDENCY is defined.
    It looks for the previous type created. It finds __foo type and injects it as a requirement.
    And now we have __group/... requires: __foo/....
  3. Next step is auto requirement. cdist tries to define that __foo auto requires __gorup,
    but it sees that __group already requires __foo so it skips this.
  4. Next __user type is executed.
  5. cdist sess that CDIST_ORDER_DEPENDENCY is defined.
    It looks for the previous type created. It finds __group type and injects it as a requirement.
    And now we have __user/... requires: __group/....
  6. Next step is auto requirement. cdist tries to define that __foo auto requires __user,
    it sees that there is no __user requires __foo so it defines:
    __foo/... autorequires:__user/....

In the end we have this:

__group/... requires: __foo/...
__user/... requires: __group/...
__foo/... requires:  __user/...

And this is wrong!

The wrong step is in 2.. cdist should not inject requirement of type which manifest is being executed for a type in type's manifest. In the above case, requirement of __foo for type __group should not be injected!
Note that when CDIST_ORDER_DEPENDENCY in used only in init manifest, this does not happen because for init manifest, when first type is executed, previous type created is None.

*Created by: darko-poljak* @telmich I will try to clarify the case better. Let we have the following init manifest: ``` __foo ``` and foo type manifest: ``` export CDIST_ORDER_DEPENDENCY=1 __group ... __user ... ``` So this means that we want dependency in type's manifest based on the order of types. Here we want that `__user` type requires `__group` type. What cdist determines is that ``` __group/... requires: __foo/... __user/... requires: __group/... __foo/... requires: __user/... ``` So, `__user` requires `__group`, which requires `__foo`, which requires `__user`, and we have circle here. How we came to that dependency tree? 1. `__foo` type should depend on all types it uses in its manifest. When `__foo` type is executed, first `__group` type is executed. 2. cdist sess that `CDIST_ORDER_DEPENDENCY` is defined. It looks for the previous type created. It finds `__foo` type and injects it as a requirement. And now we have `__group/... requires: __foo/...`. 3. Next step is auto requirement. cdist tries to define that `__foo` auto requires `__gorup`, but it sees that `__group` already requires `__foo` so it skips this. 4. Next `__user` type is executed. 5. cdist sess that `CDIST_ORDER_DEPENDENCY` is defined. It looks for the previous type created. It finds `__group` type and injects it as a requirement. And now we have `__user/... requires: __group/...`. 6. Next step is auto requirement. cdist tries to define that `__foo` auto requires `__user`, it sees that there is no `__user` requires `__foo` so it defines: `__foo/... autorequires:__user/...`. In the end we have this: ``` __group/... requires: __foo/... __user/... requires: __group/... __foo/... requires: __user/... ``` And this is wrong! The wrong step is in **2.**. cdist **should not** inject requirement of type which manifest is being executed for a type in type's manifest. In the above case, requirement of `__foo` for type `__group` should not be injected! Note that when `CDIST_ORDER_DEPENDENCY` in used only in init manifest, this does not happen because for init manifest, when first type is executed, previous type created is **None**.
Author
Owner

Created by: darko-poljak

@telmich @asteven
The wrong part here is
__group/... requires:
__foo/...
injection.

When CDIST_ORDER_REQUIREMENT is set, if last created type is object whose type manifest is
currently being executed, then such requirement should not be injected.

PR follows.

*Created by: darko-poljak* @telmich @asteven The wrong part here is __group/... requires: __foo/... injection. When CDIST_ORDER_REQUIREMENT is set, if last created type is object whose type manifest is currently being executed, then such requirement should not be injected. PR follows.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ungleich-public/cdist#99
No description provided.