Commit a1a851b1 authored by zauberstuhl's avatar zauberstuhl
Browse files

Add and use bintray fetcher in updater agent

The bintray fetcher will fetch the latest binary from
a certain package (update channel e.g. alpha) and
checks if bintray holds a newer version

In case upstream has a newer version it downloads and
replaces the local one within an hour (alpha channel five minutes)
parent 55fdbffa
Pipeline #138 passed with stages
in 22 minutes and 51 seconds
......@@ -7,7 +7,7 @@ log/
# build
*.tar.gz
conf/app.conf
bindata.go
updater/bindata.go
# assets
app/assets/vendor
......
......@@ -51,7 +51,7 @@ endif
clean:
rm -r tmp vendor node_modules \
test-results bindata.go \
test-results updater/bindata.go \
updater.*.bin *.tar.gz || true
precompile:
......@@ -105,8 +105,8 @@ endif
[ -f "ganggo.exe" ] && mv ganggo.exe ganggo ;\
go-bindata -ignore \
'src/$(package)/[vendor|node_modules|bindata.go|.*\.tar\.gz|tmp]' \
-o ../bindata.go ganggo src/... ;\
-o ../updater/bindata.go ganggo src/... ;\
}
cd $(srcdir) && go build \
cd $(srcdir)/updater && go build \
-ldflags "-X main.version=$(version)" \
-o updater.$$GOOS-$$GOARCH$$GOARM.bin updater.go bindata.go
-o ../updater.$$GOOS-$$GOARCH$$GOARM.bin updater.go bin*.go
package main
//
// GangGo Application Server
// Copyright (C) 2018 Lukas Matt <lukas@zauberstuhl.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
import (
"fmt"
"io"
"net/http"
"time"
"runtime"
"encoding/json"
)
const (
BINTRAY_API = "https://api.bintray.com/packages/%s/%s/%s/versions/_latest"
BINTRAY_DL = "https://dl.bintray.com/%s/%s/updater.%s-%s.%s.bin"
)
type Bintray struct {
User, Repo, Pkg string
Interval time.Duration
// internal
delay bool
last time.Time
}
type ApiResponse struct {
Name string
Created time.Time
}
// Init validates the provided config
func (h *Bintray) Init() error {
//apply defaults
if h.User == "" || h.Repo == "" || h.Pkg == "" {
return fmt.Errorf("User, Repo and Pkg required")
}
if h.Interval == 0 {
h.Interval = 5 * time.Minute
}
return nil
}
// Fetch the binary from the provided URL
func (h *Bintray) Fetch() (io.Reader, error) {
// delay fetches after first
if h.delay {
time.Sleep(h.Interval)
}
h.delay = true
// check version and return if no update is necessary
// https://api.bintray.com/packages/:user/:repo/:pkg/versions/_latest
resp, err := http.Get(fmt.Sprintf(BINTRAY_API, h.User, h.Repo, h.Pkg))
if err != nil {
return nil, fmt.Errorf("GET request failed (%s)", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("GET request failed (status code %d)", resp.StatusCode)
}
apiResp := ApiResponse{}
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(&apiResp)
if err != nil {
return nil, fmt.Errorf("DECODER failed (%s)", err)
}
if apiResp.Created.Before(h.last) {
return nil, nil
}
h.last = apiResp.Created
// binary fetch using GET
resp, err = http.Get(fmt.Sprintf(BINTRAY_DL, h.User, h.Repo,
runtime.GOOS, runtime.GOARCH, apiResp.Name))
if err != nil {
return nil, fmt.Errorf("GET request failed (%s)", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("GET request failed (status code %d)", resp.StatusCode)
}
return resp.Body, nil
}
package main
//
// GangGo Application Server
// Copyright (C) 2017 Lukas Matt <lukas@zauberstuhl.de>
// Copyright (C) 2018 Lukas Matt <lukas@zauberstuhl.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
......@@ -21,10 +21,8 @@ import (
"io/ioutil"
"time"
"fmt"
"strings"
"flag"
"github.com/jpillora/overseer"
"github.com/jpillora/overseer/fetcher"
"os"
"os/exec"
"github.com/revel/config"
......@@ -222,25 +220,16 @@ func main() {
overseer.Run(overseer.Config{
Program: prog,
Fetcher: &fetcher.Github{
Fetcher: &Bintray{
User: "ganggo",
Repo: "ganggo",
Asset: AssetValidator,
Pkg: updateChannel,
Interval: interval,
},
Debug: true,
})
}
// Add the ability to use multiple update channel via Github-fetcher
func AssetValidator(filename string) bool {
defaultAsset := strings.Contains(filename, runtime.GOOS) && strings.Contains(filename, runtime.GOARCH)
if defaultAsset && updateChannel == "stable" {
return true
}
return defaultAsset && strings.Contains(filename, updateChannel)
}
func prog(state overseer.State) {
buildID := int32(time.Now().Unix())
binFile := fmt.Sprintf("./ganggo.%s.%d", version, buildID)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment