func (h *Handlers) download(v *vagrantutil.Vagrant, box, filePath string, queue <-chan chan error) { h.log().Debug("downloading %q box...", box) var listeners []chan error done := make(chan error) go func() { err := vagrantutil.Wait(v.BoxAdd(&vagrantutil.Box{Name: box})) if err == vagrantutil.ErrBoxAlreadyExists { // Ignore the above error. err = nil } done <- err }() for { select { case l := <-queue: listeners = append(listeners, l) case err := <-done: // Remove the box from in progress. h.boxMu.Lock() delete(h.boxNames, box) delete(h.boxPaths, filePath) h.boxMu.Unlock() // Defensive channel drain: try to collect listeners // that may have registered after receiving from done // but before taking boxMu lock. listeners = append(listeners, drain(queue)...) // Notify all listeners. for _, l := range listeners { l <- err } h.log().Debug("downloading %q box finished: err=%v", box, err) return } } }
func (h *Handlers) create(r *kite.Request, v *vagrantutil.Vagrant) (interface{}, error) { if r.Args == nil { return nil, errors.New("missing arguments") } var params VagrantCreateOptions if err := r.Args.One().Unmarshal(¶ms); err != nil { return nil, err } params.FilePath = h.absolute(params.FilePath) if params.Box == "" { params.Box = "ubuntu/trusty64" } if params.Hostname == "" { params.Hostname = r.LocalKite.Config.Username } if params.Memory == 0 { params.Memory = 1024 } if params.Cpus == 0 { params.Cpus = 1 } if params.TLSProxyHostname == "" { params.TLSProxyHostname = pem.Hostname } switch { case !params.Dirty: // Ensure vagrant working dir has no machine provisioned. err := vagrantutil.Wait(v.Destroy()) if err != nil { h.log().Error("unable to destroy before create: %s", err) break } status, err := v.Status() if err != nil { h.log().Error("unable to check status: %s", err) break } if status != vagrantutil.NotCreated { h.log().Error("dirty Vagrant directory: want status to be %v, was %v", vagrantutil.NotCreated, status) } } h.boxAdd(v, params.Box, params.FilePath) vagrantFile, err := createTemplate(¶ms) if err != nil { return nil, err } if err := v.Create(vagrantFile); err != nil { return nil, err } return params, nil }