diff --git a/cmd/ignite-spawn/ignite-spawn.go b/cmd/ignite-spawn/ignite-spawn.go index e43d72923..fdc1fd5b5 100644 --- a/cmd/ignite-spawn/ignite-spawn.go +++ b/cmd/ignite-spawn/ignite-spawn.go @@ -5,13 +5,13 @@ import ( "os" "path" - "github.com/weaveworks/ignite/pkg/constants" - log "github.com/sirupsen/logrus" api "github.com/weaveworks/ignite/pkg/apis/ignite" + "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/container" "github.com/weaveworks/ignite/pkg/container/prometheus" "github.com/weaveworks/ignite/pkg/logs" + "github.com/weaveworks/ignite/pkg/providers" ) func main() { @@ -23,6 +23,11 @@ func main() { // Run runs the main cobra command of this application func Run() error { + // Populate the providers + if err := providers.Populate(); err != nil { + return err + } + if len(os.Args) != 2 { fmt.Printf("Usage: ignite-spawn [VM ID]") os.Exit(0) diff --git a/cmd/ignite/cmd/gitops.go b/cmd/ignite/cmd/gitops.go index 65c5b70bc..452fe73b3 100644 --- a/cmd/ignite/cmd/gitops.go +++ b/cmd/ignite/cmd/gitops.go @@ -4,7 +4,6 @@ import ( "io" "github.com/lithammer/dedent" - "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/weaveworks/ignite/pkg/errutils" diff --git a/cmd/ignite/cmd/kerncmd/kernel.go b/cmd/ignite/cmd/kerncmd/kernel.go index 7088dd111..6a8b9a4d3 100644 --- a/cmd/ignite/cmd/kerncmd/kernel.go +++ b/cmd/ignite/cmd/kerncmd/kernel.go @@ -4,7 +4,6 @@ import ( "io" "github.com/lithammer/dedent" - "github.com/spf13/cobra" "github.com/weaveworks/ignite/cmd/ignite/run" "github.com/weaveworks/ignite/pkg/errutils" diff --git a/cmd/ignite/cmd/logs.go b/cmd/ignite/cmd/logs.go index e4a58d086..4612a0314 100644 --- a/cmd/ignite/cmd/logs.go +++ b/cmd/ignite/cmd/logs.go @@ -3,9 +3,8 @@ package cmd import ( "io" - "github.com/weaveworks/ignite/cmd/ignite/cmd/vmcmd" - "github.com/spf13/cobra" + "github.com/weaveworks/ignite/cmd/ignite/cmd/vmcmd" ) // NewCmdLogs is an alias for vmcmd.NewCmdLogs diff --git a/cmd/ignite/cmd/version.go b/cmd/ignite/cmd/version.go index 409213d4c..5e980d235 100644 --- a/cmd/ignite/cmd/version.go +++ b/cmd/ignite/cmd/version.go @@ -3,9 +3,8 @@ package cmd import ( "io" - "github.com/weaveworks/ignite/cmd/ignite/run" - "github.com/spf13/cobra" + "github.com/weaveworks/ignite/cmd/ignite/run" "github.com/weaveworks/ignite/pkg/errutils" ) diff --git a/cmd/ignite/cmd/vmcmd/create.go b/cmd/ignite/cmd/vmcmd/create.go index 19966d452..f0c6fd4d6 100644 --- a/cmd/ignite/cmd/vmcmd/create.go +++ b/cmd/ignite/cmd/vmcmd/create.go @@ -4,13 +4,12 @@ import ( "fmt" "io" - "github.com/weaveworks/ignite/pkg/constants" - "github.com/lithammer/dedent" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/weaveworks/ignite/cmd/ignite/cmd/cmdutil" "github.com/weaveworks/ignite/cmd/ignite/run" + "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/errutils" ) diff --git a/cmd/ignite/ignite.go b/cmd/ignite/ignite.go index a272b6fa6..7ed321fe8 100644 --- a/cmd/ignite/ignite.go +++ b/cmd/ignite/ignite.go @@ -5,6 +5,7 @@ import ( "os" "github.com/weaveworks/ignite/cmd/ignite/cmd" + "github.com/weaveworks/ignite/pkg/providers" ) func main() { @@ -17,6 +18,11 @@ func main() { // Run runs the main cobra command of this application func Run() error { + // Populate the providers + if err := providers.Populate(); err != nil { + return err + } + c := cmd.NewIgniteCommand(os.Stdin, os.Stdout, os.Stderr) return c.Execute() } diff --git a/cmd/ignite/run/attach.go b/cmd/ignite/run/attach.go index 54b504d97..22f339da1 100644 --- a/cmd/ignite/run/attach.go +++ b/cmd/ignite/run/attach.go @@ -36,6 +36,8 @@ func Attach(ao *attachOptions) error { } // Attach to the VM in Docker + // TODO: Implement the pseudo-TTY and remove this call, see + // https://github.com/weaveworks/ignite/pull/211#issuecomment-512809841 if ec, err := util.ExecForeground("docker", dockerArgs...); err != nil { if ec != 1 { // Docker's detach sequence (^P^Q) has an exit code of -1 return fmt.Errorf("failed to attach to container for VM %s: %v", ao.vm.GetUID(), err) diff --git a/cmd/ignite/run/create.go b/cmd/ignite/run/create.go index 3aff53b30..65222e8de 100644 --- a/cmd/ignite/run/create.go +++ b/cmd/ignite/run/create.go @@ -8,12 +8,12 @@ import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/metadata" "github.com/weaveworks/ignite/pkg/metadata/imgmd" "github.com/weaveworks/ignite/pkg/metadata/kernmd" "github.com/weaveworks/ignite/pkg/metadata/vmmd" "github.com/weaveworks/ignite/pkg/operations" + "github.com/weaveworks/ignite/pkg/providers" ) func NewCreateFlags() *CreateFlags { @@ -98,7 +98,7 @@ func (cf *CreateFlags) NewCreateOptions(args []string) (*createOptions, error) { // Get the image, or import it if it doesn't exist var err error - co.image, err = operations.FindOrImportImage(client.DefaultClient, cf.VM.Spec.Image.OCIClaim.Ref) + co.image, err = operations.FindOrImportImage(providers.Client, cf.VM.Spec.Image.OCIClaim.Ref) if err != nil { return nil, err } @@ -107,7 +107,7 @@ func (cf *CreateFlags) NewCreateOptions(args []string) (*createOptions, error) { cf.VM.SetImage(co.image.Image) // Get the kernel, or import it if it doesn't exist - co.kernel, err = operations.FindOrImportKernel(client.DefaultClient, cf.VM.Spec.Kernel.OCIClaim.Ref) + co.kernel, err = operations.FindOrImportKernel(providers.Client, cf.VM.Spec.Kernel.OCIClaim.Ref) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func (cf *CreateFlags) NewCreateOptions(args []string) (*createOptions, error) { func Create(co *createOptions) error { // Create new metadata for the VM var err error - if co.newVM, err = vmmd.NewVM(co.VM, client.DefaultClient); err != nil { + if co.newVM, err = vmmd.NewVM(co.VM, providers.Client); err != nil { return err } defer metadata.Cleanup(co.newVM, false) // TODO: Handle silent diff --git a/cmd/ignite/run/helpers.go b/cmd/ignite/run/helpers.go index ab579deb4..a813d6ccc 100644 --- a/cmd/ignite/run/helpers.go +++ b/cmd/ignite/run/helpers.go @@ -1,14 +1,14 @@ package run import ( - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" "github.com/weaveworks/ignite/pkg/metadata/vmmd" + "github.com/weaveworks/ignite/pkg/providers" ) // TODO: This func getVMForMatch(vmMatch string) (*vmmd.VM, error) { - apiVM, err := client.VMs().Find(filter.NewIDNameFilter(vmMatch)) + apiVM, err := providers.Client.VMs().Find(filter.NewIDNameFilter(vmMatch)) if err != nil { return nil, err } @@ -29,7 +29,7 @@ func getVMsForMatches(vmMatches []string) ([]*vmmd.VM, error) { } func getAllVMs() (allVMs []*vmmd.VM, err error) { - allAPIVMs, err := client.VMs().FindAll(filter.NewAllFilter()) + allAPIVMs, err := providers.Client.VMs().FindAll(filter.NewAllFilter()) if err != nil { return } diff --git a/cmd/ignite/run/images.go b/cmd/ignite/run/images.go index bcc80b87d..05522422e 100644 --- a/cmd/ignite/run/images.go +++ b/cmd/ignite/run/images.go @@ -2,8 +2,8 @@ package run import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/util" ) @@ -13,7 +13,7 @@ type imagesOptions struct { func NewImagesOptions() (io *imagesOptions, err error) { io = &imagesOptions{} - io.allImages, err = client.Images().FindAll(filter.NewAllFilter()) + io.allImages, err = providers.Client.Images().FindAll(filter.NewAllFilter()) return } diff --git a/cmd/ignite/run/import.go b/cmd/ignite/run/import.go index fa8f35b9d..925f775ba 100644 --- a/cmd/ignite/run/import.go +++ b/cmd/ignite/run/import.go @@ -2,11 +2,11 @@ package run import ( meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/metadata" "github.com/weaveworks/ignite/pkg/metadata/imgmd" "github.com/weaveworks/ignite/pkg/metadata/kernmd" "github.com/weaveworks/ignite/pkg/operations" + "github.com/weaveworks/ignite/pkg/providers" ) func ImportImage(source string) (*imgmd.Image, error) { @@ -15,7 +15,7 @@ func ImportImage(source string) (*imgmd.Image, error) { return nil, err } - runImage, err := operations.FindOrImportImage(client.DefaultClient, ociRef) + runImage, err := operations.FindOrImportImage(providers.Client, ociRef) if err != nil { return nil, err } @@ -30,7 +30,7 @@ func ImportKernel(source string) (*kernmd.Kernel, error) { return nil, err } - runKernel, err := operations.FindOrImportKernel(client.DefaultClient, ociRef) + runKernel, err := operations.FindOrImportKernel(providers.Client, ociRef) if err != nil { return nil, err } diff --git a/cmd/ignite/run/inspect.go b/cmd/ignite/run/inspect.go index 98603fc50..0f4ebfc23 100644 --- a/cmd/ignite/run/inspect.go +++ b/cmd/ignite/run/inspect.go @@ -8,8 +8,8 @@ import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" + "github.com/weaveworks/ignite/pkg/providers" ) type InspectFlags struct { @@ -37,7 +37,7 @@ func (i *InspectFlags) NewInspectOptions(k, objectMatch string) (*inspectOptions return nil, fmt.Errorf("unrecognized kind: %q", k) } - if io.object, err = client.Dynamic(kind).Find(filter.NewIDNameFilter(objectMatch)); err != nil { + if io.object, err = providers.Client.Dynamic(kind).Find(filter.NewIDNameFilter(objectMatch)); err != nil { return nil, err } diff --git a/cmd/ignite/run/kernels.go b/cmd/ignite/run/kernels.go index b9fac4413..ed9907da0 100644 --- a/cmd/ignite/run/kernels.go +++ b/cmd/ignite/run/kernels.go @@ -2,8 +2,8 @@ package run import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/util" ) @@ -13,7 +13,7 @@ type kernelsOptions struct { func NewKernelsOptions() (ko *kernelsOptions, err error) { ko = &kernelsOptions{} - ko.allKernels, err = client.Kernels().FindAll(filter.NewAllFilter()) + ko.allKernels, err = providers.Client.Kernels().FindAll(filter.NewAllFilter()) return } diff --git a/cmd/ignite/run/logs.go b/cmd/ignite/run/logs.go index d8710a335..832575656 100644 --- a/cmd/ignite/run/logs.go +++ b/cmd/ignite/run/logs.go @@ -2,9 +2,10 @@ package run import ( "fmt" + "io/ioutil" - "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/metadata/vmmd" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/util" ) @@ -24,18 +25,19 @@ func Logs(lo *logsOptions) error { return fmt.Errorf("VM %q is not running", lo.vm.GetUID()) } - dockerArgs := []string{ - "logs", - constants.IGNITE_PREFIX + lo.vm.GetUID().String(), + // Fetch the VM logs + rc, err := providers.Runtime.ContainerLogs(util.NewPrefixer().Prefix(lo.vm.GetUID())) + if err != nil { + return fmt.Errorf("failed to get logs for VM %q: %v", lo.vm.GetUID(), err) } - // Fetch the VM logs from docker - output, err := util.ExecuteCommand("docker", dockerArgs...) + // Read the stream to a byte buffer + b, err := ioutil.ReadAll(rc) if err != nil { - return fmt.Errorf("failed to get logs for VM %q: %v", lo.vm.GetUID(), err) + return err } - // Print the ID and the VM logs - fmt.Println(output) + // Print the logs + fmt.Printf("%s\n", b) return nil } diff --git a/cmd/ignite/run/ps.go b/cmd/ignite/run/ps.go index c1de45d6c..163eae42a 100644 --- a/cmd/ignite/run/ps.go +++ b/cmd/ignite/run/ps.go @@ -2,8 +2,8 @@ package run import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/util" ) @@ -18,7 +18,7 @@ type psOptions struct { func (pf *PsFlags) NewPsOptions() (po *psOptions, err error) { po = &psOptions{PsFlags: pf} - po.allVMs, err = client.VMs().FindAll(filter.NewVMFilterAll("", po.All)) + po.allVMs, err = providers.Client.VMs().FindAll(filter.NewVMFilterAll("", po.All)) return } diff --git a/cmd/ignite/run/rm.go b/cmd/ignite/run/rm.go index cc7cd003c..6a7ec730d 100644 --- a/cmd/ignite/run/rm.go +++ b/cmd/ignite/run/rm.go @@ -3,9 +3,9 @@ package run import ( "fmt" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/metadata/vmmd" "github.com/weaveworks/ignite/pkg/operations" + "github.com/weaveworks/ignite/pkg/providers" ) type RmFlags struct { @@ -31,7 +31,7 @@ func Rm(ro *rmOptions) error { } // This will first kill the VM container, and then remove it - if err := operations.RemoveVM(client.DefaultClient, vm); err != nil { + if err := operations.RemoveVM(providers.Client, vm); err != nil { return err } } diff --git a/cmd/ignite/run/rmi.go b/cmd/ignite/run/rmi.go index ed38d4f55..d8d8845bf 100644 --- a/cmd/ignite/run/rmi.go +++ b/cmd/ignite/run/rmi.go @@ -4,10 +4,10 @@ import ( "fmt" "os" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" "github.com/weaveworks/ignite/pkg/metadata/imgmd" "github.com/weaveworks/ignite/pkg/metadata/vmmd" + "github.com/weaveworks/ignite/pkg/providers" ) type RmiFlags struct { @@ -24,7 +24,7 @@ func (rf *RmiFlags) NewRmiOptions(imageMatches []string) (*rmiOptions, error) { ro := &rmiOptions{RmiFlags: rf} for _, match := range imageMatches { - if image, err := client.Images().Find(filter.NewIDNameFilter(match)); err == nil { + if image, err := providers.Client.Images().Find(filter.NewIDNameFilter(match)); err == nil { ro.images = append(ro.images, imgmd.WrapImage(image)) } else { return nil, err diff --git a/cmd/ignite/run/rmk.go b/cmd/ignite/run/rmk.go index 38bd6a062..ad4794cfe 100644 --- a/cmd/ignite/run/rmk.go +++ b/cmd/ignite/run/rmk.go @@ -4,11 +4,10 @@ import ( "fmt" "os" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/filter" - "github.com/weaveworks/ignite/pkg/metadata/kernmd" "github.com/weaveworks/ignite/pkg/metadata/vmmd" + "github.com/weaveworks/ignite/pkg/providers" ) type RmkFlags struct { @@ -25,7 +24,7 @@ func (rf *RmkFlags) NewRmkOptions(kernelMatches []string) (*rmkOptions, error) { ro := &rmkOptions{RmkFlags: rf} for _, match := range kernelMatches { - if kernel, err := client.Kernels().Find(filter.NewIDNameFilter(match)); err == nil { + if kernel, err := providers.Client.Kernels().Find(filter.NewIDNameFilter(match)); err == nil { ro.kernels = append(ro.kernels, kernmd.WrapKernel(kernel)) } else { return nil, err diff --git a/cmd/ignite/run/ssh.go b/cmd/ignite/run/ssh.go index 03b682a58..6caaef90c 100644 --- a/cmd/ignite/run/ssh.go +++ b/cmd/ignite/run/ssh.go @@ -5,7 +5,6 @@ import ( "path" log "github.com/sirupsen/logrus" - "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/metadata/vmmd" "github.com/weaveworks/ignite/pkg/util" diff --git a/docs/dependencies.svg b/docs/dependencies.svg index 1c3f9bcb8..28e2be7fa 100644 --- a/docs/dependencies.svg +++ b/docs/dependencies.svg @@ -1,4348 +1,4348 @@ - - - + + %3 - + github.com/weaveworks/\nignite - -github.com/weaveworks/ -ignite + +github.com/weaveworks/ +ignite golang.org/x/sync -golang.org/x/sync +golang.org/x/sync github.com/weaveworks/\nignite->golang.org/x/sync - - + + google.golang.org/grpc -google.golang.org/grpc +google.golang.org/grpc github.com/weaveworks/\nignite->google.golang.org/grpc - - + + github.com/firecracker-microvm/\nfirecracker-go-sdk -github.com/firecracker-microvm/ -firecracker-go-sdk +github.com/firecracker-microvm/ +firecracker-go-sdk github.com/weaveworks/\nignite->github.com/firecracker-microvm/\nfirecracker-go-sdk - - + + github.com/sirupsen/\nlogrus -github.com/sirupsen/ -logrus +github.com/sirupsen/ +logrus github.com/weaveworks/\nignite->github.com/sirupsen/\nlogrus - - + + github.com/go-openapi/\nspec -github.com/go-openapi/ -spec +github.com/go-openapi/ +spec github.com/weaveworks/\nignite->github.com/go-openapi/\nspec - - + + github.com/pkg/\nerrors -github.com/pkg/ -errors +github.com/pkg/ +errors github.com/weaveworks/\nignite->github.com/pkg/\nerrors - - + + github.com/spf13/\npflag -github.com/spf13/ -pflag +github.com/spf13/ +pflag github.com/weaveworks/\nignite->github.com/spf13/\npflag - - + + k8s.io/apimachinery -k8s.io/apimachinery +k8s.io/apimachinery github.com/weaveworks/\nignite->k8s.io/apimachinery - - + + k8s.io/kube-openapi -k8s.io/kube-openapi +k8s.io/kube-openapi github.com/weaveworks/\nignite->k8s.io/kube-openapi - - + + sigs.k8s.io/yaml -sigs.k8s.io/yaml +sigs.k8s.io/yaml github.com/weaveworks/\nignite->sigs.k8s.io/yaml - - + + github.com/gorilla/\nmux -github.com/gorilla/ -mux +github.com/gorilla/ +mux github.com/weaveworks/\nignite->github.com/gorilla/\nmux - - + + github.com/prometheus/\nclient_golang -github.com/prometheus/ -client_golang +github.com/prometheus/ +client_golang github.com/weaveworks/\nignite->github.com/prometheus/\nclient_golang - - + + github.com/spf13/\ncobra -github.com/spf13/ -cobra +github.com/spf13/ +cobra github.com/weaveworks/\nignite->github.com/spf13/\ncobra - - + + github.com/weaveworks/\nflux -github.com/weaveworks/ -flux +github.com/weaveworks/ +flux github.com/weaveworks/\nignite->github.com/weaveworks/\nflux - - + + github.com/docker/\ndistribution -github.com/docker/ -distribution +github.com/docker/ +distribution github.com/weaveworks/\nignite->github.com/docker/\ndistribution - - + + github.com/Azure/\ngo-ansiterm -github.com/Azure/ -go-ansiterm +github.com/Azure/ +go-ansiterm github.com/weaveworks/\nignite->github.com/Azure/\ngo-ansiterm - - + + github.com/c2h5oh/\ndatasize -github.com/c2h5oh/ -datasize +github.com/c2h5oh/ +datasize github.com/weaveworks/\nignite->github.com/c2h5oh/\ndatasize - - + + github.com/containernetworking/\ncni -github.com/containernetworking/ -cni +github.com/containernetworking/ +cni github.com/weaveworks/\nignite->github.com/containernetworking/\ncni - - + + github.com/containers/\nimage -github.com/containers/ -image +github.com/containers/ +image github.com/weaveworks/\nignite->github.com/containers/\nimage - - + + github.com/docker/\ndocker -github.com/docker/ -docker +github.com/docker/ +docker github.com/weaveworks/\nignite->github.com/docker/\ndocker - - + + github.com/docker/\ngo-connections -github.com/docker/ -go-connections +github.com/docker/ +go-connections github.com/weaveworks/\nignite->github.com/docker/\ngo-connections - - + + github.com/emicklei/\ngo-restful -github.com/emicklei/ -go-restful +github.com/emicklei/ +go-restful github.com/weaveworks/\nignite->github.com/emicklei/\ngo-restful - - + + github.com/freddierice/\ngo-losetup -github.com/freddierice/ -go-losetup +github.com/freddierice/ +go-losetup github.com/weaveworks/\nignite->github.com/freddierice/\ngo-losetup - - + + github.com/goombaio/\nnamegenerator -github.com/goombaio/ -namegenerator +github.com/goombaio/ +namegenerator github.com/weaveworks/\nignite->github.com/goombaio/\nnamegenerator - - + + github.com/krolaw/\ndhcp4 -github.com/krolaw/ -dhcp4 +github.com/krolaw/ +dhcp4 github.com/weaveworks/\nignite->github.com/krolaw/\ndhcp4 - - + + github.com/lithammer/\ndedent -github.com/lithammer/ -dedent +github.com/lithammer/ +dedent github.com/weaveworks/\nignite->github.com/lithammer/\ndedent - - + + github.com/Microsoft/\ngo-winio -github.com/Microsoft/ -go-winio +github.com/Microsoft/ +go-winio github.com/weaveworks/\nignite->github.com/Microsoft/\ngo-winio - - + + github.com/miekg/\ndns -github.com/miekg/ -dns +github.com/miekg/ +dns github.com/weaveworks/\nignite->github.com/miekg/\ndns - - + + github.com/morikuni/\naec -github.com/morikuni/ -aec +github.com/morikuni/ +aec github.com/weaveworks/\nignite->github.com/morikuni/\naec - - + + gotest.tools -gotest.tools +gotest.tools github.com/weaveworks/\nignite->gotest.tools - - + + cloud.google.com/go -cloud.google.com/go +cloud.google.com/go github.com/golang/\nmock -github.com/golang/ -mock +github.com/golang/ +mock cloud.google.com/go->github.com/golang/\nmock - - + + github.com/golang/\nprotobuf -github.com/golang/ -protobuf +github.com/golang/ +protobuf cloud.google.com/go->github.com/golang/\nprotobuf - - + + github.com/googleapis/\ngax-go/v2 -github.com/googleapis/ -gax-go/v2 +github.com/googleapis/ +gax-go/v2 cloud.google.com/go->github.com/googleapis/\ngax-go/v2 - - + + github.com/google/\nbtree -github.com/google/ -btree +github.com/google/ +btree cloud.google.com/go->github.com/google/\nbtree - - + + github.com/google/\ngo-cmp -github.com/google/ -go-cmp +github.com/google/ +go-cmp cloud.google.com/go->github.com/google/\ngo-cmp - - + + github.com/google/\nmartian -github.com/google/ -martian +github.com/google/ +martian cloud.google.com/go->github.com/google/\nmartian - - + + github.com/google/\npprof -github.com/google/ -pprof +github.com/google/ +pprof cloud.google.com/go->github.com/google/\npprof - - + + github.com/jstemmer/\ngo-junit-report -github.com/jstemmer/ -go-junit-report +github.com/jstemmer/ +go-junit-report cloud.google.com/go->github.com/jstemmer/\ngo-junit-report - - + + golang.org/x/exp -golang.org/x/exp +golang.org/x/exp cloud.google.com/go->golang.org/x/exp - - + + golang.org/x/lint -golang.org/x/lint +golang.org/x/lint cloud.google.com/go->golang.org/x/lint - - + + golang.org/x/oauth2 -golang.org/x/oauth2 +golang.org/x/oauth2 cloud.google.com/go->golang.org/x/oauth2 - - + + cloud.google.com/go->golang.org/x/sync - - + + golang.org/x/text -golang.org/x/text +golang.org/x/text cloud.google.com/go->golang.org/x/text - - + + golang.org/x/time -golang.org/x/time +golang.org/x/time cloud.google.com/go->golang.org/x/time - - + + golang.org/x/tools -golang.org/x/tools +golang.org/x/tools cloud.google.com/go->golang.org/x/tools - - + + google.golang.org/api -google.golang.org/api +google.golang.org/api cloud.google.com/go->google.golang.org/api - - + + google.golang.org/genproto -google.golang.org/genproto +google.golang.org/genproto cloud.google.com/go->google.golang.org/genproto - - + + cloud.google.com/go->google.golang.org/grpc - - + + go.opencensus.io -go.opencensus.io +go.opencensus.io cloud.google.com/go->go.opencensus.io - - + + honnef.co/go/tools -honnef.co/go/tools +honnef.co/go/tools cloud.google.com/go->honnef.co/go/tools - - + + github.com/googleapis/\ngax-go/v2->google.golang.org/grpc - - + + golang.org/x/exp->golang.org/x/tools - - + + golang.org/x/sys -golang.org/x/sys +golang.org/x/sys golang.org/x/exp->golang.org/x/sys - - + + github.com/BurntSushi/\nxgb -github.com/BurntSushi/ -xgb +github.com/BurntSushi/ +xgb golang.org/x/exp->github.com/BurntSushi/\nxgb - - + + golang.org/x/image -golang.org/x/image +golang.org/x/image golang.org/x/exp->golang.org/x/image - - + + golang.org/x/mobile -golang.org/x/mobile +golang.org/x/mobile golang.org/x/exp->golang.org/x/mobile - - + + golang.org/x/lint->golang.org/x/tools - - + + golang.org/x/oauth2->cloud.google.com/go - - + + golang.org/x/oauth2->golang.org/x/sync - - + + golang.org/x/net -golang.org/x/net +golang.org/x/net golang.org/x/oauth2->golang.org/x/net - - + + google.golang.org/appengine -google.golang.org/appengine +google.golang.org/appengine golang.org/x/oauth2->google.golang.org/appengine - - + + golang.org/x/text->golang.org/x/tools - - + + golang.org/x/tools->golang.org/x/sync - - + + golang.org/x/tools->golang.org/x/net - - + + golang.org/x/tools->google.golang.org/appengine - - + + google.golang.org/api->github.com/google/\ngo-cmp - - + + google.golang.org/api->golang.org/x/lint - - + + google.golang.org/api->golang.org/x/oauth2 - - + + google.golang.org/api->golang.org/x/sync - - + + google.golang.org/api->golang.org/x/tools - - + + google.golang.org/api->google.golang.org/genproto - - + + google.golang.org/api->google.golang.org/grpc - - + + google.golang.org/api->go.opencensus.io - - + + google.golang.org/api->honnef.co/go/tools - - + + google.golang.org/api->google.golang.org/appengine - - + + google.golang.org/genproto->github.com/golang/\nprotobuf - - + + google.golang.org/genproto->golang.org/x/exp - - + + google.golang.org/genproto->golang.org/x/lint - - + + google.golang.org/genproto->golang.org/x/sync - - + + google.golang.org/genproto->golang.org/x/tools - - + + google.golang.org/genproto->google.golang.org/grpc - - + + google.golang.org/genproto->honnef.co/go/tools - - + + google.golang.org/genproto->golang.org/x/net - - + + google.golang.org/grpc->cloud.google.com/go - - + + google.golang.org/grpc->github.com/golang/\nmock - - + + google.golang.org/grpc->github.com/golang/\nprotobuf - - + + google.golang.org/grpc->github.com/google/\ngo-cmp - - + + google.golang.org/grpc->golang.org/x/lint - - + + google.golang.org/grpc->golang.org/x/oauth2 - - + + google.golang.org/grpc->golang.org/x/sync - - + + google.golang.org/grpc->golang.org/x/text - - + + google.golang.org/grpc->golang.org/x/tools - - + + google.golang.org/grpc->google.golang.org/genproto - - + + google.golang.org/grpc->honnef.co/go/tools - - + + google.golang.org/grpc->golang.org/x/net - - + + github.com/gogo/\ngoogleapis -github.com/gogo/ -googleapis +github.com/gogo/ +googleapis google.golang.org/grpc->github.com/gogo/\ngoogleapis - - + + github.com/gogo/\nprotobuf -github.com/gogo/ -protobuf +github.com/gogo/ +protobuf google.golang.org/grpc->github.com/gogo/\nprotobuf - - + + google.golang.org/grpc->golang.org/x/sys - - + + github.com/golang/\nglog -github.com/golang/ -glog +github.com/golang/ +glog google.golang.org/grpc->github.com/golang/\nglog - - + + github.com/kisielk/\ngotool -github.com/kisielk/ -gotool +github.com/kisielk/ +gotool google.golang.org/grpc->github.com/kisielk/\ngotool - - + + github.com/BurntSushi/\ntoml -github.com/BurntSushi/ -toml +github.com/BurntSushi/ +toml google.golang.org/grpc->github.com/BurntSushi/\ntoml - - + + google.golang.org/grpc->google.golang.org/appengine - - + + github.com/client9/\nmisspell -github.com/client9/ -misspell +github.com/client9/ +misspell google.golang.org/grpc->github.com/client9/\nmisspell - - + + github.com/envoyproxy/\ngo-control-plane -github.com/envoyproxy/ -go-control-plane +github.com/envoyproxy/ +go-control-plane google.golang.org/grpc->github.com/envoyproxy/\ngo-control-plane - - + + github.com/lyft/\nprotoc-gen-validate -github.com/lyft/ -protoc-gen-validate +github.com/lyft/ +protoc-gen-validate google.golang.org/grpc->github.com/lyft/\nprotoc-gen-validate - - + + go.opencensus.io->github.com/golang/\nprotobuf - - + + go.opencensus.io->github.com/google/\ngo-cmp - - + + go.opencensus.io->google.golang.org/api - - + + go.opencensus.io->google.golang.org/grpc - - + + go.opencensus.io->golang.org/x/net - - + + github.com/openzipkin/\nzipkin-go -github.com/openzipkin/ -zipkin-go +github.com/openzipkin/ +zipkin-go go.opencensus.io->github.com/openzipkin/\nzipkin-go - - + + go.opencensus.io->github.com/prometheus/\nclient_golang - - + + github.com/hashicorp/\ngolang-lru -github.com/hashicorp/ -golang-lru +github.com/hashicorp/ +golang-lru go.opencensus.io->github.com/hashicorp/\ngolang-lru - - + + github.com/apache/\nthrift -github.com/apache/ -thrift +github.com/apache/ +thrift go.opencensus.io->github.com/apache/\nthrift - - + + contrib.go.opencensus.io/exporter/ocagent -contrib.go.opencensus.io/exporter/ocagent +contrib.go.opencensus.io/exporter/ocagent contrib.go.opencensus.io/exporter/ocagent->github.com/golang/\nprotobuf - - + + contrib.go.opencensus.io/exporter/ocagent->google.golang.org/api - - + + contrib.go.opencensus.io/exporter/ocagent->google.golang.org/grpc - - + + contrib.go.opencensus.io/exporter/ocagent->go.opencensus.io - - + + github.com/census-instrumentation/\nopencensus-proto -github.com/census-instrumentation/ -opencensus-proto +github.com/census-instrumentation/ +opencensus-proto contrib.go.opencensus.io/exporter/ocagent->github.com/census-instrumentation/\nopencensus-proto - - + + github.com/grpc-ecosystem/\ngrpc-gateway -github.com/grpc-ecosystem/ -grpc-gateway +github.com/grpc-ecosystem/ +grpc-gateway contrib.go.opencensus.io/exporter/ocagent->github.com/grpc-ecosystem/\ngrpc-gateway - - + + github.com/grpc-ecosystem/\ngrpc-gateway->github.com/golang/\nprotobuf - - + + github.com/grpc-ecosystem/\ngrpc-gateway->google.golang.org/genproto - - + + github.com/grpc-ecosystem/\ngrpc-gateway->google.golang.org/grpc - - + + github.com/grpc-ecosystem/\ngrpc-gateway->golang.org/x/net - - + + gopkg.in/yaml.v2 -gopkg.in/yaml.v2 +gopkg.in/yaml.v2 github.com/grpc-ecosystem/\ngrpc-gateway->gopkg.in/yaml.v2 - - + + github.com/grpc-ecosystem/\ngrpc-gateway->golang.org/x/sys - - + + github.com/ghodss/\nyaml -github.com/ghodss/ -yaml +github.com/ghodss/ +yaml github.com/grpc-ecosystem/\ngrpc-gateway->github.com/ghodss/\nyaml - - + + github.com/grpc-ecosystem/\ngrpc-gateway->github.com/golang/\nglog - - + + github.com/kr/\npretty -github.com/kr/ -pretty +github.com/kr/ +pretty github.com/grpc-ecosystem/\ngrpc-gateway->github.com/kr/\npretty - - + + github.com/rogpeppe/\nfastuuid -github.com/rogpeppe/ -fastuuid +github.com/rogpeppe/ +fastuuid github.com/grpc-ecosystem/\ngrpc-gateway->github.com/rogpeppe/\nfastuuid - - + + gopkg.in/check.v1 -gopkg.in/check.v1 +gopkg.in/check.v1 github.com/grpc-ecosystem/\ngrpc-gateway->gopkg.in/check.v1 - - + + gopkg.in/resty.v1 -gopkg.in/resty.v1 +gopkg.in/resty.v1 github.com/grpc-ecosystem/\ngrpc-gateway->gopkg.in/resty.v1 - - + + github.com/aws/\naws-sdk-go -github.com/aws/ -aws-sdk-go +github.com/aws/ +aws-sdk-go github.com/jmespath/\ngo-jmespath -github.com/jmespath/ -go-jmespath +github.com/jmespath/ +go-jmespath github.com/aws/\naws-sdk-go->github.com/jmespath/\ngo-jmespath - - + + github.com/cpuguy83/\ngo-md2man -github.com/cpuguy83/ -go-md2man +github.com/cpuguy83/ +go-md2man github.com/russross/\nblackfriday -github.com/russross/ -blackfriday +github.com/russross/ +blackfriday github.com/cpuguy83/\ngo-md2man->github.com/russross/\nblackfriday - - + + github.com/elazarl/\ngoproxy/ext -github.com/elazarl/ -goproxy/ext +github.com/elazarl/ +goproxy/ext github.com/rogpeppe/\ngo-charset -github.com/rogpeppe/ -go-charset +github.com/rogpeppe/ +go-charset github.com/elazarl/\ngoproxy/ext->github.com/rogpeppe/\ngo-charset - - + + github.com/go-openapi/\nerrors -github.com/go-openapi/ -errors +github.com/go-openapi/ +errors github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/go-openapi/\nerrors - - + + github.com/go-openapi/\nruntime -github.com/go-openapi/ -runtime +github.com/go-openapi/ +runtime github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/go-openapi/\nruntime - - + + github.com/go-openapi/\nstrfmt -github.com/go-openapi/ -strfmt +github.com/go-openapi/ +strfmt github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/go-openapi/\nstrfmt - - + + github.com/go-openapi/\nswag -github.com/go-openapi/ -swag +github.com/go-openapi/ +swag github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nvalidate -github.com/go-openapi/ -validate +github.com/go-openapi/ +validate github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/go-openapi/\nvalidate - - + + github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/sirupsen/\nlogrus - - + + github.com/stretchr/\ntestify -github.com/stretchr/ -testify +github.com/stretchr/ +testify github.com/firecracker-microvm/\nfirecracker-go-sdk->github.com/stretchr/\ntestify - - + + github.com/firecracker-microvm/\nfirecracker-go-sdk->golang.org/x/net - - + + github.com/go-openapi/\nerrors->github.com/stretchr/\ntestify - - + + github.com/davecgh/\ngo-spew -github.com/davecgh/ -go-spew +github.com/davecgh/ +go-spew github.com/go-openapi/\nerrors->github.com/davecgh/\ngo-spew - - + + github.com/pmezard/\ngo-difflib -github.com/pmezard/ -go-difflib +github.com/pmezard/ +go-difflib github.com/go-openapi/\nerrors->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\nruntime->github.com/go-openapi/\nerrors - - + + github.com/go-openapi/\nruntime->github.com/go-openapi/\nstrfmt - - + + github.com/go-openapi/\nruntime->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nruntime->github.com/go-openapi/\nvalidate - - + + github.com/go-openapi/\nruntime->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nanalysis -github.com/go-openapi/ -analysis +github.com/go-openapi/ +analysis github.com/go-openapi/\nruntime->github.com/go-openapi/\nanalysis - - + + github.com/go-openapi/\nloads -github.com/go-openapi/ -loads +github.com/go-openapi/ +loads github.com/go-openapi/\nruntime->github.com/go-openapi/\nloads - - + + github.com/go-openapi/\nruntime->github.com/go-openapi/\nspec - - + + github.com/go-openapi/\nruntime->gopkg.in/yaml.v2 - - + + github.com/docker/\ngo-units -github.com/docker/ -go-units +github.com/docker/ +go-units github.com/go-openapi/\nruntime->github.com/docker/\ngo-units - - + + github.com/go-openapi/\nstrfmt->github.com/go-openapi/\nerrors - - + + github.com/go-openapi/\nstrfmt->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nstrfmt->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\nstrfmt->github.com/pmezard/\ngo-difflib - - + + github.com/mailru/\neasyjson -github.com/mailru/ -easyjson +github.com/mailru/ +easyjson github.com/go-openapi/\nstrfmt->github.com/mailru/\neasyjson - - + + github.com/asaskevich/\ngovalidator -github.com/asaskevich/ -govalidator +github.com/asaskevich/ +govalidator github.com/go-openapi/\nstrfmt->github.com/asaskevich/\ngovalidator - - + + github.com/globalsign/\nmgo -github.com/globalsign/ -mgo +github.com/globalsign/ +mgo github.com/go-openapi/\nstrfmt->github.com/globalsign/\nmgo - - + + github.com/mitchellh/\nmapstructure -github.com/mitchellh/ -mapstructure +github.com/mitchellh/ +mapstructure github.com/go-openapi/\nstrfmt->github.com/mitchellh/\nmapstructure - - + + github.com/pborman/\nuuid -github.com/pborman/ -uuid +github.com/pborman/ +uuid github.com/go-openapi/\nstrfmt->github.com/pborman/\nuuid - - + + github.com/go-openapi/\nswag->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nswag->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\nswag->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\nswag->github.com/mailru/\neasyjson - - + + github.com/go-openapi/\nswag->gopkg.in/yaml.v2 - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nerrors - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nruntime - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nstrfmt - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nvalidate->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nanalysis - - + + github.com/go-openapi/\njsonpointer -github.com/go-openapi/ -jsonpointer +github.com/go-openapi/ +jsonpointer github.com/go-openapi/\nvalidate->github.com/go-openapi/\njsonpointer - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nloads - - + + github.com/go-openapi/\nvalidate->github.com/go-openapi/\nspec - - + + github.com/go-openapi/\nvalidate->gopkg.in/yaml.v2 - - + + github.com/sirupsen/\nlogrus->github.com/stretchr/\ntestify - - + + github.com/sirupsen/\nlogrus->github.com/davecgh/\ngo-spew - - + + github.com/sirupsen/\nlogrus->github.com/pmezard/\ngo-difflib - - + + golang.org/x/crypto -golang.org/x/crypto +golang.org/x/crypto github.com/sirupsen/\nlogrus->golang.org/x/crypto - - + + github.com/sirupsen/\nlogrus->golang.org/x/sys - - + + github.com/konsorten/\ngo-windows-terminal-sequences -github.com/konsorten/ -go-windows-terminal-sequences +github.com/konsorten/ +go-windows-terminal-sequences github.com/sirupsen/\nlogrus->github.com/konsorten/\ngo-windows-terminal-sequences - - + + github.com/stretchr/\nobjx -github.com/stretchr/ -objx +github.com/stretchr/ +objx github.com/sirupsen/\nlogrus->github.com/stretchr/\nobjx - - + + github.com/stretchr/\ntestify->github.com/davecgh/\ngo-spew - - + + github.com/stretchr/\ntestify->github.com/pmezard/\ngo-difflib - - + + github.com/stretchr/\ntestify->github.com/stretchr/\nobjx - - + + golang.org/x/net->golang.org/x/text - - + + golang.org/x/net->golang.org/x/crypto - - + + github.com/gogo/\ngoogleapis->github.com/gogo/\nprotobuf - - + + github.com/kisielk/\nerrcheck -github.com/kisielk/ -errcheck +github.com/kisielk/ +errcheck github.com/gogo/\nprotobuf->github.com/kisielk/\nerrcheck - - + + github.com/kisielk/\nerrcheck->golang.org/x/tools - - + + github.com/kisielk/\nerrcheck->github.com/kisielk/\ngotool - - + + github.com/gogo/\nstatus -github.com/gogo/ -status +github.com/gogo/ +status github.com/gogo/\nstatus->github.com/golang/\nprotobuf - - + + github.com/gogo/\nstatus->golang.org/x/sync - - + + github.com/gogo/\nstatus->google.golang.org/genproto - - + + github.com/gogo/\nstatus->google.golang.org/grpc - - + + github.com/gogo/\nstatus->github.com/gogo/\ngoogleapis - - + + github.com/gogo/\nstatus->github.com/gogo/\nprotobuf - - + + github.com/go-logfmt/\nlogfmt -github.com/go-logfmt/ -logfmt +github.com/go-logfmt/ +logfmt github.com/kr/\nlogfmt -github.com/kr/ -logfmt +github.com/kr/ +logfmt github.com/go-logfmt/\nlogfmt->github.com/kr/\nlogfmt - - + + github.com/go-openapi/\nanalysis->github.com/go-openapi/\nstrfmt - - + + github.com/go-openapi/\nanalysis->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nanalysis->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nanalysis->github.com/go-openapi/\njsonpointer - - + + github.com/go-openapi/\nanalysis->github.com/go-openapi/\nloads - - + + github.com/go-openapi/\nanalysis->github.com/go-openapi/\nspec - - + + github.com/go-openapi/\njsonpointer->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\njsonpointer->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\njsonpointer->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\njsonpointer->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\njsonpointer->github.com/mailru/\neasyjson - - + + github.com/go-openapi/\njsonpointer->gopkg.in/yaml.v2 - - + + github.com/go-openapi/\nloads->golang.org/x/text - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\nerrors - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\nstrfmt - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nloads->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nloads->golang.org/x/net - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\nanalysis - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\njsonpointer - - + + github.com/go-openapi/\nloads->github.com/go-openapi/\nspec - - + + github.com/go-openapi/\nloads->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\nloads->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\nloads->github.com/mailru/\neasyjson - - + + github.com/go-openapi/\nloads->gopkg.in/yaml.v2 - - + + github.com/go-openapi/\njsonreference -github.com/go-openapi/ -jsonreference +github.com/go-openapi/ +jsonreference github.com/go-openapi/\nloads->github.com/go-openapi/\njsonreference - - + + github.com/PuerkitoBio/\npurell -github.com/PuerkitoBio/ -purell +github.com/PuerkitoBio/ +purell github.com/go-openapi/\nloads->github.com/PuerkitoBio/\npurell - - + + github.com/PuerkitoBio/\nurlesc -github.com/PuerkitoBio/ -urlesc +github.com/PuerkitoBio/ +urlesc github.com/go-openapi/\nloads->github.com/PuerkitoBio/\nurlesc - - + + github.com/go-openapi/\nloads->github.com/asaskevich/\ngovalidator - - + + github.com/go-openapi/\nloads->github.com/globalsign/\nmgo - - + + github.com/go-openapi/\nloads->github.com/mitchellh/\nmapstructure - - + + github.com/go-openapi/\nspec->golang.org/x/text - - + + github.com/go-openapi/\nspec->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\nspec->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\nspec->golang.org/x/net - - + + github.com/go-openapi/\nspec->github.com/go-openapi/\njsonpointer - - + + github.com/go-openapi/\nspec->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\nspec->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\nspec->github.com/mailru/\neasyjson - - + + github.com/go-openapi/\nspec->gopkg.in/yaml.v2 - - + + github.com/go-openapi/\nspec->github.com/go-openapi/\njsonreference - - + + github.com/go-openapi/\nspec->github.com/PuerkitoBio/\npurell - - + + github.com/go-openapi/\nspec->github.com/PuerkitoBio/\nurlesc - - + + gopkg.in/yaml.v2->gopkg.in/check.v1 - - + + github.com/go-openapi/\njsonreference->golang.org/x/text - - + + github.com/go-openapi/\njsonreference->github.com/go-openapi/\nswag - - + + github.com/go-openapi/\njsonreference->github.com/stretchr/\ntestify - - + + github.com/go-openapi/\njsonreference->golang.org/x/net - - + + github.com/go-openapi/\njsonreference->github.com/go-openapi/\njsonpointer - - + + github.com/go-openapi/\njsonreference->github.com/davecgh/\ngo-spew - - + + github.com/go-openapi/\njsonreference->github.com/pmezard/\ngo-difflib - - + + github.com/go-openapi/\njsonreference->github.com/mailru/\neasyjson - - + + github.com/go-openapi/\njsonreference->gopkg.in/yaml.v2 - - + + github.com/go-openapi/\njsonreference->github.com/PuerkitoBio/\npurell - - + + github.com/go-openapi/\njsonreference->github.com/PuerkitoBio/\nurlesc - - + + github.com/google/\nuuid -github.com/google/ -uuid +github.com/google/ +uuid github.com/pborman/\nuuid->github.com/google/\nuuid - - + + github.com/gophercloud/\ngophercloud -github.com/gophercloud/ -gophercloud +github.com/gophercloud/ +gophercloud github.com/gophercloud/\ngophercloud->gopkg.in/yaml.v2 - - + + github.com/gophercloud/\ngophercloud->golang.org/x/crypto - - + + github.com/gophercloud/\ngophercloud->golang.org/x/sys - - + + golang.org/x/crypto->golang.org/x/sys - - + + github.com/kr/\ntext -github.com/kr/ -text +github.com/kr/ +text github.com/kr/\npretty->github.com/kr/\ntext - - + + gopkg.in/resty.v1->golang.org/x/net - - + + github.com/hashicorp/\nhcl -github.com/hashicorp/ -hcl +github.com/hashicorp/ +hcl github.com/hashicorp/\nhcl->github.com/davecgh/\ngo-spew - - + + github.com/justinbarrick/\ngo-k8s-portforward -github.com/justinbarrick/ -go-k8s-portforward +github.com/justinbarrick/ +go-k8s-portforward github.com/justinbarrick/\ngo-k8s-portforward->golang.org/x/time - - + + github.com/justinbarrick/\ngo-k8s-portforward->contrib.go.opencensus.io/exporter/ocagent - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/elazarl/\ngoproxy/ext - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/stretchr/\ntestify - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/gophercloud/\ngophercloud - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/justinbarrick/\ngo-k8s-portforward - - + + github.com/Azure/\ngo-autorest -github.com/Azure/ -go-autorest +github.com/Azure/ +go-autorest github.com/justinbarrick/\ngo-k8s-portforward->github.com/Azure/\ngo-autorest - - + + github.com/dgrijalva/\njwt-go -github.com/dgrijalva/ -jwt-go +github.com/dgrijalva/ +jwt-go github.com/justinbarrick/\ngo-k8s-portforward->github.com/dgrijalva/\njwt-go - - + + github.com/docker/\nspdystream -github.com/docker/ -spdystream +github.com/docker/ +spdystream github.com/justinbarrick/\ngo-k8s-portforward->github.com/docker/\nspdystream - - + + github.com/elazarl/\ngoproxy -github.com/elazarl/ -goproxy +github.com/elazarl/ +goproxy github.com/justinbarrick/\ngo-k8s-portforward->github.com/elazarl/\ngoproxy - - + + github.com/evanphx/\njson-patch -github.com/evanphx/ -json-patch +github.com/evanphx/ +json-patch github.com/justinbarrick/\ngo-k8s-portforward->github.com/evanphx/\njson-patch - - + + github.com/googleapis/\ngnostic -github.com/googleapis/ -gnostic +github.com/googleapis/ +gnostic github.com/justinbarrick/\ngo-k8s-portforward->github.com/googleapis/\ngnostic - - + + github.com/google/\ngofuzz -github.com/google/ -gofuzz +github.com/google/ +gofuzz github.com/justinbarrick/\ngo-k8s-portforward->github.com/google/\ngofuzz - - + + github.com/imdario/\nmergo -github.com/imdario/ -mergo +github.com/imdario/ +mergo github.com/justinbarrick/\ngo-k8s-portforward->github.com/imdario/\nmergo - - + + github.com/json-iterator/\ngo -github.com/json-iterator/ -go +github.com/json-iterator/ +go github.com/justinbarrick/\ngo-k8s-portforward->github.com/json-iterator/\ngo - - + + github.com/modern-go/\nconcurrent -github.com/modern-go/ -concurrent +github.com/modern-go/ +concurrent github.com/justinbarrick/\ngo-k8s-portforward->github.com/modern-go/\nconcurrent - - + + github.com/modern-go/\nreflect2 -github.com/modern-go/ -reflect2 +github.com/modern-go/ +reflect2 github.com/justinbarrick/\ngo-k8s-portforward->github.com/modern-go/\nreflect2 - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/pkg/\nerrors - - + + github.com/justinbarrick/\ngo-k8s-portforward->github.com/spf13/\npflag - - + + gopkg.in/inf.v0 -gopkg.in/inf.v0 +gopkg.in/inf.v0 github.com/justinbarrick/\ngo-k8s-portforward->gopkg.in/inf.v0 - - + + k8s.io/api -k8s.io/api +k8s.io/api github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/api - - + + github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/apimachinery - - + + k8s.io/client-go -k8s.io/client-go +k8s.io/client-go github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/client-go - - + + k8s.io/klog -k8s.io/klog +k8s.io/klog github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/klog - - + + github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/kube-openapi - - + + k8s.io/utils -k8s.io/utils +k8s.io/utils github.com/justinbarrick/\ngo-k8s-portforward->k8s.io/utils - - + + github.com/justinbarrick/\ngo-k8s-portforward->sigs.k8s.io/yaml - - + + k8s.io/apimachinery->github.com/golang/\nprotobuf - - + + k8s.io/apimachinery->github.com/google/\ngo-cmp - - + + k8s.io/apimachinery->golang.org/x/sync - - + + k8s.io/apimachinery->golang.org/x/text - - + + k8s.io/apimachinery->github.com/stretchr/\ntestify - - + + k8s.io/apimachinery->golang.org/x/net - - + + k8s.io/apimachinery->github.com/gogo/\nprotobuf - - + + k8s.io/apimachinery->github.com/davecgh/\ngo-spew - - + + k8s.io/apimachinery->github.com/pmezard/\ngo-difflib - - + + k8s.io/apimachinery->gopkg.in/yaml.v2 - - + + k8s.io/apimachinery->golang.org/x/sys - - + + k8s.io/apimachinery->github.com/docker/\nspdystream - - + + k8s.io/apimachinery->github.com/elazarl/\ngoproxy - - + + k8s.io/apimachinery->github.com/evanphx/\njson-patch - - + + k8s.io/apimachinery->github.com/googleapis/\ngnostic - - + + k8s.io/apimachinery->github.com/google/\ngofuzz - - + + k8s.io/apimachinery->github.com/json-iterator/\ngo - - + + k8s.io/apimachinery->github.com/modern-go/\nconcurrent - - + + k8s.io/apimachinery->github.com/modern-go/\nreflect2 - - + + k8s.io/apimachinery->github.com/spf13/\npflag - - + + k8s.io/apimachinery->gopkg.in/inf.v0 - - + + k8s.io/apimachinery->k8s.io/klog - - + + k8s.io/apimachinery->k8s.io/kube-openapi - - + + k8s.io/apimachinery->sigs.k8s.io/yaml - - + + github.com/onsi/\ngomega -github.com/onsi/ -gomega +github.com/onsi/ +gomega k8s.io/apimachinery->github.com/onsi/\ngomega - - + + k8s.io/apimachinery->github.com/google/\nuuid - - + + github.com/golang/\ngroupcache -github.com/golang/ -groupcache +github.com/golang/ +groupcache k8s.io/apimachinery->github.com/golang/\ngroupcache - - + + k8s.io/apimachinery->github.com/hashicorp/\ngolang-lru - - + + github.com/mxk/\ngo-flowrate -github.com/mxk/ -go-flowrate +github.com/mxk/ +go-flowrate k8s.io/apimachinery->github.com/mxk/\ngo-flowrate - - + + github.com/kr/\npty -github.com/kr/ -pty +github.com/kr/ +pty github.com/kr/\ntext->github.com/kr/\npty - - + + github.com/onsi/\ngomega->github.com/golang/\nprotobuf - - + + github.com/onsi/\ngomega->golang.org/x/sync - - + + github.com/onsi/\ngomega->golang.org/x/text - - + + github.com/onsi/\ngomega->golang.org/x/net - - + + github.com/onsi/\ngomega->gopkg.in/yaml.v2 - - + + github.com/onsi/\ngomega->golang.org/x/sys - - + + github.com/fsnotify/\nfsnotify -github.com/fsnotify/ -fsnotify +github.com/fsnotify/ +fsnotify github.com/onsi/\ngomega->github.com/fsnotify/\nfsnotify - - + + github.com/hpcloud/\ntail -github.com/hpcloud/ -tail +github.com/hpcloud/ +tail github.com/onsi/\ngomega->github.com/hpcloud/\ntail - - + + github.com/onsi/\nginkgo -github.com/onsi/ -ginkgo +github.com/onsi/ +ginkgo github.com/onsi/\ngomega->github.com/onsi/\nginkgo - - + + gopkg.in/fsnotify.v1 -gopkg.in/fsnotify.v1 +gopkg.in/fsnotify.v1 github.com/onsi/\ngomega->gopkg.in/fsnotify.v1 - - + + gopkg.in/tomb.v1 -gopkg.in/tomb.v1 +gopkg.in/tomb.v1 github.com/onsi/\ngomega->gopkg.in/tomb.v1 - - + + github.com/openzipkin/\nzipkin-go->github.com/golang/\nprotobuf - - + + github.com/openzipkin/\nzipkin-go->golang.org/x/sync - - + + github.com/openzipkin/\nzipkin-go->google.golang.org/grpc - - + + github.com/openzipkin/\nzipkin-go->golang.org/x/net - - + + github.com/openzipkin/\nzipkin-go->github.com/gogo/\nprotobuf - - + + github.com/openzipkin/\nzipkin-go->github.com/davecgh/\ngo-spew - - + + github.com/openzipkin/\nzipkin-go->golang.org/x/sys - - + + github.com/openzipkin/\nzipkin-go->github.com/onsi/\ngomega - - + + github.com/openzipkin/\nzipkin-go->github.com/onsi/\nginkgo - - + + github.com/eapache/\ngo-resiliency -github.com/eapache/ -go-resiliency +github.com/eapache/ +go-resiliency github.com/openzipkin/\nzipkin-go->github.com/eapache/\ngo-resiliency - - + + github.com/eapache/\ngo-xerial-snappy -github.com/eapache/ -go-xerial-snappy +github.com/eapache/ +go-xerial-snappy github.com/openzipkin/\nzipkin-go->github.com/eapache/\ngo-xerial-snappy - - + + github.com/eapache/\nqueue -github.com/eapache/ -queue +github.com/eapache/ +queue github.com/openzipkin/\nzipkin-go->github.com/eapache/\nqueue - - + + github.com/golang/\nsnappy -github.com/golang/ -snappy +github.com/golang/ +snappy github.com/openzipkin/\nzipkin-go->github.com/golang/\nsnappy - - + + github.com/gorilla/\ncontext -github.com/gorilla/ -context +github.com/gorilla/ +context github.com/openzipkin/\nzipkin-go->github.com/gorilla/\ncontext - - + + github.com/openzipkin/\nzipkin-go->github.com/gorilla/\nmux - - + + github.com/pierrec/\nlz4 -github.com/pierrec/ -lz4 +github.com/pierrec/ +lz4 github.com/openzipkin/\nzipkin-go->github.com/pierrec/\nlz4 - - + + github.com/rcrowley/\ngo-metrics -github.com/rcrowley/ -go-metrics +github.com/rcrowley/ +go-metrics github.com/openzipkin/\nzipkin-go->github.com/rcrowley/\ngo-metrics - - + + github.com/Shopify/\nsarama -github.com/Shopify/ -sarama +github.com/Shopify/ +sarama github.com/openzipkin/\nzipkin-go->github.com/Shopify/\nsarama - - + + github.com/Shopify/\ntoxiproxy -github.com/Shopify/ -toxiproxy +github.com/Shopify/ +toxiproxy github.com/openzipkin/\nzipkin-go->github.com/Shopify/\ntoxiproxy - - + + github.com/prometheus/\nclient_golang->github.com/golang/\nprotobuf - - + + github.com/prometheus/\nclient_golang->golang.org/x/sync - - + + github.com/prometheus/\nclient_golang->github.com/stretchr/\ntestify - - + + github.com/prometheus/\nclient_golang->golang.org/x/net - - + + github.com/prometheus/\nclient_golang->golang.org/x/sys - - + + github.com/prometheus/\nclient_golang->github.com/json-iterator/\ngo - - + + github.com/prometheus/\nclient_golang->github.com/modern-go/\nconcurrent - - + + github.com/prometheus/\nclient_golang->github.com/modern-go/\nreflect2 - - + + github.com/beorn7/\nperks -github.com/beorn7/ -perks +github.com/beorn7/ +perks github.com/prometheus/\nclient_golang->github.com/beorn7/\nperks - - + + github.com/prometheus/\nclient_model -github.com/prometheus/ -client_model +github.com/prometheus/ +client_model github.com/prometheus/\nclient_golang->github.com/prometheus/\nclient_model - - + + github.com/prometheus/\ncommon -github.com/prometheus/ -common +github.com/prometheus/ +common github.com/prometheus/\nclient_golang->github.com/prometheus/\ncommon - - + + github.com/prometheus/\nprocfs -github.com/prometheus/ -procfs +github.com/prometheus/ +procfs github.com/prometheus/\nclient_golang->github.com/prometheus/\nprocfs - - + + github.com/prometheus/\nclient_model->github.com/golang/\nprotobuf - - + + github.com/prometheus/\nclient_model->golang.org/x/sync - - + + github.com/prometheus/\ncommon->github.com/golang/\nprotobuf - - + + github.com/prometheus/\ncommon->golang.org/x/sync - - + + github.com/prometheus/\ncommon->github.com/sirupsen/\nlogrus - - + + github.com/prometheus/\ncommon->golang.org/x/net - - + + github.com/prometheus/\ncommon->github.com/gogo/\nprotobuf - - + + github.com/prometheus/\ncommon->github.com/go-logfmt/\nlogfmt - - + + github.com/prometheus/\ncommon->github.com/kr/\nlogfmt - - + + github.com/prometheus/\ncommon->gopkg.in/yaml.v2 - - + + github.com/prometheus/\ncommon->golang.org/x/sys - - + + github.com/prometheus/\ncommon->github.com/pkg/\nerrors - - + + github.com/prometheus/\ncommon->github.com/prometheus/\nclient_golang - - + + github.com/prometheus/\ncommon->github.com/beorn7/\nperks - - + + github.com/prometheus/\ncommon->github.com/prometheus/\nclient_model - - + + github.com/prometheus/\ncommon->github.com/prometheus/\nprocfs - - + + github.com/alecthomas/\ntemplate -github.com/alecthomas/ -template +github.com/alecthomas/ +template github.com/prometheus/\ncommon->github.com/alecthomas/\ntemplate - - + + github.com/alecthomas/\nunits -github.com/alecthomas/ -units +github.com/alecthomas/ +units github.com/prometheus/\ncommon->github.com/alecthomas/\nunits - - + + github.com/go-kit/\nkit -github.com/go-kit/ -kit +github.com/go-kit/ +kit github.com/prometheus/\ncommon->github.com/go-kit/\nkit - - + + github.com/go-stack/\nstack -github.com/go-stack/ -stack +github.com/go-stack/ +stack github.com/prometheus/\ncommon->github.com/go-stack/\nstack - - + + github.com/julienschmidt/\nhttprouter -github.com/julienschmidt/ -httprouter +github.com/julienschmidt/ +httprouter github.com/prometheus/\ncommon->github.com/julienschmidt/\nhttprouter - - + + github.com/matttproud/\ngolang_protobuf_extensions -github.com/matttproud/ -golang_protobuf_extensions +github.com/matttproud/ +golang_protobuf_extensions github.com/prometheus/\ncommon->github.com/matttproud/\ngolang_protobuf_extensions - - + + github.com/mwitkow/\ngo-conntrack -github.com/mwitkow/ -go-conntrack +github.com/mwitkow/ +go-conntrack github.com/prometheus/\ncommon->github.com/mwitkow/\ngo-conntrack - - + + gopkg.in/alecthomas/kingpin.v2 -gopkg.in/alecthomas/kingpin.v2 +gopkg.in/alecthomas/kingpin.v2 github.com/prometheus/\ncommon->gopkg.in/alecthomas/kingpin.v2 - - + + github.com/prometheus/\nprocfs->golang.org/x/sync - - + + github.com/spf13/\ncast -github.com/spf13/ -cast +github.com/spf13/ +cast github.com/spf13/\ncast->github.com/stretchr/\ntestify - - + + github.com/spf13/\ncast->github.com/davecgh/\ngo-spew - - + + github.com/spf13/\ncast->github.com/pmezard/\ngo-difflib - - + + github.com/spf13/\ncobra->github.com/cpuguy83/\ngo-md2man - - + + github.com/spf13/\ncobra->gopkg.in/yaml.v2 - - + + github.com/spf13/\ncobra->github.com/spf13/\npflag - - + + github.com/spf13/\ncobra->github.com/BurntSushi/\ntoml - - + + github.com/inconshreveable/\nmousetrap -github.com/inconshreveable/ -mousetrap +github.com/inconshreveable/ +mousetrap github.com/spf13/\ncobra->github.com/inconshreveable/\nmousetrap - - + + github.com/mitchellh/\ngo-homedir -github.com/mitchellh/ -go-homedir +github.com/mitchellh/ +go-homedir github.com/spf13/\ncobra->github.com/mitchellh/\ngo-homedir - - + + github.com/spf13/\nviper -github.com/spf13/ -viper +github.com/spf13/ +viper github.com/spf13/\ncobra->github.com/spf13/\nviper - - + + github.com/spf13/\nviper->golang.org/x/text - - + + github.com/spf13/\nviper->github.com/stretchr/\ntestify - - + + github.com/spf13/\nviper->gopkg.in/yaml.v2 - - + + github.com/spf13/\nviper->github.com/mitchellh/\nmapstructure - - + + github.com/spf13/\nviper->golang.org/x/crypto - - + + github.com/spf13/\nviper->golang.org/x/sys - - + + github.com/spf13/\nviper->github.com/hashicorp/\nhcl - - + + github.com/spf13/\nviper->github.com/spf13/\npflag - - + + github.com/spf13/\nviper->github.com/fsnotify/\nfsnotify - - + + github.com/spf13/\nviper->github.com/spf13/\ncast - - + + github.com/armon/\nconsul-api -github.com/armon/ -consul-api +github.com/armon/ +consul-api github.com/spf13/\nviper->github.com/armon/\nconsul-api - - + + github.com/coreos/\netcd -github.com/coreos/ -etcd +github.com/coreos/ +etcd github.com/spf13/\nviper->github.com/coreos/\netcd - - + + github.com/coreos/\ngo-etcd -github.com/coreos/ -go-etcd +github.com/coreos/ +go-etcd github.com/spf13/\nviper->github.com/coreos/\ngo-etcd - - + + github.com/coreos/\ngo-semver -github.com/coreos/ -go-semver +github.com/coreos/ +go-semver github.com/spf13/\nviper->github.com/coreos/\ngo-semver - - + + github.com/magiconair/\nproperties -github.com/magiconair/ -properties +github.com/magiconair/ +properties github.com/spf13/\nviper->github.com/magiconair/\nproperties - - + + github.com/pelletier/\ngo-toml -github.com/pelletier/ -go-toml +github.com/pelletier/ +go-toml github.com/spf13/\nviper->github.com/pelletier/\ngo-toml - - + + github.com/spf13/\nafero -github.com/spf13/ -afero +github.com/spf13/ +afero github.com/spf13/\nviper->github.com/spf13/\nafero - - + + github.com/spf13/\njwalterweatherman -github.com/spf13/ -jwalterweatherman +github.com/spf13/ +jwalterweatherman github.com/spf13/\nviper->github.com/spf13/\njwalterweatherman - - + + github.com/ugorji/\ngo/codec -github.com/ugorji/ -go/codec +github.com/ugorji/ +go/codec github.com/spf13/\nviper->github.com/ugorji/\ngo/codec - - + + github.com/xordataexchange/\ncrypt -github.com/xordataexchange/ -crypt +github.com/xordataexchange/ +crypt github.com/spf13/\nviper->github.com/xordataexchange/\ncrypt - - + + github.com/weaveworks/\nflux->cloud.google.com/go - - + + github.com/weaveworks/\nflux->github.com/golang/\nprotobuf - - + + github.com/weaveworks/\nflux->github.com/google/\ngo-cmp - - + + github.com/weaveworks/\nflux->golang.org/x/oauth2 - - + + github.com/weaveworks/\nflux->golang.org/x/time - - + + github.com/weaveworks/\nflux->google.golang.org/api - - + + github.com/weaveworks/\nflux->google.golang.org/grpc - - + + github.com/weaveworks/\nflux->github.com/aws/\naws-sdk-go - - + + github.com/weaveworks/\nflux->github.com/sirupsen/\nlogrus - - + + github.com/weaveworks/\nflux->github.com/stretchr/\ntestify - - + + github.com/weaveworks/\nflux->golang.org/x/net - - + + github.com/weaveworks/\nflux->github.com/gogo/\ngoogleapis - - + + github.com/weaveworks/\nflux->github.com/gogo/\nstatus - - + + github.com/weaveworks/\nflux->github.com/go-logfmt/\nlogfmt - - + + github.com/weaveworks/\nflux->gopkg.in/yaml.v2 - - + + github.com/weaveworks/\nflux->github.com/gophercloud/\ngophercloud - - + + github.com/weaveworks/\nflux->golang.org/x/crypto - - + + github.com/weaveworks/\nflux->golang.org/x/sys - - + + github.com/weaveworks/\nflux->github.com/ghodss/\nyaml - - + + github.com/weaveworks/\nflux->github.com/justinbarrick/\ngo-k8s-portforward - - + + github.com/weaveworks/\nflux->github.com/docker/\nspdystream - - + + github.com/weaveworks/\nflux->github.com/evanphx/\njson-patch - - + + github.com/weaveworks/\nflux->github.com/google/\ngofuzz - - + + github.com/weaveworks/\nflux->github.com/imdario/\nmergo - - + + github.com/weaveworks/\nflux->github.com/pkg/\nerrors - - + + github.com/weaveworks/\nflux->github.com/spf13/\npflag - - + + github.com/weaveworks/\nflux->k8s.io/api - - + + github.com/weaveworks/\nflux->k8s.io/apimachinery - - + + github.com/weaveworks/\nflux->k8s.io/client-go - - + + github.com/weaveworks/\nflux->k8s.io/klog - - + + github.com/weaveworks/\nflux->k8s.io/kube-openapi - - + + github.com/weaveworks/\nflux->github.com/gorilla/\nmux - - + + github.com/weaveworks/\nflux->github.com/google/\nuuid - - + + github.com/weaveworks/\nflux->github.com/prometheus/\nclient_golang - - + + github.com/weaveworks/\nflux->github.com/prometheus/\nclient_model - - + + github.com/weaveworks/\nflux->github.com/prometheus/\ncommon - - + + github.com/weaveworks/\nflux->github.com/prometheus/\nprocfs - - + + github.com/weaveworks/\nflux->github.com/go-kit/\nkit - - + + github.com/weaveworks/\nflux->github.com/konsorten/\ngo-windows-terminal-sequences - - + + github.com/weaveworks/\nflux->github.com/spf13/\ncobra - - + + github.com/weaveworks/\nflux->github.com/inconshreveable/\nmousetrap - - + + github.com/bradfitz/\ngomemcache -github.com/bradfitz/ -gomemcache +github.com/bradfitz/ +gomemcache github.com/weaveworks/\nflux->github.com/bradfitz/\ngomemcache - - + + github.com/codahale/\nhdrhistogram -github.com/codahale/ -hdrhistogram +github.com/codahale/ +hdrhistogram github.com/weaveworks/\nflux->github.com/codahale/\nhdrhistogram - - + + github.com/cyphar/\nfilepath-securejoin -github.com/cyphar/ -filepath-securejoin +github.com/cyphar/ +filepath-securejoin github.com/weaveworks/\nflux->github.com/cyphar/\nfilepath-securejoin - - + + github.com/weaveworks/\nflux->github.com/docker/\ndistribution - - + + github.com/docker/\ngo-metrics -github.com/docker/ -go-metrics +github.com/docker/ +go-metrics github.com/weaveworks/\nflux->github.com/docker/\ngo-metrics - - + + github.com/docker/\nlibtrust -github.com/docker/ -libtrust +github.com/docker/ +libtrust github.com/weaveworks/\nflux->github.com/docker/\nlibtrust - - + + github.com/gobwas/\nglob -github.com/gobwas/ -glob +github.com/gobwas/ +glob github.com/weaveworks/\nflux->github.com/gobwas/\nglob - - + + github.com/golang/\ngddo -github.com/golang/ -gddo +github.com/golang/ +gddo github.com/weaveworks/\nflux->github.com/golang/\ngddo - - + + github.com/weaveworks/\nflux->github.com/golang/\ngroupcache - - + + github.com/gorilla/\nwebsocket -github.com/gorilla/ -websocket +github.com/gorilla/ +websocket github.com/weaveworks/\nflux->github.com/gorilla/\nwebsocket - - + + github.com/hashicorp/\ngo-cleanhttp -github.com/hashicorp/ -go-cleanhttp +github.com/hashicorp/ +go-cleanhttp github.com/weaveworks/\nflux->github.com/hashicorp/\ngo-cleanhttp - - + + github.com/weaveworks/\nflux->github.com/hashicorp/\ngolang-lru - - + + github.com/huandu/\nxstrings -github.com/huandu/ -xstrings +github.com/huandu/ +xstrings github.com/weaveworks/\nflux->github.com/huandu/\nxstrings - - + + github.com/Masterminds/\ngoutils -github.com/Masterminds/ -goutils +github.com/Masterminds/ +goutils github.com/weaveworks/\nflux->github.com/Masterminds/\ngoutils - - + + github.com/Masterminds/\nsemver -github.com/Masterminds/ -semver +github.com/Masterminds/ +semver github.com/weaveworks/\nflux->github.com/Masterminds/\nsemver - - + + github.com/Masterminds/\nsprig -github.com/Masterminds/ -sprig +github.com/Masterminds/ +sprig github.com/weaveworks/\nflux->github.com/Masterminds/\nsprig - - + + github.com/ncabatoff/\ngo-seq -github.com/ncabatoff/ -go-seq +github.com/ncabatoff/ +go-seq github.com/weaveworks/\nflux->github.com/ncabatoff/\ngo-seq - - + + github.com/opencontainers/\ngo-digest -github.com/opencontainers/ -go-digest +github.com/opencontainers/ +go-digest github.com/weaveworks/\nflux->github.com/opencontainers/\ngo-digest - - + + github.com/opencontainers/\nimage-spec -github.com/opencontainers/ -image-spec +github.com/opencontainers/ +image-spec github.com/weaveworks/\nflux->github.com/opencontainers/\nimage-spec - - + + github.com/opentracing-contrib/\ngo-stdlib -github.com/opentracing-contrib/ -go-stdlib +github.com/opentracing-contrib/ +go-stdlib github.com/weaveworks/\nflux->github.com/opentracing-contrib/\ngo-stdlib - - + + github.com/opentracing/\nopentracing-go -github.com/opentracing/ -opentracing-go +github.com/opentracing/ +opentracing-go github.com/weaveworks/\nflux->github.com/opentracing/\nopentracing-go - - + + github.com/pkg/\nterm -github.com/pkg/ -term +github.com/pkg/ +term github.com/weaveworks/\nflux->github.com/pkg/\nterm - - + + github.com/ryanuber/\ngo-glob -github.com/ryanuber/ -go-glob +github.com/ryanuber/ +go-glob github.com/weaveworks/\nflux->github.com/ryanuber/\ngo-glob - - + + github.com/uber/\njaeger-client-go -github.com/uber/ -jaeger-client-go +github.com/uber/ +jaeger-client-go github.com/weaveworks/\nflux->github.com/uber/\njaeger-client-go - - + + github.com/uber/\njaeger-lib -github.com/uber/ -jaeger-lib +github.com/uber/ +jaeger-lib github.com/weaveworks/\nflux->github.com/uber/\njaeger-lib - - + + github.com/VividCortex/\ngohistogram -github.com/VividCortex/ -gohistogram +github.com/VividCortex/ +gohistogram github.com/weaveworks/\nflux->github.com/VividCortex/\ngohistogram - - + + github.com/weaveworks/\ncommon -github.com/weaveworks/ -common +github.com/weaveworks/ +common github.com/weaveworks/\nflux->github.com/weaveworks/\ncommon - - + + github.com/weaveworks/\ngo-checkpoint -github.com/weaveworks/ -go-checkpoint +github.com/weaveworks/ +go-checkpoint github.com/weaveworks/\nflux->github.com/weaveworks/\ngo-checkpoint - - + + github.com/weaveworks/\npromrus -github.com/weaveworks/ -promrus +github.com/weaveworks/ +promrus github.com/weaveworks/\nflux->github.com/weaveworks/\npromrus - - + + github.com/whilp/\ngit-urls -github.com/whilp/ -git-urls +github.com/whilp/ +git-urls github.com/weaveworks/\nflux->github.com/whilp/\ngit-urls - - + + github.com/weaveworks/\nflux->google.golang.org/appengine - - + + k8s.io/apiextensions-apiserver -k8s.io/apiextensions-apiserver +k8s.io/apiextensions-apiserver github.com/weaveworks/\nflux->k8s.io/apiextensions-apiserver - - + + k8s.io/code-generator -k8s.io/code-generator +k8s.io/code-generator github.com/weaveworks/\nflux->k8s.io/code-generator - - + + k8s.io/helm -k8s.io/helm +k8s.io/helm github.com/weaveworks/\nflux->k8s.io/helm - - + + google.golang.org/appengine->github.com/golang/\nprotobuf - - + + google.golang.org/appengine->golang.org/x/text - - + + google.golang.org/appengine->golang.org/x/net - - + + k8s.io/code-generator->golang.org/x/tools - - + + k8s.io/code-generator->github.com/gogo/\nprotobuf - - + + k8s.io/code-generator->github.com/spf13/\npflag - - + + k8s.io/code-generator->k8s.io/klog - - + + gonum.org/v1/gonum -gonum.org/v1/gonum +gonum.org/v1/gonum k8s.io/code-generator->gonum.org/v1/gonum - - + + gonum.org/v1/netlib -gonum.org/v1/netlib +gonum.org/v1/netlib k8s.io/code-generator->gonum.org/v1/netlib - - + + k8s.io/gengo -k8s.io/gengo +k8s.io/gengo k8s.io/code-generator->k8s.io/gengo - - + + golang.org/x/image->golang.org/x/text - - + + gonum.org/v1/gonum->golang.org/x/exp - - + + gonum.org/v1/gonum->golang.org/x/tools - - + + gonum.org/v1/gonum->gonum.org/v1/netlib - - + + gonum.org/v1/netlib->golang.org/x/exp - - + + gonum.org/v1/netlib->gonum.org/v1/gonum - - + + github.com/remyoudompheng/\nbigfft -github.com/remyoudompheng/ -bigfft +github.com/remyoudompheng/ +bigfft gonum.org/v1/netlib->github.com/remyoudompheng/\nbigfft - - + + modernc.org/cc -modernc.org/cc +modernc.org/cc gonum.org/v1/netlib->modernc.org/cc - - + + modernc.org/golex -modernc.org/golex +modernc.org/golex gonum.org/v1/netlib->modernc.org/golex - - + + modernc.org/mathutil -modernc.org/mathutil +modernc.org/mathutil gonum.org/v1/netlib->modernc.org/mathutil - - + + modernc.org/strutil -modernc.org/strutil +modernc.org/strutil gonum.org/v1/netlib->modernc.org/strutil - - + + modernc.org/xc -modernc.org/xc +modernc.org/xc gonum.org/v1/netlib->modernc.org/xc - - + + diff --git a/go.mod b/go.mod index 952ea3254..8ee1f156b 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/containers/image v2.0.0+incompatible github.com/docker/distribution v2.7.1+incompatible // indirect github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 - github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-connections v0.4.0 github.com/emicklei/go-restful v2.9.6+incompatible // indirect github.com/firecracker-microvm/firecracker-go-sdk v0.15.2-0.20190627223500-b2e8284e890c github.com/freddierice/go-losetup v0.0.0-20170407175016-fc9adea44124 diff --git a/pkg/apis/ignite/validation/validation.go b/pkg/apis/ignite/validation/validation.go index 1988dc570..5ba7e67c1 100644 --- a/pkg/apis/ignite/validation/validation.go +++ b/pkg/apis/ignite/validation/validation.go @@ -5,7 +5,6 @@ import ( "path" api "github.com/weaveworks/ignite/pkg/apis/ignite" - "k8s.io/apimachinery/pkg/util/validation/field" ) diff --git a/pkg/client/client.go b/pkg/client/client.go index 28a7a61f5..e8c57f174 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -67,6 +67,3 @@ type Client struct { imageClient ImageClient dynamicClients map[meta.Kind]DynamicClient } - -// DefaultClient is the default client that can be easily used -var DefaultClient = NewClient(storage.DefaultStorage) diff --git a/pkg/client/client_dynamic.go b/pkg/client/client_dynamic.go index 1cd3579ab..2b97ee217 100644 --- a/pkg/client/client_dynamic.go +++ b/pkg/client/client_dynamic.go @@ -35,11 +35,6 @@ func (c *Client) Dynamic(kind meta.Kind) (dc DynamicClient) { return } -// Dynamic is a shorthand for accessing the DynamicClient using the default client -func Dynamic(kind meta.Kind) DynamicClient { - return DefaultClient.Dynamic(kind) -} - // dynamicClient is a struct implementing the DynamicClient interface // It uses a shared storage instance passed from the Client together with its own Filterer type dynamicClient struct { diff --git a/pkg/client/client_resource_template.go b/pkg/client/client_resource_template.go index d12a857a1..12b056890 100644 --- a/pkg/client/client_resource_template.go +++ b/pkg/client/client_resource_template.go @@ -43,11 +43,6 @@ func (c *Client) Resources() ResourceClient { return c.resourceClient } -// Resources is a shorthand for accessing Resources using the default client -func Resources() ResourceClient { - return DefaultClient.Resources() -} - // resourceClient is a struct implementing the ResourceClient interface // It uses a shared storage instance passed from the Client together with its own Filterer type resourceClient struct { diff --git a/pkg/client/zz_generated.client_image.go b/pkg/client/zz_generated.client_image.go index 65ee9cbff..09aadca70 100644 --- a/pkg/client/zz_generated.client_image.go +++ b/pkg/client/zz_generated.client_image.go @@ -1,4 +1,3 @@ - /* Note: This file is autogenerated! Do not edit it manually! Edit client_image_template.go instead, and run @@ -42,11 +41,6 @@ func (c *Client) Images() ImageClient { return c.imageClient } -// Images is a shorthand for accessing Images using the default client -func Images() ImageClient { - return DefaultClient.Images() -} - // imageClient is a struct implementing the ImageClient interface // It uses a shared storage instance passed from the Client together with its own Filterer type imageClient struct { diff --git a/pkg/client/zz_generated.client_kernel.go b/pkg/client/zz_generated.client_kernel.go index 9e5730243..17bac400f 100644 --- a/pkg/client/zz_generated.client_kernel.go +++ b/pkg/client/zz_generated.client_kernel.go @@ -1,4 +1,3 @@ - /* Note: This file is autogenerated! Do not edit it manually! Edit client_kernel_template.go instead, and run @@ -42,11 +41,6 @@ func (c *Client) Kernels() KernelClient { return c.kernelClient } -// Kernels is a shorthand for accessing Kernels using the default client -func Kernels() KernelClient { - return DefaultClient.Kernels() -} - // kernelClient is a struct implementing the KernelClient interface // It uses a shared storage instance passed from the Client together with its own Filterer type kernelClient struct { diff --git a/pkg/client/zz_generated.client_vm.go b/pkg/client/zz_generated.client_vm.go index 97c8f0c97..5ecd96e53 100644 --- a/pkg/client/zz_generated.client_vm.go +++ b/pkg/client/zz_generated.client_vm.go @@ -1,4 +1,3 @@ - /* Note: This file is autogenerated! Do not edit it manually! Edit client_vm_template.go instead, and run @@ -42,11 +41,6 @@ func (c *Client) VMs() VMClient { return c.vmClient } -// VMs is a shorthand for accessing VMs using the default client -func VMs() VMClient { - return DefaultClient.VMs() -} - // vmClient is a struct implementing the VMClient interface // It uses a shared storage instance passed from the Client together with its own Filterer type vmClient struct { diff --git a/pkg/container/network.go b/pkg/container/network.go index aefcebda5..4ab0d56ed 100644 --- a/pkg/container/network.go +++ b/pkg/container/network.go @@ -9,7 +9,6 @@ import ( log "github.com/sirupsen/logrus" "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/util" - "k8s.io/apimachinery/pkg/util/wait" ) diff --git a/pkg/dm/dm.go b/pkg/dm/dm.go index 118e8017f..0aeb50c5f 100644 --- a/pkg/dm/dm.go +++ b/pkg/dm/dm.go @@ -5,9 +5,8 @@ import ( "log" "os" - "github.com/weaveworks/ignite/pkg/util" - meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" + "github.com/weaveworks/ignite/pkg/util" ) type blockDevice interface { diff --git a/pkg/metadata/id.go b/pkg/metadata/id.go index ca7344cf7..fc5ef65e8 100644 --- a/pkg/metadata/id.go +++ b/pkg/metadata/id.go @@ -4,8 +4,8 @@ import ( "fmt" "log" - "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/logs" + "github.com/weaveworks/ignite/pkg/providers" ) // TODO: Get rid of this @@ -21,7 +21,8 @@ func Cleanup(md Metadata, silent bool) error { } else if !silent { fmt.Println(md.GetUID()) } - return client.Dynamic(md.GetKind()).Delete(md.GetUID()) + + return providers.Client.Dynamic(md.GetKind()).Delete(md.GetUID()) } if !logs.Quiet { diff --git a/pkg/metadata/imgmd/imgmd.go b/pkg/metadata/imgmd/imgmd.go index 04433a71a..d99ebc069 100644 --- a/pkg/metadata/imgmd/imgmd.go +++ b/pkg/metadata/imgmd/imgmd.go @@ -8,6 +8,7 @@ import ( "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/metadata" + "github.com/weaveworks/ignite/pkg/providers" ) type Image struct { @@ -27,7 +28,7 @@ func WrapImage(obj *api.Image) *Image { return &Image{ Image: obj, - c: client.DefaultClient, + c: providers.Client, } } diff --git a/pkg/metadata/kernmd/kernmd.go b/pkg/metadata/kernmd/kernmd.go index 59a9407db..c2560afb5 100644 --- a/pkg/metadata/kernmd/kernmd.go +++ b/pkg/metadata/kernmd/kernmd.go @@ -8,6 +8,7 @@ import ( "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/metadata" + "github.com/weaveworks/ignite/pkg/providers" ) type Kernel struct { @@ -27,7 +28,7 @@ func WrapKernel(obj *api.Kernel) *Kernel { return &Kernel{ Kernel: obj, - c: client.DefaultClient, + c: providers.Client, } } diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go index b56f6a2d8..d8b6e479e 100644 --- a/pkg/metadata/metadata.go +++ b/pkg/metadata/metadata.go @@ -13,6 +13,7 @@ import ( "github.com/weaveworks/ignite/pkg/client" "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/filter" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/storage/filterer" "github.com/weaveworks/ignite/pkg/util" ) @@ -36,7 +37,7 @@ func InitObject(obj meta.Object, c *client.Client) error { } if c == nil { - c = client.DefaultClient + c = providers.Client } // Default the object diff --git a/pkg/metadata/vmmd/vmmd.go b/pkg/metadata/vmmd/vmmd.go index 5d59044c9..e76bca731 100644 --- a/pkg/metadata/vmmd/vmmd.go +++ b/pkg/metadata/vmmd/vmmd.go @@ -13,6 +13,7 @@ import ( "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/filter" "github.com/weaveworks/ignite/pkg/metadata" + "github.com/weaveworks/ignite/pkg/providers" ) type VM struct { @@ -36,7 +37,7 @@ func WrapVM(obj *api.VM) *VM { vm := &VM{ VM: obj, - c: client.DefaultClient, + c: providers.Client, } return vm diff --git a/pkg/network/cni/cni.go b/pkg/network/cni/cni.go index 2b632c6b4..c3f0b7b0b 100644 --- a/pkg/network/cni/cni.go +++ b/pkg/network/cni/cni.go @@ -2,7 +2,6 @@ package cni import ( "context" - "errors" "fmt" "sort" "strings" @@ -44,10 +43,6 @@ func GetCNINetworkPlugin(runtime runtime.Interface) (NetworkPlugin, error) { binDirs: binDirs, } - if err := plugin.syncNetworkConfig(); err != nil { - return nil, err - } - return plugin, nil } @@ -72,7 +67,7 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error) case err != nil: return nil, err case len(files) == 0: - return nil, fmt.Errorf("No networks found in %s", confDir) + return nil, fmt.Errorf("no networks found in %s", confDir) } sort.Strings(files) @@ -121,7 +116,7 @@ func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error) return network, nil } - return nil, fmt.Errorf("No valid networks found in %s", confDir) + return nil, fmt.Errorf("no valid networks found in %s", confDir) } func (plugin *cniNetworkPlugin) syncNetworkConfig() error { @@ -148,7 +143,10 @@ func (plugin *cniNetworkPlugin) setDefaultNetwork(n *cniNetwork) { func (plugin *cniNetworkPlugin) checkInitialized() error { if plugin.getDefaultNetwork() == nil { - return errors.New("cni config uninitialized") + // Sync the network configuration if the plugin is not initialized + if err := plugin.syncNetworkConfig(); err != nil { + return err + } } return nil @@ -168,7 +166,7 @@ func (plugin *cniNetworkPlugin) SetupContainerNetwork(containerid string) error return err } - netnsPath, err := plugin.runtime.GetNetNS(containerid) + netnsPath, err := plugin.runtime.ContainerNetNS(containerid) if err != nil { return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) } @@ -187,7 +185,7 @@ func (plugin *cniNetworkPlugin) RemoveContainerNetwork(containerid string) error } // Lack of namespace should not be fatal on teardown - netnsPath, err := plugin.runtime.GetNetNS(containerid) + netnsPath, err := plugin.runtime.ContainerNetNS(containerid) if err != nil { log.Infof("CNI failed to retrieve network namespace path: %v", err) } diff --git a/pkg/operations/remove.go b/pkg/operations/remove.go index 2428ca329..f83290ad6 100644 --- a/pkg/operations/remove.go +++ b/pkg/operations/remove.go @@ -4,19 +4,16 @@ import ( "fmt" "log" - "github.com/weaveworks/ignite/pkg/metadata/vmmd" - meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" "github.com/weaveworks/ignite/pkg/client" - "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/logs" + "github.com/weaveworks/ignite/pkg/metadata/vmmd" + "github.com/weaveworks/ignite/pkg/providers" "github.com/weaveworks/ignite/pkg/util" ) -var ( - stopArgs = []string{"stop"} - killArgs = []string{"kill", "-s", "SIGQUIT"} - rmArgs = []string{"rm", "-f"} +const ( + signalSIGQUIT = "SIGQUIT" ) // RemoveVM removes the specified VM @@ -45,12 +42,8 @@ func RemoveVM(c *client.Client, vm *vmmd.VM) error { } func RemoveVMContainer(vm meta.Object) error { - // Specify what container to remove - dockerArgs := append(rmArgs, constants.IGNITE_PREFIX+vm.GetUID().String()) - // Remove the VM container - // TODO: Use pkg/runtime here instead - if _, err := util.ExecuteCommand("docker", dockerArgs...); err != nil { + if err := providers.Runtime.RemoveContainer(util.NewPrefixer().Prefix(vm.GetUID())); err != nil { return fmt.Errorf("failed to remove container for VM %q: %v", vm.GetUID(), err) } @@ -59,20 +52,20 @@ func RemoveVMContainer(vm meta.Object) error { // StopVM stops or kills a VM func StopVM(vm *vmmd.VM, kill, silent bool) error { - dockerArgs := stopArgs + var err error + container := util.NewPrefixer().Prefix(vm.GetUID()) + action := "stop" - // Change to kill arguments if requested + // Stop or kill the VM container if kill { - dockerArgs = killArgs + action = "kill" + err = providers.Runtime.KillContainer(container, signalSIGQUIT) // TODO: common constant for SIGQUIT + } else { + err = providers.Runtime.StopContainer(container, nil) } - // Specify what container to stop/kill - dockerArgs = append(dockerArgs, constants.IGNITE_PREFIX+vm.GetUID().String()) - - // Stop/Kill the VM in docker - // TODO: Use pkg/runtime here instead - if _, err := util.ExecuteCommand("docker", dockerArgs...); err != nil { - return fmt.Errorf("failed to stop container for VM %q: %v", vm.GetUID(), err) + if err != nil { + return fmt.Errorf("failed to %s container for %s %q: %v", action, vm.GetKind(), vm.GetUID(), err) } if silent { diff --git a/pkg/operations/start.go b/pkg/operations/start.go index 9c4a2c504..6948d554e 100644 --- a/pkg/operations/start.go +++ b/pkg/operations/start.go @@ -7,21 +7,20 @@ import ( "log" "path" "path/filepath" - "strings" "time" api "github.com/weaveworks/ignite/pkg/apis/ignite" "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/metadata/vmmd" - "github.com/weaveworks/ignite/pkg/network/cni" - "github.com/weaveworks/ignite/pkg/runtime/docker" + "github.com/weaveworks/ignite/pkg/providers" + "github.com/weaveworks/ignite/pkg/runtime" "github.com/weaveworks/ignite/pkg/util" "github.com/weaveworks/ignite/pkg/version" ) func StartVM(vm *vmmd.VM, debug bool) error { // Make sure the VM container does not exist. Don't care about the error. - RemoveVMContainer(vm.VM) + _ = RemoveVMContainer(vm.VM) // Setup the snapshot overlay filesystem if err := vm.SetupSnapshot(); err != nil { @@ -30,58 +29,61 @@ func StartVM(vm *vmmd.VM, debug bool) error { vmDir := filepath.Join(constants.VM_DIR, vm.GetUID().String()) kernelDir := filepath.Join(constants.KERNEL_DIR, vm.GetKernelUID().String()) + igniteImage := fmt.Sprintf("weaveworks/ignite:%s", version.GetIgnite().ImageTag()) - dockerArgs := []string{ - "-itd", - fmt.Sprintf("--label=ignite.name=%s", vm.GetName()), - fmt.Sprintf("--name=%s", constants.IGNITE_PREFIX+vm.GetUID()), - fmt.Sprintf("--volume=%s:%s", vmDir, vmDir), - fmt.Sprintf("--volume=%s:%s", kernelDir, kernelDir), - fmt.Sprintf("--stop-timeout=%d", constants.STOP_TIMEOUT+constants.IGNITE_TIMEOUT), - "--cap-add=SYS_ADMIN", // Needed to run "dmsetup remove" inside the container - "--cap-add=NET_ADMIN", // Needed for removing the IP from the container's interface - "--device=/dev/mapper/control", // This enables containerized Ignite to remove its own dm snapshot - "--device=/dev/net/tun", // Needed for creating TAP adapters - "--device=/dev/kvm", // Pass though virtualization support - fmt.Sprintf("--device=%s", vm.SnapshotDev()), + // Verify that the image containing ignite-spawn is pulled + // TODO: Integrate automatic pulling into pkg/runtime + if err := verifyPulled(igniteImage); err != nil { + return err } - if vm.Spec.Network.Mode == api.NetworkModeCNI { - dockerArgs = append(dockerArgs, "--net=none") + config := &runtime.ContainerConfig{ + Cmd: []string{vm.GetUID().String()}, + Labels: map[string]string{"ignite.name": vm.GetName()}, + Binds: []*runtime.Bind{ + { + HostPath: vmDir, + ContainerPath: vmDir, + }, + { + HostPath: kernelDir, + ContainerPath: kernelDir, + }, + }, + CapAdds: []string{ + "SYS_ADMIN", // Needed to run "dmsetup remove" inside the container + "NET_ADMIN", // Needed for removing the IP from the container's interface + }, + Devices: []string{ + "/dev/mapper/control", // This enables containerized Ignite to remove its own dm snapshot + "/dev/net/tun", // Needed for creating TAP adapters + "/dev/kvm", // Pass through virtualization support + vm.SnapshotDev(), // The block device to boot from + }, + StopTimeout: constants.STOP_TIMEOUT + constants.IGNITE_TIMEOUT, + PortBindings: vm.Spec.Network.Ports, // Add the port mappings to Docker } - dockerCmd := append(make([]string, 0, len(dockerArgs)+2), "run") + // If the VM is using CNI networking, disable Docker's own implementation + if vm.Spec.Network.Mode == api.NetworkModeCNI { + config.NetworkMode = "none" + } // If we're not debugging, remove the container post-run if !debug { - dockerCmd = append(dockerCmd, "--rm") + config.AutoRemove = true } - // Add the port mappings to Docker - for _, portMapping := range vm.Spec.Network.Ports { - dockerArgs = append(dockerArgs, fmt.Sprintf("-p=%d:%d", portMapping.HostPort, portMapping.VMPort)) - } - - igniteImage := fmt.Sprintf("weaveworks/ignite:%s", version.GetIgnite().ImageTag()) - dockerArgs = append(dockerArgs, igniteImage, vm.GetUID().String()) - - // Verify that the image containing ignite-spawn is pulled - // TODO: Integrate automatic pulling into pkg/runtime - if err := verifyPulled(igniteImage); err != nil { - return err - } - - // Create the VM container in docker - // TODO: Replace all calls to the docker binary with pkg/runtime - output, err := util.ExecuteCommand("docker", append(dockerCmd, dockerArgs...)...) + // Run the VM container in Docker + containerID, err := providers.Runtime.RunContainer(igniteImage, config, util.NewPrefixer().Prefix(vm.GetUID())) if err != nil { return fmt.Errorf("failed to start container for VM %q: %v", vm.GetUID(), err) } - containerID := strings.TrimSpace(output) - if vm.Spec.Network.Mode == api.NetworkModeCNI { - if err := setupCNINetworking(containerID); err != nil { + // TODO: Right now IP addresses aren't reclaimed when the VM is removed. + // NetworkPlugin.RemoveContainerNetwork needs to be called when removing the VM. + if err := providers.NetworkPlugin.SetupContainerNetwork(containerID); err != nil { return err } @@ -96,33 +98,10 @@ func StartVM(vm *vmmd.VM, debug bool) error { return waitForSpawn(vm) } -func setupCNINetworking(containerID string) error { - // TODO: Both the client and networkPlugin variables should be constructed once, - // and accessible throughout the program. - // TODO: Right now IP addresses aren't reclaimed when the VM is removed. - // networkPlugin.RemoveContainerNetwork need to be called when removing the VM. - client, err := docker.GetDockerClient() - if err != nil { - return err - } - - networkPlugin, err := cni.GetCNINetworkPlugin(client) - if err != nil { - return err - } - - return networkPlugin.SetupContainerNetwork(containerID) -} - func verifyPulled(image string) error { - client, err := docker.GetDockerClient() - if err != nil { - return err - } - - if _, err = client.InspectImage(image); err != nil { + if _, err := providers.Runtime.InspectImage(image); err != nil { log.Printf("Pulling image %q...", image) - rc, err := client.PullImage(image) + rc, err := providers.Runtime.PullImage(image) if err != nil { return err } @@ -137,7 +116,7 @@ func verifyPulled(image string) error { } // Verify the image was pulled - if _, err = client.InspectImage(image); err != nil { + if _, err = providers.Runtime.InspectImage(image); err != nil { return err } } diff --git a/pkg/providers/client.go b/pkg/providers/client.go new file mode 100644 index 000000000..eec9474c0 --- /dev/null +++ b/pkg/providers/client.go @@ -0,0 +1,11 @@ +package providers + +import "github.com/weaveworks/ignite/pkg/client" + +// Client is the default client that can be easily used +var Client *client.Client + +func SetClient() error { + Client = client.NewClient(Storage) + return nil +} diff --git a/pkg/providers/network.go b/pkg/providers/network.go new file mode 100644 index 000000000..e822c0f18 --- /dev/null +++ b/pkg/providers/network.go @@ -0,0 +1,13 @@ +package providers + +import ( + "github.com/weaveworks/ignite/pkg/network/cni" +) + +// NetworkPlugin provides the default network plugin implementation +var NetworkPlugin cni.NetworkPlugin + +func SetCNINetworkPlugin() (err error) { + NetworkPlugin, err = cni.GetCNINetworkPlugin(Runtime) + return +} diff --git a/pkg/providers/providers.go b/pkg/providers/providers.go new file mode 100644 index 000000000..931d31e8e --- /dev/null +++ b/pkg/providers/providers.go @@ -0,0 +1,21 @@ +package providers + +// Populate initializes all providers +func Populate() error { + // NOTE: This initialization is order-dependent! + // E.g. the network plugin depends on the runtime. + providers := []func() error{ + SetDockerRuntime, // Use the Docker runtime + SetCNINetworkPlugin, // Use the CNI Network plugin + SetCachedStorage, // Use a generic storage implementation backed by a cache + SetClient, // Set the globally available client + } + + for _, init := range providers { + if err := init(); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/providers/runtime.go b/pkg/providers/runtime.go new file mode 100644 index 000000000..4cb46f13c --- /dev/null +++ b/pkg/providers/runtime.go @@ -0,0 +1,14 @@ +package providers + +import ( + "github.com/weaveworks/ignite/pkg/runtime" + "github.com/weaveworks/ignite/pkg/runtime/docker" +) + +// Runtime provides the default runtime +var Runtime runtime.Interface + +func SetDockerRuntime() (err error) { + Runtime, err = docker.GetDockerClient() + return +} diff --git a/pkg/providers/storage.go b/pkg/providers/storage.go new file mode 100644 index 000000000..bf8d3db3c --- /dev/null +++ b/pkg/providers/storage.go @@ -0,0 +1,17 @@ +package providers + +import ( + "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" + "github.com/weaveworks/ignite/pkg/constants" + "github.com/weaveworks/ignite/pkg/storage" +) + +// Storage is the default storage implementation +var Storage storage.Storage + +func SetCachedStorage() error { + Storage = storage.NewCache( + storage.NewGenericStorage( + storage.NewDefaultRawStorage(constants.DATA_DIR), scheme.Serializer)) + return nil +} diff --git a/pkg/runtime/docker/client.go b/pkg/runtime/docker/client.go index 8dc933412..cc538bcd0 100644 --- a/pkg/runtime/docker/client.go +++ b/pkg/runtime/docker/client.go @@ -4,13 +4,27 @@ import ( "context" "fmt" "io" + "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" + "github.com/docker/go-connections/nat" "github.com/weaveworks/ignite/pkg/runtime" ) -const dockerNetNSFmt = "/proc/%v/ns/net" +const ( + dockerNetNSFmt = "/proc/%v/ns/net" + portFormat = "%d/tcp" // TODO: Support protocols other than TCP +) + +// dockerClient is a runtime.Interface +// implementation serving the Docker client +type dockerClient struct { + client *client.Client +} + +var _ runtime.Interface = &dockerClient{} // GetDockerClient builds a client for talking to docker func GetDockerClient() (runtime.Interface, error) { @@ -24,10 +38,6 @@ func GetDockerClient() (runtime.Interface, error) { }, nil } -type dockerClient struct { - client *client.Client -} - func (dc *dockerClient) RawClient() interface{} { return dc.client } @@ -49,11 +59,91 @@ func (dc *dockerClient) PullImage(image string) (io.ReadCloser, error) { return dc.client.ImagePull(context.Background(), image, types.ImagePullOptions{}) } -// GetNetNS returns the network namespace of the given containerID. The ID -// supplied is typically the ID of a pod sandbox. This getter doesn't try -// to map non-sandbox IDs to their respective sandboxes. -func (dc *dockerClient) GetNetNS(podSandboxID string) (string, error) { - r, err := dc.client.ContainerInspect(context.TODO(), podSandboxID) +func (dc *dockerClient) ExportImage(image string) (io.ReadCloser, string, error) { + config, err := dc.client.ContainerCreate(context.Background(), &container.Config{ + Cmd: []string{"sh"}, // We need a temporary command, this doesn't need to exist in the image + Image: image, + }, nil, nil, "") + if err != nil { + return nil, "", err + } + + rc, err := dc.client.ContainerExport(context.Background(), config.ID) + return rc, config.ID, err +} + +func (dc *dockerClient) RunContainer(image string, config *runtime.ContainerConfig, name string) (string, error) { + portBindings := make(nat.PortMap) + for _, portMapping := range config.PortBindings { + portBindings[nat.Port(fmt.Sprintf(portFormat, portMapping.VMPort))] = []nat.PortBinding{ + { + HostPort: fmt.Sprintf(portFormat, portMapping.HostPort), + }, + } + } + + binds := make([]string, 0, len(config.Binds)) + for _, bind := range config.Binds { + binds = append(binds, fmt.Sprintf("%s:%s", bind.HostPath, bind.ContainerPath)) + } + + devices := make([]container.DeviceMapping, 0, len(config.Devices)) + for _, device := range config.Devices { + devices = append(devices, container.DeviceMapping{ + PathOnHost: device, + PathInContainer: device, + CgroupPermissions: "rwm", + }) + } + + stopTimeout := int(config.StopTimeout) + + c, err := dc.client.ContainerCreate(context.Background(), &container.Config{ + Hostname: config.Hostname, + Tty: true, // --tty + OpenStdin: true, // --interactive + Cmd: config.Cmd, + Image: image, + Labels: config.Labels, + StopTimeout: &stopTimeout, + }, &container.HostConfig{ + Binds: binds, + NetworkMode: container.NetworkMode(config.NetworkMode), + PortBindings: portBindings, + AutoRemove: config.AutoRemove, + CapAdd: config.CapAdds, + Resources: container.Resources{ + Devices: devices, + }, + }, nil, name) + if err != nil { + return "", err + } + + return c.ID, dc.client.ContainerStart(context.Background(), c.ID, types.ContainerStartOptions{}) +} + +func (dc *dockerClient) StopContainer(container string, timeout *time.Duration) error { + return dc.client.ContainerStop(context.Background(), container, timeout) +} + +func (dc *dockerClient) KillContainer(container, signal string) error { + return dc.client.ContainerKill(context.Background(), container, signal) +} + +func (dc *dockerClient) RemoveContainer(container string) error { + return dc.client.ContainerRemove(context.Background(), container, types.ContainerRemoveOptions{}) +} + +func (dc *dockerClient) ContainerLogs(container string) (io.ReadCloser, error) { + return dc.client.ContainerLogs(context.Background(), container, types.ContainerLogsOptions{ + ShowStdout: true, // We only need stdout, as TTY mode merges stderr into it + }) +} + +// ContainerNetNS returns the network namespace of the given container. +func (dc *dockerClient) ContainerNetNS(container string) (string, error) { + r, err := dc.client.ContainerInspect(context.TODO(), container) if err != nil { return "", err } diff --git a/pkg/runtime/types.go b/pkg/runtime/types.go index fbeb6c762..a1f464d53 100644 --- a/pkg/runtime/types.go +++ b/pkg/runtime/types.go @@ -1,6 +1,11 @@ package runtime -import "io" +import ( + "io" + "time" + + meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" +) type ImageInspectResult struct { ID string @@ -8,9 +13,36 @@ type ImageInspectResult struct { Size int64 } +type Bind struct { + HostPath string + ContainerPath string +} + +type ContainerConfig struct { + Cmd []string + Hostname string + Labels map[string]string + Binds []*Bind + CapAdds []string + Devices []string + StopTimeout uint32 + AutoRemove bool + NetworkMode string + PortBindings meta.PortMappings +} + type Interface interface { InspectImage(image string) (*ImageInspectResult, error) PullImage(image string) (io.ReadCloser, error) - GetNetNS(containerID string) (string, error) + ExportImage(image string) (io.ReadCloser, string, error) + + // TODO: AttachContainer + RunContainer(image string, config *ContainerConfig, name string) (string, error) + StopContainer(container string, timeout *time.Duration) error + KillContainer(container, signal string) error + RemoveContainer(container string) error + ContainerLogs(container string) (io.ReadCloser, error) + ContainerNetNS(container string) (string, error) + RawClient() interface{} } diff --git a/pkg/source/docker.go b/pkg/source/docker.go index 513c94bef..69013afd9 100644 --- a/pkg/source/docker.go +++ b/pkg/source/docker.go @@ -9,10 +9,10 @@ import ( api "github.com/weaveworks/ignite/pkg/apis/ignite" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" - "github.com/weaveworks/ignite/pkg/runtime/docker" - "github.com/weaveworks/ignite/pkg/util" + "github.com/weaveworks/ignite/pkg/providers" ) +// TODO: Make this a generic "OCISource" as it now only depends on the generic providers.Runtime type DockerSource struct { imageID string containerID string @@ -31,16 +31,11 @@ func (ds *DockerSource) ID() string { } func (ds *DockerSource) Parse(ociRef meta.OCIImageRef) (*api.OCIImageSource, error) { - client, err := docker.GetDockerClient() - if err != nil { - return nil, err - } - source := ociRef.String() - res, err := client.InspectImage(source) + res, err := providers.Runtime.InspectImage(source) if err != nil { log.Printf("Docker image %q not found locally, pulling...", source) - rc, err := client.PullImage(source) + rc, err := providers.Runtime.PullImage(source) if err != nil { return nil, err } @@ -48,7 +43,7 @@ func (ds *DockerSource) Parse(ociRef meta.OCIImageRef) (*api.OCIImageSource, err // Don't output the pull command io.Copy(ioutil.Discard, rc) rc.Close() - res, err = client.InspectImage(source) + res, err = providers.Runtime.InspectImage(source) if err != nil { return nil, err } @@ -66,34 +61,17 @@ func (ds *DockerSource) Parse(ociRef meta.OCIImageRef) (*api.OCIImageSource, err }, nil } -func (ds *DockerSource) Reader() (io.ReadCloser, error) { - // Create a container from the image to be exported - var err error - if ds.containerID, err = util.ExecuteCommand("docker", "create", ds.imageID, "sh"); err != nil { - return nil, fmt.Errorf("failed to create Docker container from image %q: %v", ds.imageID, err) - } - - // Open a tar file stream to be extracted straight into the image volume - ds.exportCmd = exec.Command("docker", "export", ds.containerID) - reader, err := ds.exportCmd.StdoutPipe() - if err != nil { - return nil, err - } - - if err := ds.exportCmd.Start(); err != nil { - return nil, err - } - - return reader, nil +func (ds *DockerSource) Reader() (rc io.ReadCloser, err error) { + // Export the image + rc, ds.containerID, err = providers.Runtime.ExportImage(ds.imageID) + return } -func (ds *DockerSource) Cleanup() error { +func (ds *DockerSource) Cleanup() (err error) { if len(ds.containerID) > 0 { // Remove the temporary container - if _, err := util.ExecuteCommand("docker", "rm", ds.containerID); err != nil { - return fmt.Errorf("failed to remove container %q: %v", ds.containerID, err) - } + err = providers.Runtime.RemoveContainer(ds.containerID) } - return nil + return } diff --git a/pkg/storage/gitops/rawstorage.go b/pkg/storage/gitops/rawstorage.go index 36cb8b89e..844456bf4 100644 --- a/pkg/storage/gitops/rawstorage.go +++ b/pkg/storage/gitops/rawstorage.go @@ -15,7 +15,6 @@ import ( meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" "github.com/weaveworks/ignite/pkg/storage" "github.com/weaveworks/ignite/pkg/util" - "sigs.k8s.io/yaml" ) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 0275112bf..0514beb9b 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -4,11 +4,8 @@ import ( "fmt" "path" - "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" - "github.com/weaveworks/ignite/pkg/constants" "github.com/weaveworks/ignite/pkg/storage/serializer" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" @@ -38,9 +35,6 @@ type Storage interface { Count(kind meta.Kind) (uint64, error) } -// DefaultStorage is the default storage implementation -var DefaultStorage = NewCache(NewGenericStorage(NewDefaultRawStorage(constants.DATA_DIR), scheme.Serializer)) - // NewGenericStorage constructs a new Storage func NewGenericStorage(rawStorage RawStorage, serializer serializer.Serializer) Storage { return &GenericStorage{rawStorage, serializer} diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index 7d10ec8be..7647210e3 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -3,9 +3,8 @@ package storage import ( "testing" - "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" - api "github.com/weaveworks/ignite/pkg/apis/ignite" + "github.com/weaveworks/ignite/pkg/apis/ignite/scheme" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" ) diff --git a/pkg/util/util.go b/pkg/util/util.go index 29e838063..23b04d604 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -137,9 +137,15 @@ func NewPrefixer() *Prefixer { } } -func (p *Prefixer) Prefix(input ...string) string { +func (p *Prefixer) Prefix(input ...interface{}) string { if len(input) > 0 { - p.prefix += p.separator + strings.Join(input, p.separator) + s := make([]string, 0, len(input)) + + for _, data := range input { + s = append(s, fmt.Sprintf("%v", data)) + } + + p.prefix += p.separator + strings.Join(s, p.separator) } return p.prefix diff --git a/vendor/modules.txt b/vendor/modules.txt index aecfaed6d..c991b58d3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -27,13 +27,15 @@ github.com/docker/distribution/digestset github.com/docker/distribution/registry/api/errcode # github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 github.com/docker/docker/api/types -github.com/docker/docker/client github.com/docker/docker/api/types/container +github.com/docker/docker/client github.com/docker/docker/api/types/filters github.com/docker/docker/api/types/mount github.com/docker/docker/api/types/network github.com/docker/docker/api/types/registry github.com/docker/docker/api/types/swarm +github.com/docker/docker/api/types/blkiodev +github.com/docker/docker/api/types/strslice github.com/docker/docker/api github.com/docker/docker/api/types/events github.com/docker/docker/api/types/image @@ -41,8 +43,6 @@ github.com/docker/docker/api/types/time github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/volume github.com/docker/docker/errdefs -github.com/docker/docker/api/types/blkiodev -github.com/docker/docker/api/types/strslice github.com/docker/docker/api/types/swarm/runtime # github.com/docker/go-connections v0.4.0 github.com/docker/go-connections/nat