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

[#1215] Ensure module postrun command only runs for modified envs #1216

Merged
merged 1 commit into from
Sep 15, 2021

Conversation

Magisus
Copy link
Collaborator

@Magisus Magisus commented Sep 10, 2021

Previously, when a postrun command with interpolated environments was
specified, the deploy module command with no environments specified
would cause the command to be run for all environments that contained
the module, whether or not the env was actually updated by the
deploy.

Similarly, puppet generate types would be run for any environment that
contained the module, not just those for which it was updated. Together,
these two things could result in a huge amount of unnecessary work.

This commit makes modules return the result of their syncing, true for
"updated" and false for "not updated". The environment's deploy
function collects this information, recording the names of each module
that was updated as part of the deploy. The module deploy action then
uses this to determine which environments actually had modules modified,
and uses that to populate the $modifiedenvs in the postrun command. So
now, the command will only be run for environments that actually updated
a module.

This also updates the logic for running puppet generate types to
follow the same pattern: it is only run for environments that actually
had an updated module.

Note this does not affect environment deploys.

@Magisus Magisus force-pushed the module-postrun-bug branch 3 times, most recently from 68e0605 to aea1812 Compare September 10, 2021 23:35
@Magisus Magisus changed the title WIP Track which modules were updated during a sync [#1215] Ensure module postrun command only runs for modified envs Sep 10, 2021
@Magisus
Copy link
Collaborator Author

Magisus commented Sep 10, 2021

Tested this out, deploying a module to all environments, but only expecting it to be actually updated in one of them. Previously, this caused the following:

Running postrun command for environments prod1 prod2 production.

Now, it only runs for the one env where an update happened.

Running postrun command for environments prod1.

@Magisus Magisus marked this pull request as ready for review September 10, 2021 23:46
@Magisus Magisus requested a review from a team September 10, 2021 23:46
lib/r10k/action/deploy/module.rb Outdated Show resolved Hide resolved
lib/r10k/module/svn.rb Outdated Show resolved Hide resolved
lib/r10k/module/svn.rb Show resolved Hide resolved
lib/r10k/git/stateful_repository.rb Show resolved Hide resolved
lib/r10k/content_synchronizer.rb Outdated Show resolved Hide resolved
lib/r10k/content_synchronizer.rb Show resolved Hide resolved
spec/unit/action/deploy/module_spec.rb Outdated Show resolved Hide resolved
expect(R10K::Util::Subprocess).to receive(:new).
with(["/generate/types/wrapper", "first"]).
and_return(mock_subprocess)

expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
if environment.name == 'first'
expect(environment).to receive(:deploy).and_return(true)
expect(environment).to receive(:modules).and_return([mock_mod])
Copy link
Contributor

Choose a reason for hiding this comment

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

Why remove this?

spec/unit/module/git_spec.rb Outdated Show resolved Hide resolved
@alexjfisher
Copy link
Contributor

@Magisus Thanks for all your work on this! I've tested this PR out today in my environment and everything seems to work as advertised.

If I create a branch of a module with a random name not matching any environment name, the postrun isn't called.
If I create a branch that does match an existing environment, then the postrun is called with just that single environment.
If I merge a branch into main, most environments are affected and postrun is called with that long list of environments (this is still pretty slow for me, but something that I'd expect. It's not the usual case, and I can optimize my postrun script to cater for this. For example, if postrun is called with > 10 environments, call the puppetserver API once to flush all environments instead of looping through the environments and flushing them individually.)

@mwaggett
Copy link
Contributor

This will also need a changelog entry.

@mwaggett mwaggett added the bug label Sep 15, 2021
def self.concurrent_accept(modules, visitor, loader, pool_size, logger)
mods_queue = modules_visit_queue(modules, visitor, loader)
sync_queue(mods_queue, pool_size, logger)
end

# Returns a Queue of the names of modules actually updated
Copy link
Member

Choose a reason for hiding this comment

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

fwiw, I think this will return either a Queue of module names, or nil, if there was an error during a deprecated accept call, or raise if there was an error during the newer syncs.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want me to update this? I didn't dig into these methods, but I can if you want.

Copy link
Member

Choose a reason for hiding this comment

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

That's fine, I was more trying to tie together why we were checking for both nil? and empty? in the caller

…d envs

Previously, when a postrun command with interpolated environments was
specified, the `deploy module` command with no environments specified
would cause the command to be run for all environments that contained
the module, whether or not the env was actually updated by the
deploy.

Similarly, `puppet generate types` would be run for any environment that
contained the module, not just those for which it was updated. Together,
these two things could result in a huge amount of unnecessary work.

This commit makes modules return the result of their syncing, true for
"updated" and false for "not updated". The environment's `deploy`
function collects this information, recording the names of each module
that was updated as part of the deploy. The `module deploy` action then
uses this to determine which environments actually had modules modified,
and uses that to populate the `$modifiedenvs` in the postrun command. So
now, the command will only be run for environments that actually updated
a module.

This also updates the logic for running `puppet generate types` to
follow the same pattern: it is only run for environments that actually
had an updated module.

Note this does not affect environment deploys.
@justinstoller justinstoller merged commit fe65c73 into puppetlabs:main Sep 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants