Skip to content

Conversation

@nakabonne
Copy link
Member

What this PR does / why we need it:
Mainly this PR contains:

  • Enable to write and push the outdated images
  • Refactoring
  • Rename PipedImageWatcherRepoTarget to PipedImageWatcherFilter so Piped config will be like:
  imageWatcher:
    filters:
      - repoId: foo
        includes:
          - imagewatcher-dev.yaml

Also, currently the mutex is used for file locking. If we have to try to perform as fast as possible, I'd say it's preferable to have mutex for each repository. But premature optimization is the root of all evil. Let's use the same mutex for all file locking.

Which issue(s) this PR fixes:

Fixes #1210

Does this PR introduce a user-facing change?:

NONE

@pipecd-bot
Copy link
Collaborator

COVERAGE

Code coverage for golang is 33.81%. This pull request does not change code coverage.

@khanhtc1202
Copy link
Member

Rename PipedImageWatcherRepoTarget to PipedImageWatcherFilter

sorry for the dumb question, but I could not get the point of rename repos to filters. The name filters quite generic, and hard to understand what do we do with that field here.

}
}
return updates, nil
return cfg, nil
Copy link
Member

@khanhtc1202 khanhtc1202 Dec 16, 2020

Choose a reason for hiding this comment

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

nit: I suggest we could simplify the function signature of this config.LoadImageWatcher function to

func LoadImageWatcher(repoRoot string, includes, excludes []string) (*ImageWatcherSpec, error)

and create a new error type config.NotFound, then check it here with errors.Is.
The reasons is

  1. current ok value here look quite weird, should it be found? such that it's clarifying shown what do we use it for.
  2. I read the implementation of config.LoadImageWatcher once, looks like after check for os.IsNotExist we have to pass false value for it on all other cases.

What do you think of it? 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you! No objection to that! Other part should use that error type, so let me address it as another patch: #1259

Copy link
Member

Choose a reason for hiding this comment

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

thanks 👍

@nakabonne
Copy link
Member Author

@khanhtc1202

but I could not get the point of rename repos to filters.

Thanks for giving me the opportunity to rethink it. This config field mainly aims to filter the image watcher files. With the name repos, I feel like users can be confused, that's why I decided to rename it.

@nakabonne
Copy link
Member Author

IMO, config field name should tell users what it actually does by setting its name, but what do you think?

}

// run periodically compares the image stored in the given provider and one stored in git.
// run periodically compares the image in the given provider and one in git repository.
Copy link
Member

@nghialv nghialv Dec 16, 2020

Choose a reason for hiding this comment

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

Not in this PR's scope, but I feel that we should start thinking about simplifying the concurrency model implemented in this ImageWatcher package.

Current approach:

  • Spawn goroutines for each image provider
  • Inside each goroutine
    • loop the repositories
      • lock and pull to update the local git.repo data
      • load the configuration at .pipe to find the target providers
      • if the provider was specified, retrieve the latest images
      • lock and update them

Suggestion:

  • Spawn goroutines for each repository
  • Inside each goroutine
    • pull to update the local repo data
    • load the configuration at .pipe to find the target providers
    • loop the target providers
      • retrieve the latest images and update them

Pros:

  • don't need the look for git.Pull
  • avoid complex concurrent processing for git.Repo: pull and push
  • reduce the number of pulls and configuration loads (current: provider_num x repo_num, new: repo_num)

Cons:

  • The pull interval for all image providers must be same (I suggest to move that field into imageWatcher part, imageProvider part is only for defining how to interact with the image provider)

Copy link
Member Author

Choose a reason for hiding this comment

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

You're quite right. Current complex implementation is cause by the spec that requires to specify polling interval for each provider. I couldn't completely make up my mind for a long time. The way to be the same interval across all provider would be pretty simple, and love it. But isn't it really needed to configure the interval for each provider? I thought we should be more cautious about communication to the container registry than to git repository, that's why I designed like this.

Copy link
Member Author

Choose a reason for hiding this comment

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

But as you said, using the same interval is pretty good if it's not worth supporting.

Copy link
Member Author

Choose a reason for hiding this comment

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

For instance, a user has two image providers:

  • Docker Hub that has the strict pull rate limit
  • ECR that has not strict pull rate limit

For that, it's useful to respectively set pull intervals.

However, we don't have to handle such carefully if we define that case as an edge case.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think in that case they can split into multiple pipeds.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, agree with you. The general case had better be prioritized. Okay, let me work on them in another PR. I'll fix your other change requests.

Copy link
Member

Choose a reason for hiding this comment

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

👍

return fmt.Errorf("failed to replace value at %s with %s: %w", target.Field, imageInRegistry, err)
}
w.mu.Lock()
f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, os.ModeAppend)
Copy link
Member

Choose a reason for hiding this comment

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

Writing directly into the git.Repo may cause unexpected behaviors.

  • other goroutines are also accessing this local directory too
  • adding a new commit may cause a pull error in the future

So I think we have to clone it into a temporary directory for pushing the changes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds great idea, will do so!

Copy link
Member Author

Choose a reason for hiding this comment

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

This change will be unneeded if we change to spawn goroutines for each repository according to your suggestion in the above comment, right?

Copy link
Member Author

@nakabonne nakabonne Dec 16, 2020

Choose a reason for hiding this comment

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

Dumb... still remains an issue adding a new commit may cause a pull error in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

Leave TODO comments so may I address them when I work on the issue to spawn goroutines for each repo?

Copy link
Member

Choose a reason for hiding this comment

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

Sure.

if err := f.Close(); err != nil {
return fmt.Errorf("failed to close file %s: %w", path, err)
}
err = repo.Push(ctx, repo.GetClonedBranch())
Copy link
Member

Choose a reason for hiding this comment

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

We need to commit the changes before pushing.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, that's the basic part...

# encryptServiceAccountFile: /etc/piped-secret/encrypt-service-account.json

imageWatcher:
repos:
Copy link
Member

@nghialv nghialv Dec 16, 2020

Choose a reason for hiding this comment

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

One vote from me to keep it as repos. It may contain not only the filter thing but also other configurable fields (e.g. interval).

Copy link
Member

Choose a reason for hiding this comment

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

still do not have a good enough ideal for the name but the previous repos is lgtm. cc @nakabonne

Copy link
Member Author

Choose a reason for hiding this comment

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

From now my thought has been varied. Let's keep as is.

Copy link
Member Author

Choose a reason for hiding this comment

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

still do not have a good enough ideal for the name

Yup, I keep thinking the best name :D

@pipecd-bot
Copy link
Collaborator

TODO

The following ISSUES will be created once got merged. If you want me to skip creating the issue, you can use /todo skip command.

Details

1. Spawn goroutines for each repository

https://github.com/pipe-cd/pipe/blob/c70a038f0c4c348c572ff7fa0e1fa16eb045ae7d/pkg/app/piped/imagewatcher/watcher.go#L69-L72

This was created by todo plugin since "TODO:" was found in c70a038 when #1258 was merged. cc: @nakabonne.

2. Clone repository another temporary destination

https://github.com/pipe-cd/pipe/blob/c70a038f0c4c348c572ff7fa0e1fa16eb045ae7d/pkg/app/piped/imagewatcher/watcher.go#L72-L75

This was created by todo plugin since "TODO:" was found in c70a038 when #1258 was merged. cc: @nakabonne.

3. Make it changeable the commit message

https://github.com/pipe-cd/pipe/blob/c70a038f0c4c348c572ff7fa0e1fa16eb045ae7d/pkg/app/piped/imagewatcher/watcher.go#L206-L209

This was created by todo plugin since "TODO:" was found in c70a038 when #1258 was merged. cc: @nakabonne.

@nakabonne
Copy link
Member Author

@nghialv Fixed them. I'll address the created three issues in the next PR.

@pipecd-bot
Copy link
Collaborator

COVERAGE

Code coverage for golang is 33.81%. This pull request does not change code coverage.

@nghialv
Copy link
Member

nghialv commented Dec 16, 2020

/lgtm

@nakabonne
Copy link
Member Author

/cc @khanhtc1202

@khanhtc1202
Copy link
Member

thanks 👍
/approve

@pipecd-bot
Copy link
Collaborator

APPROVE

This pull request is APPROVED by khanhtc1202.

Approvers can cancel the approval by writing /approve cancel in a comment. Any additional commits also will change this pull request to be not-approved.

@pipecd-bot pipecd-bot merged commit 5ceca2c into master Dec 16, 2020
@pipecd-bot pipecd-bot deleted the update-images branch December 16, 2020 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make it possible to push outdated images to Git

5 participants