Code Monkey home page Code Monkey logo

Comments (8)

ainsleyclark avatar ainsleyclark commented on May 10, 2024

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.

from go-rocket-update.

mouuff avatar mouuff commented on May 10, 2024

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:

err = p.Walk(func(info *provider.FileInfo) error {

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:

status = Updated

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) :)

from go-rocket-update.

ainsleyclark avatar ainsleyclark commented on May 10, 2024

Hi @mouuff
Thank's so much for getting back to me. This seems to make a lot of sense.

A couple of questions:

  1. 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()
  1. 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?

  2. 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).

  3. 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!

from go-rocket-update.

mouuff avatar mouuff commented on May 10, 2024

Hello!

  1. Yes exactly! But I think it makes more sense to call update first so you only do this action if the soft has been updated.
  2. Yes! We could add the function to the Updater struct and the Update() method would call this post-update function.
  3. Removing .old files is not done automatically today for few reasons. You can check this issue for more details: #13
  4. Today there is no way to verify the checksum.
    I think it doesn't add any more safety when using Github. Things you download shouldn't be corrupt with the protocol we are using. We could add a new Provider which verifies that (pretty much like the Provider.Secure https://github.com/mouuff/go-rocket-update/blob/master/pkg/provider/provider_secure.go)
    Talking of Provider.Secure, you can use this one to sign your updates, it will work to verify the integrity but it will also prevent other types of attacks :)
    Here is doc if you want to do that: https://github.com/mouuff/go-rocket-update/wiki/Sign-packages

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

from go-rocket-update.

ainsleyclark avatar ainsleyclark commented on May 10, 2024

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.

from go-rocket-update.

mouuff avatar mouuff commented on May 10, 2024

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:

  • Add the /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).
  • Return the checksums when you call Provider.Github.Retrieve() on /checksums.txt (since apparently you can get it from the Github API. right?)
  • Do it inside the 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 seamlessly

from go-rocket-update.

mouuff avatar mouuff commented on May 10, 2024

Hello, 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

from go-rocket-update.

ainsleyclark avatar ainsleyclark commented on May 10, 2024

Thanks for the update 😀

from go-rocket-update.

Related Issues (10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.