feat: add sub-command upgrade

This commit is contained in:
wencaiwulue
2023-01-11 21:37:42 +08:00
parent ecf9fe7353
commit 1786a7965e
10 changed files with 484 additions and 66 deletions

View File

@@ -33,6 +33,7 @@ jobs:
- name: Build kubevpn-all-arch
run: |
git tag `echo ${{ github.event.client_payload.tag }} | sed 's/refs\/tags\///' | sed 's/\(.*\)-.*/\1/' | sed 's/-[0-9]*$//' || true` || true
export GitHubOAuthToken=${{ secrets.KUBEVPN_UPGRADE_OAUTH }}
make all-kubevpn
- name: Upload Release Asset

View File

@@ -26,6 +26,7 @@ LDFLAGS=--ldflags "\
-X ${FOLDER}/cmds.GitCommit=${GIT_COMMIT} \
-X ${FOLDER}/cmds.Branch=${BRANCH} \
-X ${FOLDER}/cmds.OsArch=${OS_ARCH} \
-X ${FOLDER}/cmds.GitHubOAuthToken=${GitHubOAuthToken} \
"
GO111MODULE=on

View File

@@ -0,0 +1,47 @@
package cmds
import (
"fmt"
"io"
"os"
"testing"
"time"
)
func TestName111(t *testing.T) {
var processBar = []string{
"00%: [ ]",
"05%: [## ]",
"10%: [#### ]",
"15%: [###### ]",
"20%: [######## ]",
"25%: [########## ]",
"30%: [############ ]",
"35%: [############## ]",
"40%: [################ ]",
"45%: [################## ]",
"50%: [#################### ]",
"55%: [###################### ]",
"60%: [######################## ]",
"65%: [########################## ]",
"70%: [############################ ]",
"75%: [############################## ]",
"80%: [################################ ]",
"85%: [################################## ]",
"90%: [#################################### ]",
"95%: [###################################### ]",
"100%:[##########################################]\n",
}
for idx, val := range processBar {
fmt.Printf("[%d:1H:2K] \r \a%s", idx, val)
time.Sleep(1 * time.Millisecond * 200)
}
}
func TestAAAAA(t *testing.T) {
writer := io.MultiWriter(os.Stdout, os.Stderr)
for i := 0; i < 10; i++ {
fmt.Fprintf(writer, "\r[%d:1H:2K]", i)
time.Sleep(1 * time.Millisecond * 200)
}
}

View File

@@ -0,0 +1,38 @@
package cmds
import (
"net/http"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/oauth2"
"github.com/wencaiwulue/kubevpn/pkg/upgrade"
)
// GitHubOAuthToken
// --ldflags -X
var (
GitHubOAuthToken = ""
)
var upgradeCmd = &cobra.Command{
Use: "upgrade",
Short: "Upgrade KubeVPN version",
Long: `Upgrade KubeVPN version, automatically download latest KubeVPN from GitHub`,
Run: func(cmd *cobra.Command, args []string) {
println(GitHubOAuthToken)
var client = http.DefaultClient
if GitHubOAuthToken != "" {
client = oauth2.NewClient(cmd.Context(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: GitHubOAuthToken, TokenType: "Bearer"}))
}
err := upgrade.Main(Version, client)
if err != nil {
log.Fatal(err)
}
},
}
func init() {
RootCmd.AddCommand(upgradeCmd)
}

132
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/docker/libcontainer v2.2.1+incompatible
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1
github.com/fsnotify/fsnotify v1.5.4
github.com/go-openapi/jsonpointer v0.19.5
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/miekg/dns v1.0.14
github.com/milosgajdos/tenus v0.0.3
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
@@ -17,13 +17,13 @@ require (
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/spf13/cobra v1.4.0
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
golang.org/x/sys v0.1.0
golang.zx2c4.com/wireguard v0.0.0-20211209221555-9c9e7e272434
golang.zx2c4.com/wireguard/windows v0.4.10
google.golang.org/appengine v1.6.7
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.47.0
google.golang.org/protobuf v1.28.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/api v0.25.0
k8s.io/apimachinery v0.25.0
k8s.io/cli-runtime v0.24.2
@@ -33,72 +33,76 @@ require (
)
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd
github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
github.com/census-instrumentation/opencensus-proto v0.2.1
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1
github.com/containernetworking/cni v1.1.2
github.com/davecgh/go-spew v1.1.1
github.com/emicklei/go-restful/v3 v3.8.0
github.com/envoyproxy/protoc-gen-validate v0.1.0
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
github.com/fatih/camelcase v1.0.0
github.com/fvbommel/sortorder v1.0.1
github.com/go-errors/errors v1.0.1
github.com/go-logr/logr v1.2.3
github.com/go-openapi/jsonreference v0.19.5
github.com/go-openapi/swag v0.19.14
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.2
github.com/google/btree v1.0.1
github.com/google/gnostic v0.5.7-v3refs
github.com/google/go-cmp v0.5.8
github.com/google/gofuzz v1.1.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.2.0
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
github.com/imdario/mergo v0.3.12
github.com/inconshreveable/mousetrap v1.0.0
github.com/josharian/intern v1.0.0
github.com/json-iterator/go v1.1.12
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
github.com/mailru/easyjson v0.7.6
github.com/hashicorp/go-version v1.6.0
github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24
github.com/mitchellh/go-wordwrap v1.0.0
github.com/moby/spdystream v0.2.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/reflect2 v1.0.2
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/peterbourgon/diskv v2.0.1+incompatible
github.com/pmezard/go-difflib v1.0.0
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3
github.com/russross/blackfriday v1.5.2
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.7
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v3 v3.0.1
k8s.io/component-base v0.25.0
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
sigs.k8s.io/kustomize/api v0.11.4
sigs.k8s.io/kustomize/kyaml v0.13.6
sigs.k8s.io/structured-merge-diff/v4 v4.2.3
sigs.k8s.io/yaml v1.3.0
)
require github.com/onsi/ginkgo v1.16.5 // indirect
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.25.0 // indirect
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/kustomize/api v0.11.4 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)

8
go.sum
View File

@@ -281,6 +281,8 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -536,6 +538,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a h1:tlXy25amD5A7gOfbXdqCGN5k8ESEed/Ee1E5RcrYnqU=
golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -704,8 +708,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=

93
pkg/upgrade/modle.go Normal file
View File

@@ -0,0 +1,93 @@
package upgrade
type RootEntity struct {
Url string `json:"url"`
AssetsUrl string `json:"assets_url"`
UploadUrl string `json:"upload_url"`
HtmlUrl string `json:"html_url"`
Id int64 `json:"id"`
NodeId string `json:"node_id"`
TagName string `json:"tag_name"`
TargetCommitish string `json:"target_commitish"`
Name string `json:"name"`
Draft bool `json:"draft"`
Prerelease bool `json:"prerelease"`
CreatedAt string `json:"created_at"`
PublishedAt string `json:"published_at"`
Assets []AssetsEntity `json:"assets"`
TarballUrl string `json:"tarball_url"`
ZipballUrl string `json:"zipball_url"`
Body string `json:"body"`
Reactions ReactionsEntity `json:"reactions"`
}
type AuthorEntity struct {
Login string `json:"login"`
Id int64 `json:"id"`
NodeId string `json:"node_id"`
AvatarUrl string `json:"avatar_url"`
GravatarId string `json:"gravatar_id"`
Url string `json:"url"`
HtmlUrl string `json:"html_url"`
FollowersUrl string `json:"followers_url"`
FollowingUrl string `json:"following_url"`
GistsUrl string `json:"gists_url"`
StarredUrl string `json:"starred_url"`
SubscriptionsUrl string `json:"subscriptions_url"`
OrganizationsUrl string `json:"organizations_url"`
ReposUrl string `json:"repos_url"`
EventsUrl string `json:"events_url"`
ReceivedEventsUrl string `json:"received_events_url"`
Type string `json:"type"`
SiteAdmin bool `json:"site_admin"`
}
type AssetsEntity struct {
Url string `json:"url"`
Id int64 `json:"id"`
NodeId string `json:"node_id"`
Name string `json:"name"`
Label string `json:"label"`
Uploader UploaderEntity `json:"uploader"`
ContentType string `json:"content_type"`
State string `json:"state"`
Size int64 `json:"size"`
DownloadCount int64 `json:"download_count"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
BrowserDownloadUrl string `json:"browser_download_url"`
}
type UploaderEntity struct {
Login string `json:"login"`
Id int64 `json:"id"`
NodeId string `json:"node_id"`
AvatarUrl string `json:"avatar_url"`
GravatarId string `json:"gravatar_id"`
Url string `json:"url"`
HtmlUrl string `json:"html_url"`
FollowersUrl string `json:"followers_url"`
FollowingUrl string `json:"following_url"`
GistsUrl string `json:"gists_url"`
StarredUrl string `json:"starred_url"`
SubscriptionsUrl string `json:"subscriptions_url"`
OrganizationsUrl string `json:"organizations_url"`
ReposUrl string `json:"repos_url"`
EventsUrl string `json:"events_url"`
ReceivedEventsUrl string `json:"received_events_url"`
Type string `json:"type"`
SiteAdmin bool `json:"site_admin"`
}
type ReactionsEntity struct {
Url string `json:"url"`
TotalCount int64 `json:"total_count"`
Normal1 int64 `json:"+1"`
Normal11 int64 `json:"-1"`
Laugh int64 `json:"laugh"`
Hooray int64 `json:"hooray"`
Confused int64 `json:"confused"`
Heart int64 `json:"heart"`
Rocket int64 `json:"rocket"`
Eyes int64 `json:"eyes"`
}

View File

@@ -0,0 +1,59 @@
package upgrade
import (
"io"
"sync"
"sync/atomic"
)
type progress struct {
sync.Mutex
updates chan<- Update
lastUpdate *Update
}
type Update struct {
Total int64
Complete int64
Error error
}
func (p *progress) total(delta int64) {
atomic.AddInt64(&p.lastUpdate.Total, delta)
}
func (p *progress) complete(delta int64) {
p.Lock()
defer p.Unlock()
p.updates <- Update{
Total: p.lastUpdate.Total,
Complete: atomic.AddInt64(&p.lastUpdate.Complete, delta),
}
}
func (p *progress) err(err error) error {
if err != nil && p.updates != nil {
p.updates <- Update{Error: err}
}
return err
}
type progressReader struct {
rc io.ReadCloser
count *int64 // number of bytes this reader has read, to support resetting on retry.
progress *progress
}
func (r *progressReader) Read(b []byte) (int, error) {
n, err := r.rc.Read(b)
if err != nil {
return n, err
}
atomic.AddInt64(r.count, int64(n))
// TODO: warn/debug log if sending takes too long, or if sending is blocked while context is canceled.
r.progress.complete(int64(n))
return n, nil
}
func (r *progressReader) Close() error { return r.rc.Close() }

137
pkg/upgrade/upgrade.go Normal file
View File

@@ -0,0 +1,137 @@
package upgrade
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"runtime"
goversion "github.com/hashicorp/go-version"
"k8s.io/utils/pointer"
)
// Main
// 1) get current binary version
// 2) get the latest version
// 3) compare two version decide needs to download or not
// 4) download newer version
// 5) chmod +x, move old to /temp, move new to CURRENT_FOLDER
func Main(current string, client *http.Client) error {
version, url, err := getManifest(client)
if err != nil {
return err
}
cVersion, err := goversion.NewVersion(current)
if err != nil {
return err
}
dVersion, err := goversion.NewVersion(version)
if err != nil {
return err
}
if cVersion.GreaterThanOrEqual(dVersion) {
fmt.Println("current version is bigger than latest version, don't needs to download")
return nil
}
var temp *os.File
temp, err = os.CreateTemp("", "")
if err != nil {
return err
}
err = download(client, url, temp.Name())
if err != nil {
return err
}
err = os.Chmod(temp.Name(), 0755)
if err != nil {
return err
}
var curFolder string
curFolder, err = os.Executable()
if err != nil {
return err
}
createTemp, err := os.CreateTemp("", "")
err = os.Remove(createTemp.Name())
err = os.Rename(curFolder, createTemp.Name())
err = os.Rename(temp.Name(), curFolder)
return err
}
func getManifest(httpCli *http.Client) (version string, url string, err error) {
var resp *http.Response
resp, err = httpCli.Get("https://api.github.com/repos/wencaiwulue/kubevpn/releases/latest")
if err != nil {
err = fmt.Errorf("failed to resp latest version of KubeVPN, err: %v", err)
return
}
all, err := io.ReadAll(resp.Body)
if err != nil {
err = fmt.Errorf("failed to resp latest version of KubeVPN, err: %v", err)
return
}
var m RootEntity
err = json.Unmarshal(all, &m)
if err != nil {
err = fmt.Errorf("failed to resp latest version of KubeVPN, err: %v", err)
return
}
version = m.TagName
for _, asset := range m.Assets {
name := fmt.Sprintf("%s-%s-%s", "kubevpn", runtime.GOOS, runtime.GOARCH)
if name == asset.Name {
url = asset.BrowserDownloadUrl
break
}
}
if len(url) == 0 {
err = fmt.Errorf("failed to resp latest version url of KubeVPN")
return
}
return
}
// https://api.github.com/repos/wencaiwulue/kubevpn/releases
// https://github.com/wencaiwulue/kubevpn/releases/download/v1.1.13/kubevpn-windows-arm64.exe
func download(client *http.Client, url string, filename string) error {
get, err := client.Get(url)
if err != nil {
return err
}
pr := make(chan Update, 1)
p := &progressReader{
rc: get.Body,
count: pointer.Int64(0),
progress: &progress{
updates: pr,
lastUpdate: &Update{},
},
}
p.progress.total(get.ContentLength)
go func() {
var last string
for {
select {
case u, ok := <-pr:
if ok {
per := float32(u.Complete) / float32(u.Total) * 100
s := fmt.Sprintf("%.0f%%", per)
if last != s {
fmt.Printf(fmt.Sprintf("\r%s%%", s))
last = s
}
}
}
}
}()
var f *os.File
f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
buf := make([]byte, 10<<(10*2)) // 10M
_, err = io.CopyBuffer(f, p, buf)
return err
}

View File

@@ -0,0 +1,34 @@
package upgrade
import (
"fmt"
"testing"
goversion "github.com/hashicorp/go-version"
"github.com/stretchr/testify/assert"
"golang.org/x/oauth2"
)
func TestCompare(t *testing.T) {
version, err := goversion.NewVersion("v1.1.12")
assert.Nil(t, err)
newVersion, err := goversion.NewVersion("v1.1.13")
assert.Nil(t, err)
assert.True(t, version.LessThan(newVersion))
}
func TestGetManifest(t *testing.T) {
client := oauth2.NewClient(nil, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: "", TokenType: "Bearer"}))
manifest, url, err := getManifest(client)
assert.Nil(t, err)
assert.True(t, manifest != "")
assert.True(t, url != "")
}
func TestPercentage(t *testing.T) {
per := float32(1) / float32(100) * 100
s := fmt.Sprintf("%.0f%%", per)
fmt.Printf(fmt.Sprintf("\r%s%%", s))
}