Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: check-for-changes.sh should not fall out of sync with shared logic #2260

Merged

Conversation

polarathene
Copy link
Member

@polarathene polarathene commented Oct 25, 2021

Description

Removes duplicate logic from check-for-changes.sh that is used/maintained elsewhere to avoid risk of problems, as this code is already starting to diverge / rot.


Previously the change detection support has had code added for rebuilding config upon change detection which is the same as code run during startup scripts. Unfortunately over time this has fallen out of sync. Mostly the startup scripts would get maintenance and the contributor and reviewers may not have been aware of the duplicate code handled by check-for-changes.sh.

That code was starting to diverge in addition to some changes in structure (eg: relay host logic seems interleaved here vs separated out in startup scripts). I wanted to address this before it risks becoming a much bigger headache.

Rather than bloat helper-functions.sh further, I've added a helpers/ folder extracting relevant common logic between startup scripts and changedetector. If you want to follow that process I've kept scoped commits to make those diffs easier. Some minor changes/improvements were added but nothing significant.

I've not given too much thought to naming conventions at present, that should still be fairly flexible. A similar PR will be handled for TLS functionality and additional changes to check-for-changes.sh once #2245 is merged. I want to minimize any merge conflicts due to related PRs open.

accounts.sh contains logic that #2248 is updating, so I've reverted my setup-stack.sh changes for that affected method to avoid merge conflicts. Once it is merged, a merge commit into this PR should go smoothly and I'll sync changes to accounts.sh, followed by bringing back the minimal setup-stack.sh:_setup_dovecot_local_user method this PR introduces.


Ran into a little confusion with shellcheck lint, that's been resolved and some extra maintainer comment docs in the lint.sh for shellcheck to clarify it to others. Probably will migrate to maintainer docs at a later stage.

A recent PR shellcheck linting behaviour/config came up and regarding SCRIPTDIR was also identified here.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (non-breaking change that does improve existing functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (README.md or the documentation under docs/)
  • If necessary I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

`/etc/postfix/sasl_passwd` is removed upfront if `SASL_PASSWD` is not set and this file exists for some reason.

Otherwise, the intention was to add that ENV value to an empty `/etc/postfix/sasl_passwd`, thus `>` is appropriate here.

No need for separate conditionals.
- Pulled out the warning conditional.
- Added comment for context about the tabbed white-space chars.
- Extracted the shared `/etc/postfix/sasl_passwd` adjustments to be a fix.
Rather than bloat `helper-functions.sh`, a new `relay.sh` file will make the various logic available as scoped functions.

This is necessary for `check-for-changes.sh` to adopt.
Moves the conditional ENV into the merged method.
DRY to avoid falling out of sync again via co-location and shared methods.
These are possibly more verbose than needed and can be reduced at a later stage.

They are helpful during this refactor process while investigating that everything is handled correctly.
Similar to other methods, explicitly clear `/etc/postfix/vhost` upfront. Avoids any lingering state if container mishaps from happening, such as container restarts causing issues in the past.

Additional notes added for context.
`check-for-changes.sh`:
- TODO for considering LDAP support/compatibility with change detection, at least for cert renewals.
- Another note about potential LDAP support in future, where vhost step needs to make sure to persist a value specifically handled for LDAP.
- In `start-mailserver.sh` the account creation is guarded by `SMTP_ONLY` ENV, carrying that over to this too.

`helper-functions.sh`: Add the new `helpers/` scripts for other consumers to utilize.

`accounts.sh`: 
- Add TODO for PR that needs to sync changes to this file after merge.
- Add note regarding potential bug for bare domain setups with `/etc/postfix/vhost` and `mydestination` sharing same domain value.

`aliases.sh`:
- Add note about LDAP and new logic that will also operate on the `postfix-virtual.cf` file once PR is merged.
- Split `_create_aliases` method into three separate responsibilities it covered, kept original method for other scripts to call.

`relay.sh`: 
- Remove the tabs for a single space delimiter, revised associated comment.
- Add PR reference for original `_populate_relayhost_map` implementation which has some useful details.
- Remove unnecessary shellcheck disable rule.
This should avoid having to mess with any merge conflicts.

Once the other PR is merged, the intended changes can be applied again here, and the `accounts.sh` method synced.
@georglauterbach georglauterbach added area/scripts kind/improvement Improve an existing feature, configuration file or the documentation labels Oct 26, 2021
@georglauterbach georglauterbach added this to the v10.3.0 milestone Oct 26, 2021
@georglauterbach
Copy link
Member

This PR look like it introduces really nice changes! Keep it up :D

PR merged, used merge commit to align with master and now it's good to restore changes for this method, along with syncing the changes from the PR it was waiting on.

Most of that PR has been assigned to a function to scope it, rather than blend in with the main account function logic.
Better to source through a single file instead.

Relative paths should be ok to use too, instead of the absolute container paths.
This took a while to figure out, added some inline doc comments to assist others in future.
The helpers folder doesn't get copied over, add it afterwards.
This was missed when extracting from `check-for-changes.sh`, without it, results in duplicate entries (old + new) in the relay test causing a failure.
@polarathene polarathene marked this pull request as ready for review November 13, 2021 00:35
Copy link
Member

@georglauterbach georglauterbach left a comment

Choose a reason for hiding this comment

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

If I see and understand all of this correctly, there is no "new" functionality in this PR, but this PR cleans up the whole check-for-changes.sh mess plus additional cleanup?

Exceptionally well done, LGTM!

target/scripts/helpers/index.sh Show resolved Hide resolved
@polarathene
Copy link
Member Author

polarathene commented Nov 13, 2021

If I see and understand all of this correctly, there is no "new" functionality in this PR

Correct 👍

but this PR cleans up the whole check-for-changes.sh mess plus additional cleanup?

Yeah, an initial pass. It still causes a large diff so I didn't want to introduce any broader changes, those can be addressed in a follow-up PR at a later point :)

I made sure to use commit history for easier to follow transition of changes if helpful.

@casperklein
Copy link
Member

Sorry for the delay. Sometimes I am bit scared when I see large PR/changes 😄. I'll try to review it within the next week.

@polarathene
Copy link
Member Author

Sometimes I am bit scared when I see large PR/changes 😄

It's really not as large as it looks in the diff. The commit history is intended to help provide you with that confidence as I was careful to break down the transition for better review by diffs.

Even without that, you can bring up your own diff app (eg: meld) and take the setup-stack.sh deleted sections to find they're effectively 1:1 copied to functions in new files. Only minor differences might be splitting into multiple functions and some conditionals.

check-for-changes.sh roughly is the same I believe I kept the order intact and just call the extracted functions. I used a diff against setup-stack.sh initially while extracting the common logic out to the new helpers.

I'll try to review it within the next week.

No worries, take your time reviewing it, no rush 👍

@polarathene polarathene mentioned this pull request Nov 14, 2021
4 tasks
georglauterbach and others added 2 commits November 15, 2021 21:22
Failure occurred from a merge commit, so the default range is too sensitive for this test.
target/scripts/helper-functions.sh Outdated Show resolved Hide resolved
target/scripts/helpers/relay.sh Outdated Show resolved Hide resolved
target/scripts/helpers/sasl.sh Outdated Show resolved Hide resolved
target/scripts/helpers/relay.sh Outdated Show resolved Hide resolved
target/scripts/helpers/postfix.sh Outdated Show resolved Hide resolved
@casperklein
Copy link
Member

One other thing to consider is, to conditionally source some helpers, e.g.:

source SASL stuff only, if SASL is used

Co-authored-by: Casper <casperklein@users.noreply.github.com>
@polarathene
Copy link
Member Author

One other thing to consider is, to conditionally source some helpers, e.g.:

source SASL stuff only, if SASL is used

Are you referring to the check-for-changes.sh part?

That is something I'd like to do, but deferred from this PR to ease review since I wanted it to be reasonably clear in the diff that the bulk of it is just shifting the logic out to new files, especially with check-for-changes.sh having differed a bit in order and some lines.

@casperklein
Copy link
Member

I was referring to helpers/index.sh. It was just a (future) suggestion, no need to change/improve it now.

@polarathene
Copy link
Member Author

polarathene commented Nov 17, 2021

I was referring to helpers/index.sh. It was just a (future) suggestion, no need to change/improve it now.

Ah, well that's already handled either within the function or via the caller IIRC.

The SASL one has two functions, one that checks the ENV and another that checks for a file. It seems that those conditions are best suited where they are and that conditionally sourcing the functions/file would be a bit more messier and prone to timing? (especially at setup)

@casperklein
Copy link
Member

casperklein commented Nov 17, 2021

prone to timing?

A bit. But it will also save memory 😉 In that particular case, I admit, it's not worth 😆
It was more a general thinking: Source only those files/function that are needed.

Edit: I misunderstood the timing thing. There should be no race condition or what did you mean?

@polarathene
Copy link
Member Author

Edit: I misunderstood the timing thing. There should be no race condition or what did you mean?

  • aliases.sh:_handle_postfix_aliases_config checks if /tmp/docker-mailserver/postfix-aliases.cf exists, otherwise creates it, not really anything to conditionally source there, but if anything else expected /tmp/docker-mailserver/postfix-aliases.cf when invoked later on, and we didn't originally source it because the file didn't exist, that'd fail silently? (a quick grep through the project for postfix-aliases.cf suggests this currently isn't used for anything, so it's unclear why we create this as an empty file if it doesn't exist, other than possibly because it's expected by the file monitor?)
  • postfix.sh:_create_postfix_vhost likewise relies on /tmp/vhost.tmp which is populated at runtime by setup-stack.sh:_setup_ldap, accounts.sh:_create_accounts and aliases.sh:_handle_postfix_virtual_config.
  • relay.sh:_populate_relayhost_map checks for postfix-accounts.cf and postfix-virtual.cf files, non-issue if you don't have relay enabled, and the two methods in relay.sh: _setup_relayhost (setup-stack.sh) and _rebuild_relayhost (check-for-changes.sh) handle the conditional checks for what to run.. you could lift that up into index.sh to only source if RELAY_HOST exists, I didn't investigate enough to check why DEFAULT_RELAY_HOST was handled separately though which may defeat the benefit of sourcing that way.
  • Additionally with relay.sh there's a SASL section, if that's conditionally sourced, it needs to add logic to conditionally not run that method when sasl.sh is not sourced.

Timing wise, I was thinking more about the time that helper-functions.sh is sourced and these conditional sourcing would apply, vs changes that occur after that point onwards. Besides the concerns above that need to be accounted for, check-for-changes.sh might later have a config file created/added but if we sourced conditionally based on that, the related scripts wouldn't have been sourced.. perhaps you only had ENV in mind for conditionally sourcing?

Just seems like more maintenance burden for minimal benefit vs just sourcing it all and guarding with conditionals within the respective files like we presently have. There is some conditionals external still, such as SMTP_ONLY IIRC.


Personally I prefer the requirements to run the logic to be clearly defined within these files themselves, so conditionally sourcing at index.sh will for the most part duplicate that, or enforce a hard requirement of sourcing only via index.sh (or rather implicitly via helper-functions.sh).

After this is merged, I'd like to move some of the helper-functions.sh out to separate files too, and noticed that the new files in this PR rely on functions from helper-functions.sh already and dependency management via sourcing in each file would be messy in bash 😅

So at best I might leave a comment to reference them at the top, but rely on importing via index.sh anyway, so this will probably be the advised way to use any method regardless (via sourcing helper-functions.sh as we currently do), so lifting the conditions where appropriate is probably fine...but then complicates it a bit further for minimal benefit when calling the functions that may not be sourced (eg: the relay ones in setup-stack.sh and check-for-changes.sh, it's more convenient to have the conditional execution wrapped in the associated relay.sh file and just source unconditionally)

Co-authored-by: Casper <casperklein@users.noreply.github.com>
@polarathene polarathene merged commit 5254f7c into docker-mailserver:master Nov 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/scripts kind/improvement Improve an existing feature, configuration file or the documentation priority/medium
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants