diff --git a/cmd/kubevpn/cmds/connect.go b/cmd/kubevpn/cmds/connect.go index 3344291f..5669a86a 100644 --- a/cmd/kubevpn/cmds/connect.go +++ b/cmd/kubevpn/cmds/connect.go @@ -59,9 +59,11 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command { log.Errorln(err) handler.Cleanup(syscall.SIGQUIT) } else { + fmt.Println() fmt.Println(`---------------------------------------------------------------------------`) fmt.Println(` Now you can access resources in the kubernetes cluster, enjoy it :) `) fmt.Println(`---------------------------------------------------------------------------`) + fmt.Println() } select {} }, diff --git a/cmd/kubevpn/cmds/options.go b/cmd/kubevpn/cmds/options.go index 4b8ea4fa..76ce936e 100644 --- a/cmd/kubevpn/cmds/options.go +++ b/cmd/kubevpn/cmds/options.go @@ -12,7 +12,7 @@ import ( var ( optionsExample = templates.Examples(i18n.T(` # Print flags inherited by all commands - kubectl options`)) + kubevpn options`)) ) func CmdOptions(cmdutil.Factory) *cobra.Command { diff --git a/cmd/kubevpn/cmds/upgrade.go b/cmd/kubevpn/cmds/upgrade.go index d0c0a65d..e0cab1fe 100644 --- a/cmd/kubevpn/cmds/upgrade.go +++ b/cmd/kubevpn/cmds/upgrade.go @@ -31,7 +31,7 @@ func CmdUpgrade(_ cmdutil.Factory) *cobra.Command { if err != nil { log.Fatal(err) } - log.Infoln("Done") + println("Done") }, } return cmd diff --git a/go.mod b/go.mod index 76882c89..22547942 100644 --- a/go.mod +++ b/go.mod @@ -36,9 +36,11 @@ require ( github.com/containernetworking/cni v1.1.2 github.com/hashicorp/go-version v1.6.0 github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 + github.com/schollz/progressbar/v3 v3.13.0 github.com/stretchr/testify v1.8.1 golang.org/x/exp v0.0.0-20230113213754-f9f960f08ad4 golang.org/x/oauth2 v0.4.0 + golang.org/x/term v0.4.0 k8s.io/utils v0.0.0-20230115233650-391b47cb4029 sigs.k8s.io/yaml v1.3.0 ) @@ -75,6 +77,8 @@ require ( 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.7 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -84,13 +88,13 @@ require ( 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/rivo/uniseg v0.4.3 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.starlark.net v0.0.0-20230112144946-fae38c8a6d89 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.5.0 // indirect diff --git a/go.sum b/go.sum index cacda974..a576d128 100644 --- a/go.sum +++ b/go.sum @@ -214,6 +214,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -232,10 +233,15 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 h1:uYuGXJBAi1umT+ZS4oQJUgKtfXCAYTR+n9zw1ViT0vA= github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/milosgajdos/tenus v0.0.3 h1:jmaJzwaY1DUyYVD0lM4U+uvP2kkEg1VahDqRFxIkVBE= github.com/milosgajdos/tenus v0.0.3/go.mod h1:eIjx29vNeDOYWJuCnaHY2r4fq5egetV26ry3on7p8qY= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= @@ -275,10 +281,15 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.13.0 h1:9TeeWRcjW2qd05I8Kf9knPkW4vLM/hYoa6z9ABvxje8= +github.com/schollz/progressbar/v3 v3.13.0/go.mod h1:ZBYnSuLAX2LU8P8UiKN/KgF2DY58AJC8yfVYLPC8Ly4= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28= github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM= @@ -468,6 +479,7 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/upgrade/upgrade.go b/pkg/upgrade/upgrade.go index c8303be7..17eca289 100644 --- a/pkg/upgrade/upgrade.go +++ b/pkg/upgrade/upgrade.go @@ -6,10 +6,12 @@ import ( "io" "net/http" "os" + "path/filepath" "runtime" goversion "github.com/hashicorp/go-version" - "k8s.io/utils/pointer" + "github.com/schollz/progressbar/v3" + "github.com/wencaiwulue/kubevpn/pkg/util" ) // Main @@ -17,24 +19,48 @@ import ( // 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 +// 5) check permission of putting new kubevpn back +// 6) 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) + fmt.Printf("The latest version is: %s\n", version) + var cVersion, dVersion *goversion.Version + cVersion, err = goversion.NewVersion(current) if err != nil { return err } - dVersion, err := goversion.NewVersion(version) + 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") + fmt.Println("Already up to date, don't needs to upgrade") return nil } + + var executable string + executable, err = os.Executable() + if err != nil { + return err + } + var tem *os.File + tem, err = os.Create(filepath.Join(filepath.Dir(executable), ".test")) + if tem != nil { + _ = tem.Close() + _ = os.Remove(tem.Name()) + } + if os.IsPermission(err) { + util.RunWithElevated() + os.Exit(0) + } else if err != nil { + return err + } + + fmt.Printf("Current version is: %s less than latest version: %s, needs to upgrade\n", cVersion, dVersion) + var temp *os.File temp, err = os.CreateTemp("", "") if err != nil { @@ -82,18 +108,19 @@ 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) + err = fmt.Errorf("failed to call github api, err: %v", err) return } - all, err := io.ReadAll(resp.Body) + var all []byte + all, err = io.ReadAll(resp.Body) if err != nil { - err = fmt.Errorf("failed to resp latest version of KubeVPN, err: %v", err) + err = fmt.Errorf("failed to read all reponse from github api, 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) + err = fmt.Errorf("failed to unmarshal reponse, err: %v", err) return } version = m.TagName @@ -108,7 +135,7 @@ func getManifest(httpCli *http.Client) (version string, url string, err error) { } } if len(url) == 0 { - err = fmt.Errorf("failed to resp latest version url of KubeVPN, resp: %s", string(all)) + err = fmt.Errorf("can not found latest version url of KubeVPN, resp: %s", string(all)) return } return @@ -121,39 +148,34 @@ func download(client *http.Client, url string, filename string) error { 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 - } - } - } - } - }() + defer get.Body.Close() + total := float64(get.ContentLength) / 1024 / 1024 + fmt.Printf("Length: 68276642 (%0.2fM)\n", total) + var f *os.File f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) if err != nil { return err } defer f.Close() + bar := progressbar.NewOptions(int(get.ContentLength), + progressbar.OptionSetWriter(os.Stdout), + progressbar.OptionEnableColorCodes(true), + progressbar.OptionShowBytes(true), + progressbar.OptionSetWidth(50), + progressbar.OptionOnCompletion(func() { + _, _ = fmt.Fprint(os.Stderr, "\n") + }), + progressbar.OptionSetRenderBlankState(true), + progressbar.OptionSetDescription("Writing temp file..."), + progressbar.OptionSetTheme(progressbar.Theme{ + Saucer: "=", + SaucerHead: ">", + SaucerPadding: " ", + BarStart: "[", + BarEnd: "]", + })) buf := make([]byte, 10<<(10*2)) // 10M - _, err = io.CopyBuffer(f, p, buf) + _, err = io.CopyBuffer(io.MultiWriter(f, bar), get.Body, buf) return err }