selfupdate

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2024 License: Apache-2.0 Imports: 19 Imported by: 0

README

self-update: Build self-updating Go programs

Coverage Status

This repository simplifies the logic from the fynelabs/selfupdate repository for easier use. Security-related checks such as hash values, checksums, and signature verifications, as well as scheduler-related logic, have been removed.

All you need to do is run it with the URL of the update you want. That's it!

Unmanaged update

Example of updating from a URL:

import (
    "fmt"
    "net/http"

    "github.com/Jaeminst/selfupdate"
)

func doUpdate(url string) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    err = selfupdate.Apply(resp.Body, selfupdate.Options{})
    if err != nil {
        // error handling
    }
    return err
}

Managed update

func main() {
	done := make(chan struct{})

	// The public key above match the signature of the below file served by our CDN
	httpSource := selfupdate.NewHTTPSource(nil, url)
	config := &selfupdate.Config{
		FetchOnStart: true,
		Source:       httpSource,

		RestartConfirmCallback: func() bool {
			// Add a custom cofirm survey here.
			// or success message
			done <- struct{}{}
			return true
		},
		UpgradeConfirmCallback: func(_ string) bool {
			// Add a custom cofirm survey here.
			return true
		},
	}

	_, err = selfupdate.Manage(config)
	if err != nil {
		fmt.Printf("Error while setting up update manager: %v", err)
		return
	}
	<-done
}

License

Apache

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNotSupported = errors.New("operating system not supported")

ErrNotSupported is returned by `Manage` when it is not possible to manage the current application.

Functions

func Apply

func Apply(update io.Reader, opts Options) error

Apply performs an update of the current executable (or opts.TargetFile, if set) with the contents of the given io.Reader.

Apply performs the following actions to ensure a safe cross-platform update:

1. If configured, applies the contents of the update io.Reader as a binary patch.

2. If configured, computes the checksum of the new executable and verifies it matches.

3. If configured, verifies the signature with a public key.

4. Creates a new file, /path/to/.target.new with the TargetMode with the contents of the updated file

5. Renames /path/to/target to /path/to/.target.old

6. Renames /path/to/.target.new to /path/to/target

7. If the final rename is successful, deletes /path/to/.target.old, returns no error. On Windows, the removal of /path/to/target.old always fails, so instead Apply hides the old file instead.

8. If the final rename fails, attempts to roll back by renaming /path/to/.target.old back to /path/to/target.

If the roll back operation fails, the file system is left in an inconsistent state (betweet steps 5 and 6) where there is no new executable file and the old executable file could not be be moved to its original location. In this case you should notify the user of the bad news and ask them to recover manually. Applications can determine whether the rollback failed by calling RollbackError, see the documentation on that function for additional detail.

This function is provided for backward compatibility with go-selfupdate original package

func ExecutableDefaultOldPath

func ExecutableDefaultOldPath() (string, error)

ExecutableDefaultOldPath returns the path to the old executable and an error if something went bad

func ExecutableRealPath

func ExecutableRealPath() (string, error)

ExecutableRealPath returns the path to the original executable and an error if something went bad

func RollbackError

func RollbackError(err error) error

RollbackError takes an error value returned by Apply and returns the error, if any, that occurred when attempting to roll back from a failed update. Applications should always call this function on any non-nil errors returned by Apply.

If no rollback was needed or if the rollback was successful, RollbackError returns nil, otherwise it returns the error encountered when trying to roll back.

Types

type Config

type Config struct {
	FetchOnStart           bool
	Zip                    bool
	Source                 Source            // Necessary Source for update
	RestartConfirmCallback func() bool       // if present will ask for user acceptance before restarting app
	UpgradeConfirmCallback func(string) bool // if present will ask for user acceptance, it can present the message passed
	ExitCallback           func(error)       // if present will be expected to handle app exit procedure
}

Config define extra parameter necessary to manage the updating process

type HTTPSource

type HTTPSource struct {
	// contains filtered or unexported fields
}

HTTPSource provide a Source that will download the update from a HTTP url. It is expecting the signature file to be served at ${URL}.ed25519

func (*HTTPSource) Get

func (h *HTTPSource) Get() (io.ReadCloser, int64, error)

Get will return if it succeed an io.ReaderCloser to the new executable being downloaded and its length

type Options

type Options struct {
	// TargetPath defines the path to the file to update.
	// The empty string means 'the executable file of the running program'.
	TargetPath string

	// Create TargetPath replacement with this file mode. If zero, defaults to 0755.
	TargetMode os.FileMode

	// If nil, treat the update as a complete replacement for the contents of the file at TargetPath.
	// If non-nil, treat the update contents as a patch and use this object to apply the patch.
	Patcher Patcher

	// Store the old executable file at this path after a successful update.
	// The empty string means the old executable file will be removed after the update.
	OldSavePath string
}

Options give additional parameters when calling Apply

func (*Options) CheckPermissions

func (o *Options) CheckPermissions() error

CheckPermissions determines whether the process has the correct permissions to perform the requested update. If the update can proceed, it returns nil, otherwise it returns the error that would occur if an update were attempted.

type Patcher

type Patcher interface {
	Patch(old io.Reader, new io.Writer, patch io.Reader) error
}

Patcher defines an interface for applying binary patches to an old item to get an updated item.

func NewBSDiffPatcher

func NewBSDiffPatcher() Patcher

NewBSDiffPatcher returns a new Patcher that applies binary patches using the bsdiff algorithm. See http://www.daemonology.net/bsdiff/

type Source

type Source interface {
	Get() (io.ReadCloser, int64, error) // Get the executable to be updated to
}

Source define an interface that is able to get an update

func NewHTTPSource

func NewHTTPSource(client *http.Client, base string) Source

NewHTTPSource provide a selfupdate.Source that will fetch the specified base URL for update and signature using the http.Client provided. To help into providing cross platform application, the base is actually a Go Template string where the following parameter are recognized: {{.OS}} will be filled by the runtime OS name {{.Arch}} will be filled by the runtime Arch name {{.Ext}} will be filled by the executable expected extension for the OS As an example the following string `http://localhost/myapp-{{.OS}}-{{.Arch}}{{.Ext}}` would fetch on Windows AMD64 the following URL: `http://localhost/myapp-windows-amd64.exe` and on Linux AMD64: `http://localhost/myapp-linux-amd64`.

type Updater

type Updater struct {
	// contains filtered or unexported fields
}

Updater is managing update for your application in the background

func Manage

func Manage(conf *Config) (*Updater, error)

Manage sets up an Updater and runs it to manage the current executable.

func (*Updater) CheckNow

func (u *Updater) CheckNow() error

CheckNow will manually trigger a check of an update and if one is present will start the update process

func (*Updater) Restart

func (u *Updater) Restart() error

Restart once an update is done can trigger a restart of the binary. This is useful to implement a restart later policy.

Directories

Path Synopsis
internal
binarydist
Package binarydist implements binary diff and patch as described on http://www.daemonology.net/bsdiff/.
Package binarydist implements binary diff and patch as described on http://www.daemonology.net/bsdiff/.
osext
Package osext provide extensions to the standard "os" package.
Package osext provide extensions to the standard "os" package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL