-
Notifications
You must be signed in to change notification settings - Fork 47
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
Generic provider #179
base: master
Are you sure you want to change the base?
Generic provider #179
Conversation
Hey! thx for the PR! retrieving binaries from direct http endpoints has been an idea that I've been waiting to generalize as a provider for a while and seems like this PR could be the perfect segway towards that. WDYT if we take this PR as a starting point and create a new bin install --latest-url https://get.helm.sh/helm-latest-version https://get.helm.sh/helm-v3.13.1-linux-arm64.tar.gz The idea is that How does that sound? |
Hi! Yes, sounds good. I was also wondering how to have a generic approach. I will update the PR. |
Did you have a chance to take a look at the updated PR commits? |
It's a brilliant idea to provide providers with the most popular tools like |
hey! my apologies for delaying on this one. Will check it out this week 🙏 |
all bool | ||
force bool | ||
provider string | ||
latestURL 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 should move this latestURL
inside the generic provider only since it doesn't apply to all of them
@@ -57,7 +58,7 @@ func newInstallCmd() *installCmd { | |||
// TODO check if binary already exists in config | |||
// and triger the update process if that's the case | |||
|
|||
p, err := providers.New(u, root.opts.provider) | |||
p, err := providers.New(u, root.opts.provider, root.opts.latestURL) |
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.
same as the comment above. The provider itself should be the one who parses the latest url from the provided flags instead of sending this argument to all provider initializations. We'll have to refactor the code a bit but I believe it's worth it. We'll have to use different flagsets (https://pkg.go.dev/flag#NewFlagSet) per provider.
@@ -87,6 +88,7 @@ func newInstallCmd() *installCmd { | |||
Hash: fmt.Sprintf("%x", pResult.Hash.Sum(nil)), | |||
URL: u, | |||
Provider: p.GetID(), | |||
LatestURL: root.opts.latestURL, |
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.
Same as other comments, having this in the top level of the config seems weird. I was thinking that we could maybe extend the provider
key we already have and make it map
instead of string
. That way, we can save provider specific configurations in the config.
We could add a new GetConfig
methgod to the provider interface for this.
@@ -68,7 +68,7 @@ func newUpdateCmd() *updateCmd { | |||
updateFailures := map[*config.Binary]error{} | |||
|
|||
for _, b := range binsToProcess { | |||
p, err := providers.New(b.URL, b.Provider) | |||
p, err := providers.New(b.URL, b.Provider, b.LatestURL) |
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.
Same as comments in install.go
@@ -108,8 +108,7 @@ func newUpdateCmd() *updateCmd { | |||
// the same thing as install logic. Refactor to | |||
// use the same code in both places | |||
for ui, b := range toUpdate { | |||
|
|||
p, err := providers.New(ui.url, b.Provider) | |||
p, err := providers.New(ui.url, b.Provider, b.LatestURL) |
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.
Same as comments in install.go
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.
nit: renane generic.go
to http_generic.go
? WDYT?
func (g *generic) GetLatestVersion() (string, string, error) { | ||
log.Debugf("Getting latest release for %s", g.name) | ||
|
||
resp, err := http.Get(g.latestURL) |
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 should check if latestURL
is not empty here so we can add proper debug
logs for this with a message like: latest url not found for $name
or something
@@ -44,16 +45,16 @@ var ( | |||
dockerUrlPrefix = regexp.MustCompile("^docker://") | |||
) | |||
|
|||
func New(u, provider string) (Provider, error) { | |||
func New(u, provider, latestURL string) (Provider, error) { |
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.
Same as comments in install.go
@@ -70,5 +71,9 @@ func New(u, provider string) (Provider, error) { | |||
return newHashiCorp(purl) | |||
} | |||
|
|||
if len(latestURL) != 0 && (provider == "generic" || len(provider) == 0) { |
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.
Same as comments in install.go
return fname, fmt.Sprintf("%s/%s", g.baseURL, fname) | ||
} | ||
|
||
func newGeneric(u *url.URL, latestURL string) (Provider, error) { |
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.
seems like this provider is not very generic since it expects the URL to have a specific format or otherwise it'll fail. I'll leave a more general comment about this in the issue.
hey @speier just found the time to start looking at this and it's looking great and in the right direction. The most relevant comment I have is that the provider doesn't seem to be generic. If I understood the code correctly, if you give it an URL with a shape different than https://get.helm.sh/helm-v3.13.1-linux-arm64.tar.gz, it'll just fail to parse it and error out. Maybe I didn't explain my idea very well before ( apologies, not a native English speaker). My initial thought was to allow the generic provider to be able to fetch any kind of URL regardless of the format. So I could also do something like LMK if that makes sense or if there's something you see I'm missing. Thx again for contributing! |
Hi! The idea was to use a somewhat standard naming convention: |
Hello! Please allow to join your discussion. I would argue, that in case of generic provider such variables as os/arch should be at mercy of user. Otherwise we get non-generic provider. You could see another use case in #215, where the goal is to download shell scripts (like testssl). As for version, "latestURL" variable name suggests, that we are handling "rolling" version. Another discussible idea is how to optimize performance (save and check "Last-Modified" header, if exists?), or in worst case scenario - re-download and update (or better calculate hashsum and update only if necessary) |
Started as a Helm provider, trying to turn into a generic provider, see comments below.
Provider to download Helm releases from https://get.helm.shSupports getting latest version from https://get.helm.sh/helm-latest-version or fetching specified version.Unfortunately Helm using a rather strange way for their releases and they don't provide a list of release builds for OS/Arch, so we need to maintain a list of possible architecture and OS versions in the provider.