Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Better error messages for generated manifests #2599

Merged
merged 6 commits into from
Nov 19, 2019
Merged

Conversation

squaremo
Copy link
Member

@squaremo squaremo commented Nov 11, 2019

This PR improves the error messages for generated manifests, mainly by including the root path -- i.e., the --git-path value, or implicitly . -- as well as the path to the config file .flux.yaml, given relative to that.

For example, in the case of duplicate resources, here's the error message logged:

ts=2019-11-11T16:32:51.814302722Z caller=loop.go:101 component=sync-loop err="loading resources from repo: duplicate definition of resource <cluster>:namespace/demo generated by production/../.flux.yaml and stag
ing/../.flux.yaml"

NB this error message also names the resource in question, therefore fixes #2595.

@2opremio 2opremio self-assigned this Nov 11, 2019
@2opremio
Copy link
Contributor

It's looking much better now, thanks! Could you add a test?

@squaremo
Copy link
Member Author

Could you add a test?

Yus. And in fact, in doing so I discovered that duplicates among generated manifests are not detected, because cluster/kubernetes/resource/load.go doesn't attempt to detect them. What do you reckon, should I --

  • add duplicate detection in there
  • leave that case alone (or similarly, leave the later detection in as a backstop)

@2opremio
Copy link
Contributor

because cluster/kubernetes/resource/load.go doesn't attempt to detect them

Can you elaborate? That file does detect duplicates at

return fmt.Errorf(`duplicate definition of '%s' (in %s and %s)`, id, alreadyDefined.Source(), source)

@squaremo
Copy link
Member Author

because cluster/kubernetes/resource/load.go doesn't attempt to detect them

Can you elaborate? That file does detect duplicates at

In Load it detects when a manifest loaded from a file duplicates a manifest loaded from another file.
But in ParseMultidoc, which is used by Load as well as config generation, it doesn't attempt to detect duplicates within a chunk of bytes. So duplicate definitions within a file or a generated chunk of bytes aren't detected.

@2opremio
Copy link
Contributor

2opremio commented Nov 13, 2019

In Load it detects when a manifest loaded from a file duplicates a manifest loaded from another file.
But in ParseMultidoc, which is used by Load as well as config generation, it doesn't attempt to detect duplicates within a chunk of bytes. So duplicate definitions within a file or a generated chunk of bytes aren't detected.

Ah, now I understand, thanks. I was assuming that iterating over the resources, looking for duplicates after parsing was enough. But it isn't, since ParseMultidoc() already returns a map, silently and implicitly coalescing resources with identical ID.

Thanks! This ended up being more work that one would expect.

id := item.ResourceID().String()
if _, ok := objs[id]; ok {
return nil, fmt.Errorf(`duplicate definition of '%s' (in %s)`, id, source)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we somehow factor out the duplicate-check and message? maybe in a local function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It occurred to me too, but I didn't bother because it would increase the line count, and the sites are close together. Have I drunk too much Go-aid? Possibly.

Copy link
Contributor

@2opremio 2opremio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit, otherwise LGTM! Thanks @squaremo !

 - The relative path to the `.flux.yaml` from a particular ConfigFile
   won't change over its lifetime, so we can calculate it when
   creating the ConfigFile. Then there's no need to check for errors
   later, which is more convenient.

 - record the "original" path, that is the path as supplied by the
   user (which may be `.`, implicitly). This can then be used to
   further identify where particular manifests came from, especially
   in errors.
When collecting all the generated resources in configaware.go, we have
an idea of where each one came from because it either has a config
file attached to it or not.

So we can report quite accurately where duplicate definitions arise --
they will either duplicate a resource in a YAML file (no config file
attached), the config file currently being processed, or a config file
previously processed.

To show the config file path as well as the --git-path in question,
I've combined them into a gitpath-plus-relative-path. For example, if
the original path is `staging`, but the .flux.yaml found is actually
in the directory above, it'll use `staging/../.flux.yaml` as the
location of the config file.
This gives the various paths clearer names, by appending `Relative` to
those which are supplied or calculated as relative to another.

The method `ConfigRelativeToWorkingDir()` gives the path to the config
file, starting from the working directory. This encodes two pieces of
information: the working directory aka `--git-path`, and where the
config file is in the git repo.

This is also used as the Source of generated manifests (since it will
always end in the configuration file name, it'll still work in
comparisons e.g., in pkg/daemon/sync.go).
When asssembling manifests from files or generators, there are some
checks for duplicate definitions. However, duplicates _within_ a
(multi-doc) file, or within a generated set of manifests, won't be
detected, since the code that parses a chunk of bytes (in
cluster/kubernetes/resource/load.go) doesn't check for duplicates.

So: add a test that duplicates within a generated set of manifests are
detected, and make it pass by checking when parsing bytes into
manifests.
To wit:
 - when a manifest appears in a YAML file, and is also generated
 - when a manifest is generated by two different configs
@squaremo squaremo merged commit b5a739b into master Nov 19, 2019
@squaremo squaremo deleted the better-fluxyaml-sources branch November 19, 2019 14:12
@2opremio 2opremio added this to the 1.16.0 milestone Nov 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve error messages involving resources from .flux.yaml files
2 participants