Skip to content

fix: stop two false warnings on every deploy, plus two papercuts - #13

Merged
anak10thn merged 2 commits into
mainfrom
fix/deploy-warnings
Aug 6, 2026
Merged

fix: stop two false warnings on every deploy, plus two papercuts#13
anak10thn merged 2 commits into
mainfrom
fix/deploy-warnings

Conversation

@anak10thn

Copy link
Copy Markdown
Member

Four bugs surfaced while testing PVC behaviour on a live cluster. No generated YAML changes — verified by diffing the full render before and after.

1. Every named volume warned about a file that cannot exist

level=warning msg="File don't exist or failed to check if the directory is empty:
stat :/var/lib/postgresql/data: no such file or directory"

ParseVols builds MountPath as "<host>:<container>". A named volume has no host, so it comes out as ":/var/lib/postgresql/data" — and that string was handed to os.Stat to decide whether it was a config file:

mountHost := volume.Host
if mountHost == "" {
    mountHost = volume.MountPath   // ":/data"
}
useConfigMap, _, skip = isConfigFile(mountHost)   // stats a path that cannot exist

Once per volume, on every deploy, alarming, untrue, and nothing a user can act on.

Only a bind mount has a host path worth inspecting, so the check is now guarded on one. Both return values were false for named volumes anyway, so the outcome is unchanged.

Note for reviewers: the loop also overwrites the useConfigMap that kompose.volume.type: configMap sets just above it — so that label has been dead for named volumes. I preserved that behaviour rather than fixing it blind, since changing it would alter output for anyone relying on the current result. Worth its own look.

2. external: true said it was ignored while honouring it

level=warning msg="External secrets app-secret is not currently supported - ignoring"

The fork printed that and then wired the volume to that exact Secret, correctly — as verified in the x-orcinus-env-from-secret work. The message was the only thing wrong. Now:

level=info msg="Secret \"app-secret\" is external: using the one in the cluster, not creating it"

Info, not warning, because nothing is wrong. (No SetLevel anywhere, so logrus's default keeps this visible.)

3. secret get header ignored its own tabwriter

 before                          after
Name:	db-creds                 Name:                 db-creds
Namespace:	default             Namespace:            default
Managed by orcinus:	true      Managed by orcinus:   true

Raw tabs, so the header landed on terminal tab stops while the table below it was aligned. My own papercut from #11.

4. Two live e2e tests shared a container name

TestLivePlugins and TestLivePlacement both used orcinus-pl, and liveCluster does docker rm -f <name> on the way in — so whichever ran second tore down the other's cluster. Only latent while they run sequentially, which is why it never bit.

Verification

Rendered a compose with a named volume, a bind mount, a read-only bind mount and an external secret, on both binaries:

=== old stderr ===                     === new stderr ===
External secrets ... - ignoring        Secret "app-secret" is external: ...
File don't exist ... stat :/var/...    (gone)
Service "app" won't be created ...     Service "app" won't be created ...

manifests: IDENTICAL

TestConvertNamedVolumeIsQuiet captures logrus output and fails if the stat warning returns — confirmed it fails without the fix, so it is not a false pass. The existing TestConvertBindMounts already covers what the guard could have broken (named volume → PVC, bind mount → hostPath, readonly preserved).

148 tests pass here; 202 in the kompose fork's own module.

Not fixed, on purpose

$(date +%s) in a command: renders as $()(date +%s), which crashes the container with a bare sh: syntax error that points nowhere near the cause. That is correct Compose behaviour — $ must be written $$ — so changing interpolation would break the spec. The error surface is genuinely bad though, and a lint that flags $( in command: would be worth discussing separately.

Four things surfaced while testing PVC behaviour on a live cluster. None change
a single byte of generated YAML — verified by diffing the full render before and
after.

**A named volume warned about a file that cannot exist.** ParseVols builds
MountPath as "<host>:<container>", and a named volume has no host, so it came
out as ":/var/lib/postgresql/data". That string was then handed to os.Stat to
decide whether it was a config file:

    level=warning msg="File don't exist or failed to check if the directory is
    empty: stat :/var/lib/postgresql/data: no such file or directory"

Once per volume, on every deploy, and nothing a user can do about it. Only a
bind mount has a host path worth inspecting, so the check is now guarded on
one. Both return values were false for named volumes anyway, so the outcome is
unchanged — including the fact that the loop overwrites the value the
kompose.volume.type label sets, which is left alone here rather than fixed
blind.

**`external: true` claimed it was ignored while honouring it.** The fork warned
"External secrets X is not currently supported - ignoring" and then wired the
volume to that exact Secret, correctly. The message was the only thing wrong;
it now says what happens, at info level, because nothing is wrong.

**`secret get` header ignored its own tabwriter**, printing raw tabs so the
header landed on terminal tab stops while the table below it was aligned.

**Two live e2e tests shared the container name "orcinus-pl"**, and liveCluster
does `docker rm -f <name>` on the way in — so whichever ran second tore down
the other's cluster. Only latent while they run sequentially.

TestConvertNamedVolumeIsQuiet captures logrus output and fails if the stat
warning returns; confirmed it fails without the fix. The existing
TestConvertBindMounts already covers the behaviour the guard could have broken
(named volume → PVC, bind mount → hostPath, readonly preserved).
Reviewing the message this branch introduced turned up that its `else` covers
three different situations, and the new wording is only right for one of them.

- `external: true` — the Secret exists in the cluster. Info, as before.
- `environment: VAR` — compose would read the value from that variable; orcinus
  does not, so no Secret is created and a service referencing it points at
  something that will never exist. That has to warn, naming the variable.
- anything else — no `file:`, not external. Warns plainly.

Saying "using the one in the cluster" for the middle case would have been worse
than the original message, since it asserts something that is not true.

The test asserts the level of the line about the secret rather than searching
the whole capture, which unrelated warnings ("won't be created because 'ports'
is not specified") would otherwise satisfy. It also matches on plain phrases:
logrus escapes the quotes inside msg, so looking for `Secret "s"` silently
never fires — the first draft of the quiet-conversion assertion passed for that
reason rather than because it was true.
@anak10thn
anak10thn force-pushed the fix/deploy-warnings branch from b9e3d2c to b755bd3 Compare August 6, 2026 05:45
@anak10thn
anak10thn merged commit 2f1b552 into main Aug 6, 2026
2 checks passed
@anak10thn
anak10thn deleted the fix/deploy-warnings branch August 6, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant