10.11.16

Using Glide to flatten and compile a custom kubernetes component.

Problem:
You have a golang code base that you want to integrate into your project.
Old Solution(s)

1) Using vendor/ + godep

2) Copying the code or forking

3) Godep?...no.... Glide!
Glide (described below) and have one thing in common - they scan your imports.  The difference is that glide adds (1) global cache separate from local deps (2) works in just two commands - glide install, go install.  Godep has this weird "godep restore" "godep save" lifecycle that can be tricky to get right unless you understand how godep  works.  Glide you can use from a very high abstraction level.  Glide is a "package manager" for golang that allows you to do maven-ish stuff.  Its similar to godeps, but its a little easier to use.

- It has really nice explicit debugging , with colors .
- It has a handy "install" function which scans all of your dependencies, vendors them for you - note this is different then "go install" which actually installs a binary on your GOPATH.


So, here's the tutorial for today

Below are the steps I took to create a Glide based "maven-ish" extension of the kuberentes scheduler.


      0. Install golang, hg, git, and glide  (super easy : curl https://glide.sh/get | sh)
  1. Copy the cmd scheduler wrapper application from kubernetes into my own directory
  2. glide init.  Now after some questions, you will see glide.yaml
package: github.com/jayunit100/kube-scheduler-experimental
import:
- package: github.com/golang/glog
- package: github.com/prometheus/client_golang
  version: ^0.8.0
  subpackages:
  - prometheus
- package: github.com/spf13/cobra
- package: github.com/spf13/pflag
- package: k8s.io/kubernetes
  version: ^1.6.0-alpha.0
  subpackages:
  - pkg/api
  - pkg/apis/componentconfig
  - pkg/apis/componentconfig/v1alpha1
  - pkg/client/clientset_generated/internalclientset
  - pkg/client/clientset_generated/internalclientset/typed/core/internalversion
  - pkg/client/leaderelection
  - pkg/client/leaderelection/resourcelock
  - pkg/client/record
  - pkg/client/restclient
  - pkg/client/unversioned/clientcmd
  - pkg/healthz
  - pkg/runtime
  - pkg/util/config
  - pkg/util/configz
  - pkg/util/flag
  - pkg/util/logs
  - pkg/version/verflag
  - plugin/cmd/kube-scheduler/app
  - plugin/cmd/kube-scheduler/app/options
  - plugin/pkg/scheduler
  - plugin/pkg/scheduler/algorithmprovider
  - plugin/pkg/scheduler/api
  - plugin/pkg/scheduler/api/latest
  - plugin/pkg/scheduler/factory
       3. yay.  okay, so what happened?  Glide went into the existing source code i had, scanned the imports, and realized it needed to import all of the above packages in order to compile it.  Not that this includes *transitive dependencies* of the scheduler itself,.  but vendor/ isn't there? Well, guess what, Glide has a ~/.glide/cache (similar to mvn/gradle/etc) where it stores all these dependencies.  So it decouples the concept of a cache for deps from app specific dependencies.  Which is good - it avoids collisions and allows you infinitely fine grained dependency management.




     4.  Ok, so now I want to run my code.  First, we do "glide install" which will install all the dependencies from the cache.  This happens very fast :).


     5.  Now, time to roll up vendor dependencies.  The way we do this is simple, just delete any messy vendor conflicts which you may see when running "go install".  I found pflag as a problem.  In general, anything that you import in YOUR CODE which also is imported INSIDE vendor/ of a LIBRARY you depend  on, can cause a problem.  The solution:

[root@localhost kube-scheduler-experimental]# rm -rf vendor/k8s.io/kubernetes/vendor/github.com/spf13/pflag/

    6.  Now I can run "go install" and create my own custom kubernetes scheduling application which sucks in existing kubernetes dependencies into its own, flattened vendor/ library.


3 comments:

  1. glide can flatten your /vendor directory for you with glide install --strip-vendor

    or the shorthand glide install -v

    ReplyDelete
  2. -v can fail in some cases, so manual vendor removal is needed, or else "go install" will choke. I'll file a bug upstream . thanks for the comment though ! In my case, kubernetes, manual vendor/ removal is required.

    ReplyDelete