Closed ainsleyclark closed 3 years ago
Edit:
I noticed there is a walk function, would you be able to explain how to copy info.Path
to a relative dir?
Many thanks.
Hello,
Thank you for your interest in this project.
Yes this is totally possible! :)
The provider you are passing to the updater has the following methods:
GetLatestVersion() (string, error) // Get the latest version (Should be accessible even if Open() was not called)
Walk(walkFn WalkFunc) error
Retrieve(srcPath string, destPath string) error
Open() error
Close() error
You can call the provider by yourself if the update is successful. For that you can check the return value of updater.Update
If you need examples of how to use the provider you can look at the unit tests: https://github.com/mouuff/go-rocket-update/blob/77dfb83a6a982d6bfaa319dda927ba97898b7e70/pkg/provider/provider_test.go#L40
I should probably add something to run post-update actions so you don't have to call Open() and Close() yourself (which can take some time depending on the provider you are using), it wouldn't be too hard. Basically we just need a callback here: https://github.com/mouuff/go-rocket-update/blob/77dfb83a6a982d6bfaa319dda927ba97898b7e70/pkg/updater/updater.go#L142 Fell free to make a PR if you want :) I can try to find some time over the weekend to do that if you are interested in that feature but I might not be able to find the time.
And to answer: "how to copy info.Path to a relative dir?" just call provider.Retrieve(info.Path, YOUR_DESTINATION_PATH) :)
Hi @mouuff Thank's so much for getting back to me. This seems to make a lot of sense.
A couple of questions:
With regards to using the walk function and updating, would the process be similar to below? (Without a callback?)
Open()
the provider and defer Close()
Walk()
and use Retrieve()
for file copying etc.Update()
Post update functions sound fantastic, would you just pass a function back to the caller? So you could run the Walk()
function after it has been updated?
This maybe an edge use case, but I think other people may have multiple files and folders they need to delete and update. For instance, I will be backing up an entire directory with the executable, and a few folders naming it backup.old
or something. Can we pass in a flag so that go-rocket-update does not create the .old
files? (more of a manual approach).
How do checksums get verified? I have a checksums.txt file when releasing, is that something that the updater looks out for? If not, would there be a manual way to verify them myself? (screenshot below)
Really appriciate your time, I think it's a great project. I just feel that a bit more documentation would help this project so much!
Have a good one!
Hello!
Updater
struct and the Update()
method would call this post-update function.EDIT: You can also check this example if you want to rollback after a failed update (it would work to prevent corrupt binaries, permission issues, etc): https://github.com/mouuff/go-rocket-update/blob/master/examples/github-rollback/main.go
Hey @mouuff
Thanks for all of these details and great info.
With regards to the call back for updating files, if you give me some more details of what you think may work I can help with a PR.
Although it's great functionality, I won't need to sign packages, but I would love to verify the checksum of the file. We could perhaps add a ChecksumsFile string
property to github
? And run something similar to below?
// getRemoteSum retrieves the checksums file from Git and
// separates the release versions (os) by scanning
// each line. The archive name is compared to
// find a match.
func getRemoteSum(url, path string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := strings.Split(scanner.Text(), Separator)
if len(line) != 2 { //nolint:gomnd
continue
}
if line[1] == filepath.Base(path) {
return line[0], nil
}
}
return "", ErrNoCheckSum
}
Then it would just be a case of checking if it's set when it's stored in the TempDir
.
Sorry if this post has gone on a bit of a tangent!
Many thanks.
Hello, I m sorry for the late answer! If you want to add a post-update callback I think you can add an interface to the updater struct.
Something like:
type UpdateHook interface {
PostUpdate(u *Updater) error
}
// Updater struct
type Updater struct {
Provider provider.Provider
ExecutableName string
Version string
OverrideExecutable string // (optionnal) Overrides the path of the executable
Hook UpdateHook
latestVersion string // cache for the latest version
}
And in the Update()
method you can do something like this:
err = u.updateExecutable()
if err == nil {
status = Updated
}
// WARNING: any code after that should also call Rollback() on failure
if status == Updated {
err = u.Hook.PostUpdate(u)
if err != nil {
u.Rollback()
status = Unknown
}
}
Then you can pass your implementation to the updater :)
As for the checksum, if we handle that, I would prefer to make it work for all providers.
We can dedicate a relative path for the checksum (pretty much like the SignatureRelPath
today)
For example /checksums.txt
and then we would have a provider (Lets say Provider.Checksum
until we find a better name) which uses any another provider to retrieve the files.
And the Provider.Checksum
would look for that /checksums.txt
file and do the verification every time we call Retrieve
(and just to be clear, it would use any other provider to actually retrieve the files).
It would work the name way as for the Provider.Secure
here: https://github.com/mouuff/go-rocket-update/blob/master/pkg/provider/provider_secure.go
Then for the Github case, we have many solutions:
/checksum.txt
file to your zip before upload. If we do that then it would be nice to have a command in rocket-update to generate the checksums (again just like the commands for the signatures).Provider.Github.Retrieve()
on /checksums.txt
(since apparently you can get it from the Github API. right?)Provider.Github
since we already use another provider to decompress the files you can add Provider.Checksum
over this one (and you would have to get the checksums from the Github's API again), and it will work seamlesslyHello, I found some time to add this "hook" feature.
Here is an example:
type TestHook struct {
}
func (hook *TestHook) PostUpdate(u *updater.Updater) error {
fmt.Println("I am running after a successful update!")
return nil
}
You must also pass this struct as Hook
parameter to the Updater
Regards
Thanks for the update 😀
Hi, Thanks for the great package, I have been looking for this for a while. Is it possible to retrieve the contents of the zip folder? I have multiple fies and folders to update and want to manually override them along with the update. Is this possible? Many thanks.