As a Go project, Capstan uses godep as its dependency manager,
however, as of Go 1.11, Go's new dependency management system(Go
Modules) is introduced officially, more and more Go projects use Go
Modules to make dependency version information explicit and easier to
manage, this patch makes Capstan migrate to Go Modules and update
codes to use the latest APIs, here are details:

- Delete Godeps directory, add go.mod and go.sum file, which are
  generated by `go mod` command and declare Capstan project is managed
  with Go Modules now
- Update packages import path, change urfave/cli from v1 to v2, change
  cheggaaa/pb from v0 to v3, all packages are newest released version
- Update code to adapt new APIs according to the old/new API doc
- Update the installation.md, use Go 1.11+ to build/manage Capstan on
  Module Mode

See [Go Modules Blogs](https://blog.golang.org/using-go-modules) to
learn more

Signed-off-by: kayhaw <xiaokedou123...@gmail.com>
---
 Documentation/Installation.md        |  22 ++-
 Godeps/Godeps.json                   |  38 -----
 Godeps/Readme                        |   5 -
 capstan.go                           | 242 +++++++++++++--------------
 cmd/build.go                         |   2 +-
 cmd/compose.go                       |   8 +-
 cmd/config.go                        |   4 +-
 cmd/stack.go                         |   6 +-
 provider/openstack/openstack_auth.go |  16 +-
 util/remote_repository.go            |   4 +-
 util/repository.go                   |  16 +-
 11 files changed, 166 insertions(+), 197 deletions(-)
 delete mode 100644 Godeps/Godeps.json
 delete mode 100644 Godeps/Readme

diff --git a/Documentation/Installation.md b/Documentation/Installation.md
index 41c438b..9807033 100644
--- a/Documentation/Installation.md
+++ b/Documentation/Installation.md
@@ -46,14 +46,14 @@ There you go, happy unikernel creating!
 
 ## Install Capstan from source (advanced)
 
-### Install Go 1.7+
+### Install Go 1.11+
 Capstan is a Go project and needs to be compiled first. But heads up, 
compiling Go project is trivial,
 as long as you have Go installed. Consult [official 
documentation](https://golang.org/doc/install)
 to learn how to install Go, or use this bash snippet to do it for you:
 ```bash
-curl https://storage.googleapis.com/golang/go1.12.6.linux-amd64.tar.gz | sudo 
tar xz -C /usr/local
-sudo mv /usr/local/go /usr/local/go1.12
-sudo ln -s /usr/local/go1.12 /usr/local/go
+curl https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz | sudo tar xz -C 
/usr/local
+sudo mv /usr/local/go /usr/local/go1.13
+sudo ln -s /usr/local/go1.13 /usr/local/go
 
 export GOPATH=$HOME/go
 export PATH=$GOPATH/bin:$PATH
@@ -63,8 +63,10 @@ export PATH=/usr/local/go/bin:$PATH
 ### Compile Capstan
 Since Capstan is hosted on GitHub, the compilation process is as simple as:
 ```
-go get github.com/cloudius-systems/capstan
-go install github.com/cloudius-systems/capstan
+git clone g...@github.com:cloudius-systems/capstan.git
+cd capstan
+go env -w GO111MODULE=on        # Needed for Go 1.11, 1.12
+go install
 ```
 That's it, we have Capstan installed. You should be able to use Capstan 
immediately because it was
 installed in `$GOPATH/bin` added to your `$PATH` above. To test that it works, 
try:
@@ -72,6 +74,14 @@ installed in `$GOPATH/bin` added to your `$PATH` above. To 
test that it works, t
 capstan --help
 ```
 
+## Maintain Capstan
+Capstan is managed with Go Moudles as 
[recommended](https://blog.golang.org/using-go-modules), while developing on 
Capstan, you should follow these steps:
+1. Update import path and corresponding code as you might do
+2. Test you changes with `go test ./...`
+3. Clear up `go.mod` and `go.sum` file with `go mod tidy`
+
+Now you are ready to tag and release new version. To learn more details about 
maintaining your Go project on Module Mode, see [Go Modules Serial 
Blogs](https://blog.golang.org/using-go-modules)
+
 ## Configure Capstan (advanced)
 Capstan uses optimized default values under the hood. But you are allowed to 
override them with
 your own values and this section describes how. Actually, there are three ways 
to override them
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
deleted file mode 100644
index e39f221..0000000
--- a/Godeps/Godeps.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-       "ImportPath": "github.com/cloudius-systems/capstan",
-       "GoVersion": "go1.7",
-       "Packages": [
-               "./..."
-       ],
-       "Deps": [
-               {
-                       "ImportPath": "github.com/cheggaaa/pb",
-                       "Rev": "a9a708f18ae43493d86f3fd5b0cd04df679b170b"
-               },
-               {
-                       "ImportPath": "github.com/olekukonko/ts",
-                       "Rev": "ecf753e7c962639ab5a1fb46f7da627d4c0a04b8"
-               },
-               {
-                       "ImportPath": "github.com/mitchellh/mapstructure",
-                       "Rev": "d2dd0262208475919e1a362f675cfc0e7c10e905"
-               },
-               {
-                       "ImportPath": "github.com/urfave/cli",
-                       "Comment": "v1.17.0-67-ge5bef42",
-                       "Rev": "e5bef42c62aa7d25aba4880dc02b7624f01e9e19"
-               },
-               {
-                       "ImportPath": "gopkg.in/check.v1",
-                       "Rev": "4f90aeace3a26ad7021961c297b22c42160c7b25"
-               },
-               {
-                       "ImportPath": "gopkg.in/natefinch/npipe.v2",
-                       "Rev": "0938d701e50e580f5925c773055eb6d6b32a0cbc"
-               },
-               {
-                       "ImportPath": "gopkg.in/yaml.v2",
-                       "Rev": "f7716cbe52baa25d2e9b0d0da546fcf909fc16b4"
-               }
-       ]
-}
diff --git a/Godeps/Readme b/Godeps/Readme
deleted file mode 100644
index 4cdaa53..0000000
--- a/Godeps/Readme
+++ /dev/null
@@ -1,5 +0,0 @@
-This directory tree is generated automatically by godep.
-
-Please do not edit.
-
-See https://github.com/tools/godep for more information.
diff --git a/capstan.go b/capstan.go
index 09fa20c..fea25ce 100644
--- a/capstan.go
+++ b/capstan.go
@@ -19,7 +19,7 @@ import (
        "github.com/cloudius-systems/capstan/provider/openstack"
        "github.com/cloudius-systems/capstan/runtime"
        "github.com/cloudius-systems/capstan/util"
-       "github.com/urfave/cli"
+       "github.com/urfave/cli/v2"
 )
 
 var (
@@ -44,15 +44,15 @@ func main() {
        app.Version = VERSION
        app.Usage = "pack, ship, and run applications in light-weight VMs"
        app.Flags = []cli.Flag{
-               cli.StringFlag{Name: "u", Usage: fmt.Sprintf("remote repository 
URL (default: \"%s\")", util.DefaultRepositoryUrl)},
-               cli.StringFlag{Name: "release-tag,r", Usage: "the release tag: 
any, latest, v0.51.0"},
-               cli.BoolFlag{Name: "s3", Usage: fmt.Sprintf("searches and 
downloads from S3 repository at (\"%s\")", util.DefaultRepositoryUrl)},
+               &cli.StringFlag{Name: "u", Usage: fmt.Sprintf("remote 
repository URL (default: \"%s\")", util.DefaultRepositoryUrl)},
+               &cli.StringFlag{Name: "release-tag,r", Usage: "the release tag: 
any, latest, v0.51.0"},
+               &cli.BoolFlag{Name: "s3", Usage: fmt.Sprintf("searches and 
downloads from S3 repository at (\"%s\")", util.DefaultRepositoryUrl)},
        }
-       app.Commands = []cli.Command{
+       app.Commands = []*cli.Command{
                {
                        Name:  "config",
                        Usage: "Capstan configuration",
-                       Subcommands: []cli.Command{
+                       Subcommands: []*cli.Command{
                                {
                                        Name:  "print",
                                        Usage: "print current capstan 
configuration",
@@ -67,10 +67,10 @@ func main() {
                        Name:  "info",
                        Usage: "show disk image information",
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        return cli.NewExitError("usage: capstan 
info [image-file]", EX_USAGE)
                                }
-                               image := c.Args()[0]
+                               image := c.Args().Get(0)
                                if err := cmd.Info(image); err != nil {
                                        return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
@@ -81,17 +81,17 @@ func main() {
                        Name:  "import",
                        Usage: "import an image to the local repository",
                        Flags: []cli.Flag{
-                               cli.StringFlag{Name: "v", Value: "", Usage: 
"image version"},
-                               cli.StringFlag{Name: "c", Value: "", Usage: 
"image creation date"},
-                               cli.StringFlag{Name: "d", Value: "", Usage: 
"image description"},
-                               cli.StringFlag{Name: "b", Value: "", Usage: 
"image build command"},
+                               &cli.StringFlag{Name: "v", Value: "", Usage: 
"image version"},
+                               &cli.StringFlag{Name: "c", Value: "", Usage: 
"image creation date"},
+                               &cli.StringFlag{Name: "d", Value: "", Usage: 
"image description"},
+                               &cli.StringFlag{Name: "b", Value: "", Usage: 
"image build command"},
                        },
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 2 {
+                               if c.Args().Len() != 2 {
                                        return cli.NewExitError("usage: capstan 
import [image-name] [image-file]", EX_USAGE)
                                }
                                repo := util.NewRepoFromCli(c)
-                               err := repo.ImportImage(c.Args()[0], 
c.Args()[1], c.String("v"), c.String("c"), c.String("d"), c.String("b"))
+                               err := repo.ImportImage(c.Args().Get(0), 
c.Args().Get(1), c.String("v"), c.String("c"), c.String("d"), c.String("b"))
                                if err != nil {
                                        return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
@@ -102,10 +102,10 @@ func main() {
                        Name:  "pull",
                        Usage: "pull an image from a remote repository",
                        Flags: []cli.Flag{
-                               cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce"},
+                               &cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce"},
                        },
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        return cli.NewExitError("usage: capstan 
pull [image-name]", EX_USAGE)
                                }
                                hypervisor := c.String("p")
@@ -124,7 +124,7 @@ func main() {
                        Name:  "rmi",
                        Usage: "delete an image from a repository",
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        return cli.NewExitError("usage: capstan 
rmi [image-name]", EX_USAGE)
                                }
                                repo := util.NewRepoFromCli(c)
@@ -140,28 +140,28 @@ func main() {
                        Usage:     "launch a VM. You may pass the image name as 
the first argument.",
                        ArgsUsage: "instance-name",
                        Flags: []cli.Flag{
-                               cli.StringFlag{Name: "i", Value: "", Usage: 
"image_name"},
-                               cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce|hkit"},
-                               cli.StringFlag{Name: "m", Value: "1G", Usage: 
"memory size"},
-                               cli.IntFlag{Name: "c", Value: 2, Usage: "number 
of CPUs"},
-                               cli.StringFlag{Name: "n", Value: "nat", Usage: 
"networking: nat|bridge|tap|vhost|vnet|vpnkit"},
-                               cli.BoolFlag{Name: "v", Usage: "verbose mode"},
-                               cli.StringFlag{Name: "b", Value: "", Usage: 
"networking device (bridge or tap): e.g., virbr0, vboxnet0, tap0"},
-                               cli.StringSliceFlag{Name: "f", Value: 
new(cli.StringSlice), Usage: "port forwarding rules"},
-                               cli.StringFlag{Name: "gce-upload-dir", Value: 
"", Usage: "Directory to upload local image to: e.g., gs://osvimg"},
-                               cli.StringFlag{Name: "mac", Value: "", Usage: 
"MAC address. If not specified, the MAC address will be generated 
automatically."},
-                               cli.StringFlag{Name: "execute,e", Usage: "set 
the command line to execute"},
-                               cli.StringSliceFlag{Name: "boot", Usage: 
"specify config_set name to boot unikernel with (repeatable, will be run left 
to right)"},
-                               cli.BoolFlag{Name: "persist", Usage: "persist 
instance parameters (only relevant for qemu instances)"},
-                               cli.StringSliceFlag{Name: "env", Value: 
new(cli.StringSlice), Usage: "specify value of environment variable e.g. 
PORT=8000 (repeatable)"},
-                               cli.StringSliceFlag{Name: "volume", Value: 
new(cli.StringSlice), Usage: `{path}[:{key=val}], e.g. ./volume.img:format=raw 
(repeatable)
+                               &cli.StringFlag{Name: "i", Value: "", Usage: 
"image_name"},
+                               &cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce|hkit"},
+                               &cli.StringFlag{Name: "m", Value: "1G", Usage: 
"memory size"},
+                               &cli.IntFlag{Name: "c", Value: 2, Usage: 
"number of CPUs"},
+                               &cli.StringFlag{Name: "n", Value: "nat", Usage: 
"networking: nat|bridge|tap|vhost|vnet|vpnkit"},
+                               &cli.BoolFlag{Name: "v", Usage: "verbose mode"},
+                               &cli.StringFlag{Name: "b", Value: "", Usage: 
"networking device (bridge or tap): e.g., virbr0, vboxnet0, tap0"},
+                               &cli.StringSliceFlag{Name: "f", Value: 
new(cli.StringSlice), Usage: "port forwarding rules"},
+                               &cli.StringFlag{Name: "gce-upload-dir", Value: 
"", Usage: "Directory to upload local image to: e.g., gs://osvimg"},
+                               &cli.StringFlag{Name: "mac", Value: "", Usage: 
"MAC address. If not specified, the MAC address will be generated 
automatically."},
+                               &cli.StringFlag{Name: "execute,e", Usage: "set 
the command line to execute"},
+                               &cli.StringSliceFlag{Name: "boot", Usage: 
"specify config_set name to boot unikernel with (repeatable, will be run left 
to right)"},
+                               &cli.BoolFlag{Name: "persist", Usage: "persist 
instance parameters (only relevant for qemu instances)"},
+                               &cli.StringSliceFlag{Name: "env", Value: 
new(cli.StringSlice), Usage: "specify value of environment variable e.g. 
PORT=8000 (repeatable)"},
+                               &cli.StringSliceFlag{Name: "volume", Value: 
new(cli.StringSlice), Usage: `{path}[:{key=val}], e.g. ./volume.img:format=raw 
(repeatable)
                                Default options are 
:format=raw:aio=native:cache=none`},
                        },
                        Action: func(c *cli.Context) error {
                                // Check for orphaned instances (those with 
osv.monitor and disk.qcow2, but
                                // without osv.config) and remove them.
                                if err := 
util.RemoveOrphanedInstances(c.Bool("v")); err != nil {
-                                       return cli.NewExitError(err, EX_DATAERR)
+                                       return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
 
                                bootOpts := cmd.BootOptions{
@@ -171,7 +171,7 @@ func main() {
                                }
                                bootCmd, err := bootOpts.GetCmd()
                                if err != nil {
-                                       return cli.NewExitError(err, EX_DATAERR)
+                                       return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
 
                                config := &runtime.RunConfig{
@@ -205,14 +205,14 @@ func main() {
                        Name:  "build",
                        Usage: "build an image",
                        Flags: []cli.Flag{
-                               cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce"},
-                               cli.StringFlag{Name: "m", Value: "512M", Usage: 
"memory size"},
-                               cli.BoolFlag{Name: "v", Usage: "verbose mode"},
+                               &cli.StringFlag{Name: "p", Value: 
hypervisor.Default(), Usage: "hypervisor: qemu|vbox|vmw|gce"},
+                               &cli.StringFlag{Name: "m", Value: "512M", 
Usage: "memory size"},
+                               &cli.BoolFlag{Name: "v", Usage: "verbose mode"},
                        },
                        Action: func(c *cli.Context) error {
                                imageName := c.Args().First()
                                repo := util.NewRepoFromCli(c)
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        imageName = repo.DefaultImage()
                                }
                                if imageName == "" {
@@ -240,20 +240,20 @@ func main() {
                        Name:  "compose",
                        Usage: "compose the image from a folder or a file",
                        Flags: []cli.Flag{
-                               cli.StringFlag{Name: "loader_image, l", Value: 
"osv-loader", Usage: "the base loader image"},
-                               cli.StringFlag{Name: "size, s", Value: "10G", 
Usage: "size of the target user partition (use M or G suffix)"},
-                               cli.StringFlag{Name: "command_line, c", Usage: 
"command line OSv will boot with"},
-                               cli.BoolFlag{Name: "verbose, v", Usage: 
"verbose mode"},
+                               &cli.StringFlag{Name: "loader_image, l", Value: 
"osv-loader", Usage: "the base loader image"},
+                               &cli.StringFlag{Name: "size, s", Value: "10G", 
Usage: "size of the target user partition (use M or G suffix)"},
+                               &cli.StringFlag{Name: "command_line, c", Usage: 
"command line OSv will boot with"},
+                               &cli.BoolFlag{Name: "verbose, v", Usage: 
"verbose mode"},
                        },
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 2 {
+                               if c.Args().Len() != 2 {
                                        return cli.NewExitError("Usage: capstan 
compose [image-name] [path-to-upload]", EX_USAGE)
                                }
 
                                // Name of the application (or image) that will 
be used in the internal repository.
-                               appName := c.Args()[0]
+                               appName := c.Args().Get(0)
                                // File or directory path that needs to be 
uploaded
-                               uploadPath := c.Args()[1]
+                               uploadPath := c.Args().Get(1)
 
                                repo := util.NewRepoFromCli(c)
 
@@ -275,9 +275,9 @@ func main() {
                        },
                },
                {
-                       Name:      "images",
-                       ShortName: "i",
-                       Usage:     "list images",
+                       Name:    "images",
+                       Aliases: []string{"i"},
+                       Usage:   "list images",
                        Action: func(c *cli.Context) error {
                                repo := util.NewRepoFromCli(c)
                                fmt.Print(repo.ListImages())
@@ -290,8 +290,8 @@ func main() {
                        Usage: "search a remote images",
                        Action: func(c *cli.Context) error {
                                image := ""
-                               if len(c.Args()) > 0 {
-                                       image = c.Args()[0]
+                               if c.Args().Len() > 0 {
+                                       image = c.Args().Get(0)
                                }
                                repo := util.NewRepoFromCli(c)
                                err := util.ListImagesRemote(repo.URL, image)
@@ -302,9 +302,9 @@ func main() {
                        },
                },
                {
-                       Name:      "instances",
-                       ShortName: "I",
-                       Usage:     "list instances",
+                       Name:    "instances",
+                       Aliases: []string{"I"},
+                       Usage:   "list instances",
                        Action: func(c *cli.Context) error {
                                cmd.Instances()
 
@@ -315,10 +315,10 @@ func main() {
                        Name:  "stop",
                        Usage: "stop an instance",
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        return cli.NewExitError("usage: capstan 
stop [instance_name]", EX_USAGE)
                                }
-                               instance := c.Args()[0]
+                               instance := c.Args().Get(0)
                                if err := cmd.Stop(instance); err != nil {
                                        return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
@@ -329,10 +329,10 @@ func main() {
                        Name:  "delete",
                        Usage: "delete an instance",
                        Action: func(c *cli.Context) error {
-                               if len(c.Args()) != 1 {
+                               if c.Args().Len() != 1 {
                                        return cli.NewExitError("usage: capstan 
delete [instance_name]", EX_USAGE)
                                }
-                               instance := c.Args()[0]
+                               instance := c.Args().Get(0)
                                if err := cmd.Delete(instance); err != nil {
                                        return cli.NewExitError(err.Error(), 
EX_DATAERR)
                                }
@@ -342,30 +342,30 @@ func main() {
                {
                        Name:  "package",
                        Usage: "package manipulation tools",
-                       Subcommands: []cli.Command{
+                       Subcommands: []*cli.Command{
                                {
                                        Name:      "init",
                                        Usage:     "initialise package 
structure",
                                        ArgsUsage: "[path]",
                                        Flags: []cli.Flag{
-                                               cli.StringFlag{Name: "name,n", 
Usage: "package name"},
-                                               cli.StringFlag{Name: "title,t", 
Usage: "package title"},
-                                               cli.StringFlag{Name: 
"author,a", Usage: "package author"},
-                                               cli.StringFlag{Name: 
"version,v", Usage: "package version"},
-                                               cli.StringSliceFlag{Name: 
"require", Usage: "specify package dependency"},
-                                               cli.StringFlag{Name: "runtime", 
Usage: "runtime to stub package for. Use 'capstan runtime list' to list all"},
-                                               cli.StringFlag{Name: "p, 
platform", Usage: "platform where package was built on"},
+                                               &cli.StringFlag{Name: "name,n", 
Usage: "package name"},
+                                               &cli.StringFlag{Name: 
"title,t", Usage: "package title"},
+                                               &cli.StringFlag{Name: 
"author,a", Usage: "package author"},
+                                               &cli.StringFlag{Name: 
"version,v", Usage: "package version"},
+                                               &cli.StringSliceFlag{Name: 
"require", Usage: "specify package dependency"},
+                                               &cli.StringFlag{Name: 
"runtime", Usage: "runtime to stub package for. Use 'capstan runtime list' to 
list all"},
+                                               &cli.StringFlag{Name: "p, 
platform", Usage: "platform where package was built on"},
                                        },
                                        Action: func(c *cli.Context) error {
-                                               if len(c.Args()) > 1 {
+                                               if c.Args().Len() > 1 {
                                                        return 
cli.NewExitError("usage: capstan package init [path]", EX_USAGE)
                                                }
 
                                                // The package path is the 
current working dir...
                                                packagePath, _ := os.Getwd()
                                                // ... unless the user has 
provided the exact location.
-                                               if len(c.Args()) == 1 {
-                                                       packagePath = 
c.Args()[0]
+                                               if c.Args().Len() == 1 {
+                                                       packagePath = 
c.Args().Get(0)
                                                }
 
                                                // Author is a mandatory field.
@@ -427,19 +427,19 @@ func main() {
                                        Usage:     "composes the package and 
all its dependencies into OSv image",
                                        ArgsUsage: "image-name",
                                        Flags: []cli.Flag{
-                                               cli.StringFlag{Name: "size, s", 
Value: "10G", Usage: "total size of the target image (use M or G suffix)"},
-                                               cli.BoolFlag{Name: "update", 
Usage: "updates the existing target VM by uploading only modified files"},
-                                               cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
-                                               cli.StringFlag{Name: "run", 
Usage: "the command line to be executed in the VM"},
-                                               cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
-                                               cli.StringSliceFlag{Name: 
"boot", Usage: "specify default config_set name to boot unikernel with 
(repeatable, will be run left to right)"},
-                                               cli.StringSliceFlag{Name: 
"env", Value: new(cli.StringSlice), Usage: "specify value of environment 
variable e.g. PORT=8000 (repeatable)"},
-                                               cli.StringFlag{Name: "fs", 
Usage: "specify type of filesystem: zfs or rofs"},
-                                               cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
-                                               cli.StringFlag{Name: 
"loader_image, l", Value: "osv-loader", Usage: "the base loader image"},
+                                               &cli.StringFlag{Name: "size, 
s", Value: "10G", Usage: "total size of the target image (use M or G suffix)"},
+                                               &cli.BoolFlag{Name: "update", 
Usage: "updates the existing target VM by uploading only modified files"},
+                                               &cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
+                                               &cli.StringFlag{Name: "run", 
Usage: "the command line to be executed in the VM"},
+                                               &cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
+                                               &cli.StringSliceFlag{Name: 
"boot", Usage: "specify default config_set name to boot unikernel with 
(repeatable, will be run left to right)"},
+                                               &cli.StringSliceFlag{Name: 
"env", Value: new(cli.StringSlice), Usage: "specify value of environment 
variable e.g. PORT=8000 (repeatable)"},
+                                               &cli.StringFlag{Name: "fs", 
Usage: "specify type of filesystem: zfs or rofs"},
+                                               &cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
+                                               &cli.StringFlag{Name: 
"loader_image, l", Value: "osv-loader", Usage: "the base loader image"},
                                        },
                                        Action: func(c *cli.Context) error {
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("Usage: capstan package compose [image-name]", EX_USAGE)
                                                }
 
@@ -455,7 +455,7 @@ func main() {
                                                        return 
cli.NewExitError(fmt.Sprintf("Incorrect image size format: %s\n", err), 
EX_USAGE)
                                                }
 
-                                               loaderImage := c.String("l")
+                                               loaderImage := c.String("l")
 
                                                updatePackage := 
c.Bool("update")
                                                verbose := c.Bool("verbose")
@@ -489,12 +489,12 @@ func main() {
                                        Usage:     "composes the package and 
all its dependencies and uploads resulting files into remote OSv instance",
                                        ArgsUsage: "remote-instance",
                                        Flags: []cli.Flag{
-                                               cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
-                                               cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
-                                               cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
+                                               &cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
+                                               &cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
+                                               &cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
                                        },
                                        Action: func(c *cli.Context) error {
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("Usage: capstan package compose-remote [remote-instance]", 
EX_USAGE)
                                                }
 
@@ -522,10 +522,10 @@ func main() {
                                        Name:  "collect",
                                        Usage: "collects contents of this 
package and all required packages",
                                        Flags: []cli.Flag{
-                                               cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
-                                               cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
-                                               cli.BoolFlag{Name: "remote", 
Usage: "set when previewing the compose-remote"},
-                                               cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
+                                               &cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
+                                               &cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
+                                               &cli.BoolFlag{Name: "remote", 
Usage: "set when previewing the compose-remote"},
+                                               &cli.StringSliceFlag{Name: 
"require", Usage: "specify extra package dependency"},
                                        },
                                        Action: func(c *cli.Context) error {
                                                repo := util.NewRepoFromCli(c)
@@ -591,7 +591,7 @@ func main() {
                                        ArgsUsage: "[package-name]",
                                        Action: func(c *cli.Context) error {
                                                // Name of the package is 
required argument.
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("usage: capstan package pull [package-name]", EX_USAGE)
                                                }
 
@@ -609,18 +609,18 @@ func main() {
                                        Usage:     "describes the package from 
local repository",
                                        ArgsUsage: "[package-name]",
                                        Flags: []cli.Flag{
-                                               cli.BoolFlag{Name: "content, 
c", Usage: "show file content"},
+                                               &cli.BoolFlag{Name: "content, 
c", Usage: "show file content"},
                                        },
                                        Action: func(c *cli.Context) error {
                                                // Name of the package is 
required argument.
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("usage: capstan package describe [package-name]", EX_USAGE)
                                                }
 
                                                // Initialise the repository
                                                repo := util.NewRepoFromCli(c)
 
-                                               packageName := c.Args()[0]
+                                               packageName := c.Args().Get(0)
 
                                                // Describe the package
                                                if s, err := 
cmd.DescribePackage(repo, packageName, c.Bool("content")); err != nil {
@@ -637,15 +637,15 @@ func main() {
                                        Usage:     "updates local packages from 
remote if remote version is newer",
                                        ArgsUsage: "[package-name]",
                                        Flags: []cli.Flag{
-                                               cli.BoolFlag{Name: "created", 
Usage: "update package also if created date is newer (regardless version)"},
-                                               cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
+                                               &cli.BoolFlag{Name: "created", 
Usage: "update package also if created date is newer (regardless version)"},
+                                               &cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
                                        },
                                        Action: func(c *cli.Context) error {
                                                // Initialise the repository
                                                repo := util.NewRepoFromCli(c)
 
                                                search := ""
-                                               if len(c.Args()) > 0 {
+                                               if c.Args().Len() > 0 {
                                                        search = 
c.Args().First()
                                                }
 
@@ -663,21 +663,21 @@ func main() {
                        Name:    "stack",
                        Aliases: []string{"openstack"},
                        Usage:   "OpenStack manipulation tools",
-                       Subcommands: []cli.Command{
+                       Subcommands: []*cli.Command{
                                {
                                        Name:  "push",
                                        Usage: "composes OSv image and pushes 
it to OpenStack",
                                        Flags: append(
                                                []cli.Flag{
-                                                       cli.StringFlag{Name: 
"size, s", Value: "10G", Usage: "minimal size of the target user partition (use 
M or G suffix).\n" +
+                                                       &cli.StringFlag{Name: 
"size, s", Value: "10G", Usage: "minimal size of the target user partition (use 
M or G suffix).\n" +
                                                                "\tNOTE: will 
be enlarged to match flavor size."},
-                                                       cli.StringFlag{Name: 
"flavor, f", Usage: "OpenStack flavor name that created OSv image should fit 
to"},
-                                                       cli.StringFlag{Name: 
"run", Usage: "the command line to be executed in the VM"},
-                                                       cli.BoolFlag{Name: 
"keep-image", Usage: "don't delete local composed image in 
.capstan/repository/stack"},
-                                                       cli.BoolFlag{Name: 
"verbose, v", Usage: "verbose mode"},
-                                                       cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
-                                                       
cli.StringSliceFlag{Name: "boot", Usage: "specify config_set name to boot 
unikernel with (repeatable, will be run left to right)"},
-                                                       
cli.StringSliceFlag{Name: "env", Value: new(cli.StringSlice), Usage: "specify 
value of environment variable e.g. PORT=8000 (repeatable)"},
+                                                       &cli.StringFlag{Name: 
"flavor, f", Usage: "OpenStack flavor name that created OSv image should fit 
to"},
+                                                       &cli.StringFlag{Name: 
"run", Usage: "the command line to be executed in the VM"},
+                                                       &cli.BoolFlag{Name: 
"keep-image", Usage: "don't delete local composed image in 
.capstan/repository/stack"},
+                                                       &cli.BoolFlag{Name: 
"verbose, v", Usage: "verbose mode"},
+                                                       &cli.BoolFlag{Name: 
"pull-missing, p", Usage: "attempt to pull packages missing from a local 
repository"},
+                                                       
&cli.StringSliceFlag{Name: "boot", Usage: "specify config_set name to boot 
unikernel with (repeatable, will be run left to right)"},
+                                                       
&cli.StringSliceFlag{Name: "env", Value: new(cli.StringSlice), Usage: "specify 
value of environment variable e.g. PORT=8000 (repeatable)"},
                                                }, 
openstack.OPENSTACK_CREDENTIALS_FLAGS...),
                                        ArgsUsage:   "image-name",
                                        Description: "Compose package, build 
.qcow2 image and upload it to OpenStack under nickname <image-name>.",
@@ -695,11 +695,11 @@ func main() {
                                        Usage: "runs image that was previously 
pushed to OpenStack",
                                        Flags: append(
                                                []cli.Flag{
-                                                       cli.StringFlag{Name: 
"flavor, f", Usage: "OpenStack flavor to be run with"},
-                                                       cli.StringFlag{Name: 
"mem, m", Usage: "MB of memory (RAM) to be run with"},
-                                                       cli.StringFlag{Name: 
"name, n", Usage: "instance name"},
-                                                       cli.IntFlag{Name: 
"count, c", Value: 1, Usage: "number of instances to run"},
-                                                       cli.BoolFlag{Name: 
"verbose, v", Usage: "verbose mode"},
+                                                       &cli.StringFlag{Name: 
"flavor, f", Usage: "OpenStack flavor to be run with"},
+                                                       &cli.StringFlag{Name: 
"mem, m", Usage: "MB of memory (RAM) to be run with"},
+                                                       &cli.StringFlag{Name: 
"name, n", Usage: "instance name"},
+                                                       &cli.IntFlag{Name: 
"count, c", Value: 1, Usage: "number of instances to run"},
+                                                       &cli.BoolFlag{Name: 
"verbose, v", Usage: "verbose mode"},
                                                }, 
openstack.OPENSTACK_CREDENTIALS_FLAGS...),
                                        ArgsUsage: "image-name",
                                        Description: "Run image that you've 
previously uploaded with 'capstan stack push'.\n   " +
@@ -720,13 +720,13 @@ func main() {
                {
                        Name:  "runtime",
                        Usage: "package runtime manipulation tools 
(meta/run.yaml)",
-                       Subcommands: []cli.Command{
+                       Subcommands: []*cli.Command{
                                {
                                        Name:  "preview",
                                        Usage: "prints runtime yaml template to 
the console",
                                        Flags: []cli.Flag{
-                                               cli.StringFlag{Name: "runtime, 
r", Usage: "Runtime name. Use 'capstan runtime list' to see available names."},
-                                               cli.BoolFlag{Name: "plain", 
Usage: "Remove comments"},
+                                               &cli.StringFlag{Name: "runtime, 
r", Usage: "Runtime name. Use 'capstan runtime list' to see available names."},
+                                               &cli.BoolFlag{Name: "plain", 
Usage: "Remove comments"},
                                        },
                                        Action: func(c *cli.Context) error {
                                                if c.String("runtime") == "" {
@@ -744,9 +744,9 @@ func main() {
                                        Name:  "init",
                                        Usage: "prepares meta/run.yaml stub for 
selected runtime",
                                        Flags: []cli.Flag{
-                                               cli.StringFlag{Name: "runtime, 
r", Usage: "Runtime name. Use 'capstan runtime list' to see available names."},
-                                               cli.BoolFlag{Name: "plain", 
Usage: "Remove comments"},
-                                               cli.BoolFlag{Name: "force, f", 
Usage: "Override existing meta/run.yaml"},
+                                               &cli.StringFlag{Name: "runtime, 
r", Usage: "Runtime name. Use 'capstan runtime list' to see available names."},
+                                               &cli.BoolFlag{Name: "plain", 
Usage: "Remove comments"},
+                                               &cli.BoolFlag{Name: "force, f", 
Usage: "Override existing meta/run.yaml"},
                                        },
                                        Action: func(c *cli.Context) error {
                                                if c.String("runtime") == "" {
@@ -775,17 +775,17 @@ func main() {
                {
                        Name:  "volume",
                        Usage: "volume manipulation tools",
-                       Subcommands: []cli.Command{
+                       Subcommands: []*cli.Command{
                                {
                                        Name:      "create",
                                        Usage:     "create empty volume and 
store it into ./volumes directory",
                                        ArgsUsage: "[volume-name]",
                                        Flags: []cli.Flag{
-                                               cli.StringFlag{Name: "size, s", 
Value: "1G", Usage: "total size of the target image (use M or G suffix)"},
-                                               cli.StringFlag{Name: "format, 
f", Usage: "volume format, e.g. [raw|qcow2|vdi|vmdk|...]"},
+                                               &cli.StringFlag{Name: "size, 
s", Value: "1G", Usage: "total size of the target image (use M or G suffix)"},
+                                               &cli.StringFlag{Name: "format, 
f", Usage: "volume format, e.g. [raw|qcow2|vdi|vmdk|...]"},
                                        },
                                        Action: func(c *cli.Context) error {
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("usage: capstan volume create [volume-name]", EX_USAGE)
                                                }
 
@@ -814,10 +814,10 @@ func main() {
                                        Usage:     "delete volume by name",
                                        ArgsUsage: "[volume-name]",
                                        Flags: []cli.Flag{
-                                               cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
+                                               &cli.BoolFlag{Name: "verbose, 
v", Usage: "verbose mode"},
                                        },
                                        Action: func(c *cli.Context) error {
-                                               if len(c.Args()) != 1 {
+                                               if c.Args().Len() != 1 {
                                                        return 
cli.NewExitError("usage: capstan volume delete [volume-name]", EX_USAGE)
                                                }
                                                name := c.Args().First()
diff --git a/cmd/build.go b/cmd/build.go
index 54ab691..4e3ff1d 100644
--- a/cmd/build.go
+++ b/cmd/build.go
@@ -12,7 +12,7 @@ import (
        "bufio"
        "errors"
        "fmt"
-       "github.com/cheggaaa/pb"
+       "github.com/cheggaaa/pb/v3"
        "github.com/cloudius-systems/capstan/core"
        "github.com/cloudius-systems/capstan/cpio"
        "github.com/cloudius-systems/capstan/hypervisor/qemu"
diff --git a/cmd/compose.go b/cmd/compose.go
index 62c3eb4..82298ed 100644
--- a/cmd/compose.go
+++ b/cmd/compose.go
@@ -11,7 +11,7 @@ import (
        "bufio"
        "crypto/md5"
        "fmt"
-       "github.com/cheggaaa/pb"
+       "github.com/cheggaaa/pb/v3"
        "github.com/cloudius-systems/capstan/core"
        "github.com/cloudius-systems/capstan/cpio"
        "github.com/cloudius-systems/capstan/hypervisor/qemu"
@@ -172,7 +172,8 @@ func uploadFiles(conn net.Conn, uploadPaths 
map[string]string, imageCache core.H
        // silent mode is activated.
        var bar *pb.ProgressBar
        if !verbose {
-               bar = pb.StartNew(len(uploadPaths)).Prefix("Uploading files ")
+               tmpl := `{{ yellow "Uploading files " }} {{ bar . "<" "-" 
(cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | green}} {{percent . | blue}}`
+               bar = pb.ProgressBarTemplate(tmpl).Start(len(uploadPaths))
        }
 
        // Initialise a dictionary for the up-to-date file hashes.
@@ -215,7 +216,8 @@ func uploadFiles(conn net.Conn, uploadPaths 
map[string]string, imageCache core.H
        }
 
        if !verbose {
-               bar.FinishPrint("All files uploaded")
+               bar.Finish()
+               fmt.Println("All files uploaded")
        }
 
        // Finalise the transfer.
diff --git a/cmd/config.go b/cmd/config.go
index 5d5454f..60d05f5 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -13,12 +13,12 @@ import (
 
        "github.com/cloudius-systems/capstan/core"
        "github.com/cloudius-systems/capstan/util"
-       "github.com/urfave/cli"
+       "github.com/urfave/cli/v2"
 )
 
 // ConfigPrint prints current capstan configuration to console.
 func ConfigPrint(c *cli.Context) error {
-       repo := util.NewRepo(c.GlobalString("u"))
+       repo := util.NewRepo(c.String("u"))
        fmt.Println("--- global configuration")
        repo.PrintRepo()
        fmt.Println()
diff --git a/cmd/stack.go b/cmd/stack.go
index 8f0f80a..3648362 100644
--- a/cmd/stack.go
+++ b/cmd/stack.go
@@ -14,7 +14,7 @@ import (
 
        "github.com/cloudius-systems/capstan/provider/openstack"
        "github.com/cloudius-systems/capstan/util"
-       "github.com/urfave/cli"
+       "github.com/urfave/cli/v2"
 )
 
 // OpenStackPush picks best flavor, composes package, builds .qcow2 image and 
uploads it to OpenStack.
@@ -28,7 +28,7 @@ func OpenStackPush(c *cli.Context) error {
        }
 
        // Use the provided repository.
-       repo := util.NewRepo(c.GlobalString("u"))
+       repo := util.NewRepo(c.String("u"))
 
        // Get temporary name of the application.
        appName := imageName
@@ -72,7 +72,7 @@ func OpenStackPush(c *cli.Context) error {
 
        // Compose image locally.
        fmt.Printf("Creating image of user-usable size %d MB.\n", sizeMB)
-       err = ComposePackage(repo, []string {}, sizeMB, false, verbose, 
pullMissing, packageDir, appName, &bootOpts, "zfs", "")
+       err = ComposePackage(repo, []string{}, sizeMB, false, verbose, 
pullMissing, packageDir, appName, &bootOpts, "zfs", "")
        if err != nil {
                return err
        }
diff --git a/provider/openstack/openstack_auth.go 
b/provider/openstack/openstack_auth.go
index 95679b9..22ef1a6 100644
--- a/provider/openstack/openstack_auth.go
+++ b/provider/openstack/openstack_auth.go
@@ -11,20 +11,20 @@ import (
        "fmt"
        "github.com/gophercloud/gophercloud"
        "github.com/gophercloud/gophercloud/openstack"
-       "github.com/urfave/cli"
+       "github.com/urfave/cli/v2"
        "os"
 )
 
 // OPENSTACK_CREDENTIALS_FLAGS is a list of argumets that are used for 
OpenStack authentication.
 // Append it to Flags list to enable direct authentication i.e. without 
environment variables.
 var OPENSTACK_CREDENTIALS_FLAGS = []cli.Flag{
-       cli.StringFlag{Name: "OS_AUTH_URL", Usage: "OpenStack auth url (e.g. 
http://10.0.2.15:5000/v2.0)"},
-       cli.StringFlag{Name: "OS_TENANT_ID", Usage: "OpenStack tenant id (e.g. 
3dfe7bf545ff4885a3912a92a4a5f8e0)"},
-       cli.StringFlag{Name: "OS_TENANT_NAME", Usage: "OpenStack tenant name 
(e.g. admin)"},
-       cli.StringFlag{Name: "OS_PROJECT_NAME", Usage: "OpenStack project name 
(e.g. admin)"},
-       cli.StringFlag{Name: "OS_USERNAME", Usage: "OpenStack username (e.g. 
admin)"},
-       cli.StringFlag{Name: "OS_PASSWORD", Usage: "OpenStack password (*TODO*: 
leave blank to be prompted)"},
-       cli.StringFlag{Name: "OS_REGION_NAME", Usage: "OpenStack username (e.g. 
RegionOne)"},
+       &cli.StringFlag{Name: "OS_AUTH_URL", Usage: "OpenStack auth url (e.g. 
http://10.0.2.15:5000/v2.0)"},
+       &cli.StringFlag{Name: "OS_TENANT_ID", Usage: "OpenStack tenant id (e.g. 
3dfe7bf545ff4885a3912a92a4a5f8e0)"},
+       &cli.StringFlag{Name: "OS_TENANT_NAME", Usage: "OpenStack tenant name 
(e.g. admin)"},
+       &cli.StringFlag{Name: "OS_PROJECT_NAME", Usage: "OpenStack project name 
(e.g. admin)"},
+       &cli.StringFlag{Name: "OS_USERNAME", Usage: "OpenStack username (e.g. 
admin)"},
+       &cli.StringFlag{Name: "OS_PASSWORD", Usage: "OpenStack password 
(*TODO*: leave blank to be prompted)"},
+       &cli.StringFlag{Name: "OS_REGION_NAME", Usage: "OpenStack username 
(e.g. RegionOne)"},
 }
 
 // ObtainCredentials attempts to obtain OpenStack credentials either from 
command args eihter from env.
diff --git a/util/remote_repository.go b/util/remote_repository.go
index 6820614..f6d2e5a 100644
--- a/util/remote_repository.go
+++ b/util/remote_repository.go
@@ -3,7 +3,7 @@ package util
 import (
        "compress/gzip"
        "fmt"
-       "github.com/cheggaaa/pb"
+       "github.com/cheggaaa/pb/v3"
        "github.com/cloudius-systems/capstan/core"
        "gopkg.in/yaml.v2"
        "io"
@@ -168,7 +168,7 @@ func (r *Repo) downloadFile(fileURL string, destPath 
string, name string) error
                return err
        }
        defer resp.Body.Close()
-       bar := pb.New64(resp.ContentLength).SetUnits(pb.U_BYTES)
+       bar := pb.New64(resp.ContentLength).Set(pb.Bytes, true)
        bar.Start()
        proxyReader := bar.NewProxyReader(resp.Body)
        var reader io.Reader = proxyReader
diff --git a/util/repository.go b/util/repository.go
index 5f4fff2..660f2fb 100644
--- a/util/repository.go
+++ b/util/repository.go
@@ -13,7 +13,7 @@ import (
        "compress/gzip"
        "errors"
        "fmt"
-       "github.com/urfave/cli"
+       "github.com/urfave/cli/v2"
        "io"
        "io/ioutil"
        "os"
@@ -29,9 +29,9 @@ import (
 )
 
 const (
-       NewLoaderImageName = "osv-loader"
-       OldLoaderImageName = "mike/osv-loader"
-       VmlinuzLoaderName = "osv-vmlinuz.bin"
+       NewLoaderImageName     = "osv-loader"
+       OldLoaderImageName     = "mike/osv-loader"
+       VmlinuzLoaderName      = "osv-vmlinuz.bin"
        GitHubRepositoryApiUrl = "https://api.github.com";
 )
 
@@ -105,12 +105,12 @@ func NewRepo(url string) *Repo {
 }
 
 func NewRepoFromCli(c *cli.Context) *Repo {
-       repo := NewRepo(c.GlobalString("u"))
-       repo.UseS3 = c.GlobalBool("s3")
+       repo := NewRepo(c.String("u"))
+       repo.UseS3 = c.Bool("s3")
        repo.GithubURL = GitHubRepositoryApiUrl
 
-       if c.GlobalString("release-tag") != "" {
-               repo.ReleaseTag = c.GlobalString("release-tag")
+       if c.String("release-tag") != "" {
+               repo.ReleaseTag = c.String("release-tag")
        }
 
        return repo
-- 
2.17.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20191209135221.16673-1-xiaokedou123456%40gmail.com.

Reply via email to