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
fixes #18964 - lifecycle environment container image name #7262
Conversation
|
Issues: #18964 |
|
@jlsherrill @parthaa @JacobCallahan - This feature will allow a 1:1 mirroring of a remote registry with the opportunity to keep the original image names (ie. openshift3/ose stays openshift3/ose for docker pull). Open questions: Should this be allowed for Library env? This would allow foreman to act as a constant mirror without user intervention, scheduled syncs would keep remote and foreman registries the same. (Note no mirror-on-sync feature in pulp @ipanova ;) ) Should I put a unique constraint on the registry_name_pattern? This will keep the chance of two repos having the same-named images. (I think that would violate pulp's rules but will confirm.) When a registry_name_pattern is changed for a lifecycle, what is the best way to update all the component content view repos? How should this be presented to user? How can I migrate all repos to retain their docker_upstream_name which was not being propogated to CVV repos? In a rake task or the migrate file? |
|
P.S. @parthaa - I changed the validation to allow an upstream name without an upstream url. This would let images that are hammer or docker pushed to use the upstream name in their registry pattern. (ie. disconnected registry mirroring) |
|
@thomasmckay it is ok to have 2 different repos with same upstream_name, just make sure the registry_id is different because of https://pulp.plan.io/issues/3165 |
a523e9b
to
e272233
Compare
|
Current dilemma: A new attribute is added to lifecycle environment, registry_name_pattern. This pattern (ERB) will define the container_repository_name for all repos in that environment. At the moment, the repo attribute is only updated through a before_validation on save. Here's how it should work: When the pattern attribute on an environment is updated, all the repos in that env need to have their name updated and propagated to pulp. All of the repos also need to be synced to capsules. (Ideally the sync would merely be for the repo attribute and not all content.) |
|
@thomasmckay so what we would do normally is make the lifecycle env create controller action async (so that a task gets returned), and as part of that action update all the repos and propagate the changes to pulp. However that already exists and is not async. What we could do is update the environment and then spawn a task to update all the docker repositories in the environment if the attribute changed. However the user still couldn't really track that easily to wait for it to finish and go use his docker repos. I assume that a desired feature? |
|
@jlsherrill - What if on changing the env pattern the user had to explicitly kick off a resync of the component repos? I don't think this would be too burdensome since I don't see a pattern of frequent env changes being normal. Perhaps there is a new endpoint to env api to refresh repos that would return task? |
e272233
to
4f2bba3
Compare
| end | ||
|
|
||
| #???? options content_type Katello::Repository::DOCKER_TYPE | ||
| def plan(env, options = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused method argument - options. If it's necessary, use _ or _options as an argument name to indicate that it won't be used.
| update_params[:name] = params[:environment][:new_name] if params[:environment][:new_name] | ||
| @environment.update_attributes!(update_params) | ||
| if update_params[:registry_name_pattern] | ||
| task = sync_task(::Actions::Katello::Environment::PublishRepositories, @environment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless assignment to variable - task.
| end | ||
|
|
||
| def run | ||
| env = ::Katello::KTEnvironment.find(input[:kt_environment][:id]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless assignment to variable - env.
| env.repositories.each do |repository| | ||
| repository.save! | ||
| plan_action(::Actions::Katello::Repository::Update, repository, {}) | ||
| plan_action(::Actions::Pulp::Repository::Refresh, repository) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jlsherrill @parthaa I'm just spamming actions here to try to get the the repo_registry_id to be updated in pulp. Any pointers of what to call to have that happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I have this sorted out; will clean up code a bit since I think this double action is not needed.
| concurrence do | ||
| env.repositories.each do |repository| | ||
| #repository.save! | ||
| plan_action(::Actions::Katello::Repository::Update, repository, {container_repository_name: repository.container_repository_name}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant curly braces around a hash parameter.
9405a81
to
049b9df
Compare
app/models/katello/repository.rb
Outdated
| set_container_repository_name | ||
| valid?( :container_repository_name) ? container_repository_name : nil | ||
| ensure | ||
| content_repository_name = original_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UselessAssignment: Useless assignment to variable - content_repository_name. Did you mean container_repository_name?
app/models/katello/repository.rb
Outdated
| def validate_container_repository_name | ||
| original_name = container_repository_name | ||
| set_container_repository_name | ||
| valid?( :container_repository_name) ? container_repository_name : nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/SpaceInsideParens: Space inside parentheses detected.
app/models/katello/repository.rb
Outdated
| @@ -757,6 +756,35 @@ def self.search_by_redhat(_key, operator, value) | |||
| end | |||
| end | |||
|
|
|||
| def safe_render_container_name(pattern=nil) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/SpaceAroundEqualsInParameterDefault: Surrounding space missing in default value assignment.
| end | ||
|
|
||
| def run | ||
| env = ::Katello::KTEnvironment.find(input[:kt_environment][:id]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UselessAssignment: Useless assignment to variable - env.
| concurrence do | ||
| repositories.each do |repository| | ||
| sequence do | ||
| plan_action(::Actions::Katello::Repository::Update, repository, {container_repository_name: repository.container_repository_name}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/BracesAroundHashParameters: Redundant curly braces around a hash parameter.
| update_params[:name] = params[:environment][:new_name] if params[:environment][:new_name] | ||
| @environment.update_attributes!(update_params) | ||
| if update_params[:registry_name_pattern] | ||
| task = sync_task(::Actions::Katello::Environment::PublishRepositories, @environment, content_type: Katello::Repository::DOCKER_TYPE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UselessAssignment: Useless assignment to variable - task.
|
Added repo name verification on environment save. https://github.com/Katello/katello/pull/7262/files#diff-043f3f54ba4d6ae4333d75f582861bd3R1 |
| <dd bst-edit-textarea="environment.registry_name_pattern" | ||
| on-save="save(environment)" | ||
| readonly="denied('edit_lifecycle_environments', environment)"> | ||
| </dd> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waldenraines - Is there a patternfly way to add some formatted help text to a field? I want to give brief description of valid formats but it should be formatted and not just a big unreadable string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do this on create, but i couldn't find any examples of on edit :(
app/models/katello/repository.rb
Outdated
| @@ -102,10 +104,19 @@ class Repository < Katello::Model | |||
| validates :product_id, :presence => true | |||
| validates :pulp_id, :presence => true, :uniqueness => true, :if => proc { |r| r.name.present? } | |||
| validates :checksum_type, :inclusion => {:in => CHECKSUM_TYPES}, :allow_blank => true | |||
| #???? refactor these into validator class, re-use in EnvironmentDockerRepositories validator | |||
| =begin | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/BlockComments: Do not use block comments.
app/models/katello/repository.rb
Outdated
| @@ -102,10 +104,19 @@ class Repository < Katello::Model | |||
| validates :product_id, :presence => true | |||
| validates :pulp_id, :presence => true, :uniqueness => true, :if => proc { |r| r.name.present? } | |||
| validates :checksum_type, :inclusion => {:in => CHECKSUM_TYPES}, :allow_blank => true | |||
| #???? refactor these into validator class, re-use in EnvironmentDockerRepositories validator | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/CommentIndentation: Incorrect indentation detected (column 4 instead of 0).
| name = repository.safe_render_container_name(environment.registry_name_pattern) | ||
| #???? check pre-render name is same as post-render? | ||
|
|
||
| if !ContainerImageNameValidator.validate_name(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/NegatedIf: Favor unless over if for negative conditions.
f22c17e
to
f74a688
Compare
| end | ||
|
|
||
| def test_update_pattern_fail | ||
| original_label = @staging.label |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UselessAssignment: Useless assignment to variable - original_label.
| @@ -79,6 +105,49 @@ def test_update | |||
| assert_equal original_label, @staging.label | |||
| end | |||
|
|
|||
| def test_update | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/DuplicateMethods: Method Katello::Api::V2::EnvironmentsControllerTest#test_update is defined at both test/controllers/api/v2/environments_controller_test.rb:93 and test/controllers/api/v2/environments_controller_test.rb:108.
| update_params[:name] = params[:environment][:new_name] if params[:environment][:new_name] | ||
| @environment.update_attributes!(update_params) | ||
| if update_params[:registry_name_pattern] | ||
| #???? should task be returned? what would be returned when async_task not called? | ||
| #???? optional param to make this a sync_task? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think i would return the task here. Technically the env is updated, its just further work that can be tracked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jlsherrill Should I change this to call update_attributes! in the plan() of the task so that there is always a task to return? (Is plan() the right place to do that?
7cb41c0
to
5c6ed65
Compare
|
There were the following issues with the commit message:
If you don't have a ticket number, please create an issue in Redmine. More guidelines are available in Coding Standards or on the Foreman wiki. This message was auto-generated by Foreman's prprocessor |
|
State of the PR: All functionality works and there is robust checking of environment registry pattern to prevent duplicate repository names. Unit test writing continues but live usage testing by others would be appreciated. |
5c6ed65
to
d42a289
Compare
cd16ec3
to
a05eb81
Compare
|
There were the following issues with the commit message:
If you don't have a ticket number, please create an issue in Redmine. More guidelines are available in Coding Standards or on the Foreman wiki. This message was auto-generated by Foreman's prprocessor |
a05eb81
to
dd6fe8a
Compare
| end | ||
|
|
||
| Katello::Repository.where(content_type: Katello::Repository::DOCKER_TYPE).each do |repository| | ||
| if !repositories.include?(repository) && names.include?(repository.container_repository_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jlsherrill - Updated this with original intention: Check all repos except for the current ones being processed (they're checked above) for name clashes.
Really struggling to write sensible tests.
|
Test I'd like to write in FactoryBot:
|
dd6fe8a
to
4d69a3b
Compare
test/models/content_view_test.rb
Outdated
| repo2_cv = build(:docker_repository, product: product, content_view_version: @organization.default_content_view.versions.first, library_instance_id: repo2_lib.id) | ||
| version2 = create(:katello_content_view_version, :content_view => view2, :repositories => [repo2_cv]) | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLines: Extra blank line detected.
4d69a3b
to
e08b81e
Compare
|
[test katello] |
e08b81e
to
0d8157b
Compare
|
[test katello] |
0d8157b
to
f55ffbd
Compare
|
Test written. Updated a few existing tests that had failed w/ the registry name unique constraint. |
|
[test katello] |
|
Small rubocop error. Also, i seem to be unable to repromote an existing cv that is already in dev, i get "Content View publish to environment dev will result in invalid container image name of member repositories", even though i'm promoting a cv thats already there. |
bcbad9f
to
3ba1341
Compare
|
@jlsherrill - Removed the repos check and switched to rely on uniqueness validator for repos. I am less excited about this but I can't wrap my head around how I could correctly check all the names. :) |
app/models/katello/repository.rb
Outdated
| allowed_methods = {} | ||
| allowed_vars = {} | ||
| scope_variables = {repository: repository, organization: repository.organization, product: repository.product, | ||
| environment: repository.environment, contentview: repository.content_view_version.content_view} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind making this 'content_view' instead of 'contentview'?
3ba1341
to
1243761
Compare
1243761
to
060c658
Compare
|
[test katello] |
This feature allows a lifecycle environment to specify a image name pattern (erb) to
use instead of the default ($org-$prod-$env-$cv-$name).
For example "<%= organization.label %>/<%= docker_upstream_name %>"
The pattern, on the lifecycle UI details page, is used for container image repositories. These repos have a name and label but in pulp they also have a "registry name". This registry name is what users use when referencing the repo for "docker pull" or "skopeo copy".
Prior to this PR, the registry name was hard coded based on a combination of organization, product, content view, life cycle, and repo labels. This style of auto-naming remains if the life cycle pattern is left blank.
The pattern is ERB format. This allows a rich flexibility in the resulting names. In the simplest, and likely the most common, is to simply use the repository's original container image name as the pattern.
It is important to remember that the results of running a repository through a life cycle's pattern must be unique across all repos in all orgs. Thus the same pattern should be reused in multiple life cycle's with care.
Variables available in ERB: