Fix displaying upgrade progress (#601)
This commit is contained in:
parent
66139ac3db
commit
39f5bde9f2
7 changed files with 645 additions and 628 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -137,10 +137,8 @@ jobs:
|
|||
run: |
|
||||
make prepare-image
|
||||
sed -i -e 's#-ld.*$#& -X github.com/andig/evcc/server/updater.Password=${{ secrets.IMAGE_PASS }}#' buildflags/github.com/andig/evcc/buildflags.txt
|
||||
cat buildflags/github.com/andig/evcc/buildflags.txt
|
||||
mkdir /home/runner/.config/gokrazy
|
||||
echo ${{ secrets.IMAGE_PASS }}> /home/runner/.config/gokrazy/http-password.txt
|
||||
cat /home/runner/.config/gokrazy/http-password.txt
|
||||
|
||||
- name: Build Image
|
||||
run: make image
|
||||
|
|
|
|||
|
|
@ -146,16 +146,14 @@ export default {
|
|||
this.updaterShown = !this.updaterShown;
|
||||
}
|
||||
},
|
||||
update: function () {
|
||||
axios
|
||||
.post("update")
|
||||
.then(() => {
|
||||
this.updateStatus = "Aktualisierung gestartet: ";
|
||||
this.updateStarted = true;
|
||||
})
|
||||
.catch((res) => {
|
||||
this.updateStatus = "Aktualisierung nicht möglich: " + res;
|
||||
});
|
||||
update: async function () {
|
||||
try {
|
||||
await axios.post("update");
|
||||
this.updateStatus = "Aktualisierung gestartet: ";
|
||||
this.updateStarted = true;
|
||||
} catch (e) {
|
||||
this.updateStatus = "Aktualisierung nicht möglich: " + e;
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
|
|
|||
1202
server/assets.go
1202
server/assets.go
File diff suppressed because it is too large
Load diff
|
|
@ -399,6 +399,7 @@ func NewHTTPd(url string, site core.SiteAPI, hub *SocketHub, cache *util.Cache)
|
|||
return srv
|
||||
}
|
||||
|
||||
// Router returns the main router
|
||||
func (s *HTTPd) Router() *mux.Router {
|
||||
return s.Handler.(*mux.Router)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ import (
|
|||
|
||||
const timeout = 30 * time.Second
|
||||
|
||||
// Repo is a github repository adapter
|
||||
type Repo struct {
|
||||
owner, repository string
|
||||
*github.Client
|
||||
}
|
||||
|
||||
// NewRepo creates repository adapter
|
||||
func NewRepo(owner, repository string) *Repo {
|
||||
r := &Repo{
|
||||
owner: owner,
|
||||
|
|
@ -30,6 +32,7 @@ func NewRepo(owner, repository string) *Repo {
|
|||
return r
|
||||
}
|
||||
|
||||
// GetLatestRelease gets latest of github releases
|
||||
func (r *Repo) GetLatestRelease() (*github.RepositoryRelease, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
|
@ -83,6 +86,7 @@ func (r *Repo) ReleaseNotes(from string) (rendered string, err error) {
|
|||
return history.String(), nil
|
||||
}
|
||||
|
||||
// FindReleaseAsset finds asset by name and returns ID and size
|
||||
func (r *Repo) FindReleaseAsset(name string) (int64, int, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
|
@ -101,6 +105,7 @@ func (r *Repo) FindReleaseAsset(name string) (int64, int, error) {
|
|||
return 0, 0, fmt.Errorf("asset not found: %s", name)
|
||||
}
|
||||
|
||||
// StreamAsset provides a ReadCloser for streaming the assets over HTTP
|
||||
func (r *Repo) StreamAsset(id int64) (io.ReadCloser, error) {
|
||||
rc, _, err := r.Repositories.DownloadReleaseAsset(context.Background(), r.owner, r.repository, id, http.DefaultClient)
|
||||
return rc, err
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ import (
|
|||
|
||||
// update constants
|
||||
const (
|
||||
MB = 1024 * 1024
|
||||
RootOffset = 8192*512 + 100*MB
|
||||
RootSize = 500 * MB
|
||||
RootFS = "evcc_%s.rootfs.gz"
|
||||
mb = 1024 * 1024
|
||||
rootOffset = 8192*512 + 100*mb
|
||||
rootSize = 500 * mb
|
||||
)
|
||||
|
||||
var (
|
||||
Password = "SECRET"
|
||||
Host = "localhost"
|
||||
Port = 8080
|
||||
Password = "SECRET"
|
||||
)
|
||||
|
||||
// unzipReader transparently unpacks zip files
|
||||
|
|
@ -53,7 +53,6 @@ func (u *watch) execute(assetID int64, size int) error {
|
|||
if !atomic.CompareAndSwapInt32(&mutex, 0, 1) {
|
||||
return errors.New("upgrade already running")
|
||||
}
|
||||
defer atomic.StoreInt32(&mutex, 0)
|
||||
|
||||
rootFS, err := u.repo.StreamAsset(assetID)
|
||||
if err != nil {
|
||||
|
|
@ -64,7 +63,24 @@ func (u *watch) execute(assetID int64, size int) error {
|
|||
rootFS.Close()
|
||||
return err
|
||||
}
|
||||
defer rootFS.Close()
|
||||
|
||||
uri := fmt.Sprintf("http://gokrazy:%s@%s:%d/", Password, Host, Port)
|
||||
target, err := updater.NewTarget(uri, http.DefaultClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// stream async to device
|
||||
go u.executeAsync(target, rootFS, size)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *watch) executeAsync(target *updater.Target, rootFS io.ReadCloser, size int) error {
|
||||
defer func() {
|
||||
atomic.StoreInt32(&mutex, 0)
|
||||
rootFS.Close()
|
||||
}()
|
||||
|
||||
cw := &countingWriter{C: make(chan int)}
|
||||
|
||||
|
|
@ -75,12 +91,6 @@ func (u *watch) execute(assetID int64, size int) error {
|
|||
u.Send("uploadProgress", 100)
|
||||
}()
|
||||
|
||||
uri := fmt.Sprintf("http://gokrazy:%s@localhost:%d/", Password, Port)
|
||||
target, err := updater.NewTarget(uri, http.DefaultClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.Send("uploadMessage", "uploading")
|
||||
if err := target.StreamTo("root", io.TeeReader(rootFS, cw)); err != nil {
|
||||
return fmt.Errorf("updating root file system: %w", err)
|
||||
|
|
|
|||
|
|
@ -28,19 +28,24 @@ func Run(log *util.Logger, httpd webServer, tee util.TeeAttacher, outChan chan<-
|
|||
c := make(chan *github.RepositoryRelease, 1)
|
||||
go u.watchReleases(server.Version, c) // endless
|
||||
|
||||
// signal update support
|
||||
u.Send("hasUpdater", true)
|
||||
|
||||
for rel := range c {
|
||||
u.Send("availableVersion", rel)
|
||||
latest = rel
|
||||
u.Send("availableVersion", *latest.TagName)
|
||||
}
|
||||
}
|
||||
|
||||
const rootFSAsset = "evcc_%s.rootfs.gz"
|
||||
|
||||
func (u *watch) updateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost || latest == nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
name := fmt.Sprintf(RootFS, *latest.TagName)
|
||||
name := fmt.Sprintf(rootFSAsset, *latest.TagName)
|
||||
assetID, size, err := u.repo.FindReleaseAsset(name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue