mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-24 11:51:13 +08:00
feat: add sub-command upgrade
This commit is contained in:
1
.github/workflows/upload_release.yml
vendored
1
.github/workflows/upload_release.yml
vendored
@@ -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
|
||||
|
||||
1
Makefile
1
Makefile
@@ -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
|
||||
|
||||
47
cmd/kubevpn/cmds/upgarde_test.go
Normal file
47
cmd/kubevpn/cmds/upgarde_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
38
cmd/kubevpn/cmds/upgrade.go
Normal file
38
cmd/kubevpn/cmds/upgrade.go
Normal 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
132
go.mod
@@ -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
8
go.sum
@@ -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
93
pkg/upgrade/modle.go
Normal 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"`
|
||||
}
|
||||
59
pkg/upgrade/progressreader.go
Normal file
59
pkg/upgrade/progressreader.go
Normal 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
137
pkg/upgrade/upgrade.go
Normal 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
|
||||
}
|
||||
34
pkg/upgrade/upgrade_test.go
Normal file
34
pkg/upgrade/upgrade_test.go
Normal 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))
|
||||
}
|
||||
Reference in New Issue
Block a user