// Spawn watches a registry image and will try to push any images that are not
// saved in the registry.
175333
func (l *RegistryListener) Spawn(shutdown <-chan interface{}, id string) {
	imagepath := l.GetPath(id)
	done := make(chan struct{})
	defer func(channel *chan struct{}) { close(*channel) }(&done)
	for {
		// Get the node
		var node RegistryImageNode
		evt, err := l.conn.GetW(imagepath, &node, done)
		if err != nil {
			glog.Errorf("Could not look up node at %s: %s", imagepath, err)
			return
		}
		repopath := path.Join(zkregistryrepos, node.Image.Library, node.Image.Repo)
		reponode := &RegistryImageLeader{HostID: l.hostid}
		leader, err := l.conn.NewLeader(repopath)
		if err != nil {
			glog.Errorf("Could not set up leader for %s: %s", repopath, err)
			return
		}
		// Has the image been pushed?
		glog.V(1).Infof("Spawn id=%s node: %s:%s %s", id, node.Image.Repo, node.Image.Tag, node.Image.Tag)
		if node.PushedAt.Unix() == 0 {
			// Do I have the image?
			glog.Infof("Checking if push required for id=%s node: %s:%s %s (UUID=%s)", id, node.Image.Repo, node.Image.Tag, node.Image.Tag, node.Image.UUID)
			if img, err := l.FindImage(&node.Image); err == nil {
				glog.V(1).Infof("Found image %v locally, acquiring lead", node.Image)
				func() {
					// Become the leader so I can push the image
					leaderDone := make(chan struct{})
					defer close(leaderDone)
					_, err := leader.TakeLead(reponode, leaderDone)
					if err != nil {
						glog.Errorf("Could not take lead %s: %s", imagepath, err)
						return
					}
					defer leader.ReleaseLead()
					// Did I shutdown before I got the lead?
					select {
					case <-shutdown:
						return
					default:
						// Did the image change (or get pushed) before I got the lead?
						if err := l.conn.Get(imagepath, &node); err != nil {
							glog.Errorf("Could not get %s: %s", imagepath, err)
							return
						}
						if node.PushedAt.Unix() > 0 {
							glog.V(1).Infof("Image %s already pushed, cancelling push", node.Image.String())
							return
						}
						if img.ID != node.Image.UUID {
							localHash, err := l.docker.GetImageHash(img.ID)
							if err != nil {
								glog.Warningf("Error building hash of image: %s, cancelling push: %s", img.ID, err)
								return
							} else if localHash != node.Image.Hash {
								glog.V(1).Infof("Image %s changed, cancelling push", node.Image.String())
								return
							}
						}
					}
					// Push the image and update the registry
					// If the push is unsuccessful, still update the timestamp,
					// so that the push will get retriggered the next time it
					// is needed.
					registrypath := path.Join(l.address, node.Image.String())
					glog.V(1).Infof("Updating registry image %s from path=%s", img.ID, registrypath)
					if err := l.docker.TagImage(img.ID, registrypath); err != nil {
						glog.Warningf("Could not tag %s as %s: %s", img.ID, registrypath, err)
						node.PushedAt = time.Unix(0, 0)
					} else if err := l.docker.PushImage(registrypath); err != nil {
						glog.Warningf("Could not push %s: %s", registrypath, err)
						node.PushedAt = time.Unix(0, 0)
					} else {
						node.PushedAt = time.Now().UTC()
					}
					// The point here is to make sure the node triggers an
					// event regardless of whether the push was successful.
					l.conn.Set(imagepath, &node)
				}()
			} else {
				glog.Errorf("Could not find image %s: %s", node.Image.UUID, err)
			}
		}
		glog.V(1).Infof("Waiting for image %s to update (imagepath=%s)", node.Image, imagepath)
		select {
		case <-evt:
		case <-shutdown:
			return
		}

		close(done)
		done = make(chan struct{})
	}
}
697545
func (reg *Manager) Start(ctx context.Context, wg *sync.WaitGroup) error {
	defer wg.Done()

	if reg.cfg.RegistrationCollective == "" {
		reg.cfg.RegistrationCollective = reg.cfg.MainCollective
	}

	var err error
	var registrator Registrator

	for _, rtype := range reg.cfg.Registration {
		switch rtype {
		case "":
			return nil
		case "file_content":
			registrator, err = registration.NewFileContent(reg.cfg, reg.log)
			if err != nil {
				return fmt.Errorf("Cannot start File Content Registrator: %s", err)
			}
		default:
			return fmt.Errorf("Unknown registration plugin: %s", reg.cfg.Registration)
		}

		reg.log.Infof("Starting registration worker for %s", rtype)
		reg.RegisterProvider(ctx, wg, registrator)
	}

	return nil
}
91969
func (d *driverMock) WaitForImageCreation(ctx context.Context, id string) error {
	return d.WaitForImageCreationErr
}
845821
func (r *Session) PushImageChecksumRegistry(imgData *ImgData, registry string) error {
	u := registry + "images/" + imgData.ID + "/checksum"

	logrus.Debugf("[registry] Calling PUT %s", u)

	req, err := http.NewRequest("PUT", u, nil)
	if err != nil {
		return err
	}
	req.Header.Set("X-Docker-Checksum", imgData.Checksum)
	req.Header.Set("X-Docker-Checksum-Payload", imgData.ChecksumPayload)

	res, err := r.client.Do(req)
	if err != nil {
		return fmt.Errorf("Failed to upload metadata: %v", err)
	}
	defer res.Body.Close()
	if len(res.Cookies()) > 0 {
		r.client.Jar.SetCookies(req.URL, res.Cookies())
	}
	if res.StatusCode != 200 {
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return fmt.Errorf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err)
		}
		var jsonBody map[string]string
		if err := json.Unmarshal(errBody, &jsonBody); err != nil {
			errBody = []byte(err.Error())
		} else if jsonBody["error"] == "Image already exists" {
			return ErrAlreadyExists
		}
		return fmt.Errorf("HTTP code %d while uploading metadata: %q", res.StatusCode, errBody)
	}
	return nil
}
1038155
func (l *ServiceListener) Spawn(shutdown <-chan interface{}, serviceID string) {
	logger := plog.WithField("serviceid", serviceID)

	// set up the retry timer
	timer := time.NewTimer(0)
	timer.Stop()
	defer timer.Stop()

	// set up cancellable on zookeeper watches
	done := make(chan struct{})
	defer func() { close(done) }()

	for {
		// set up a watch on the service
		sDat, err := NewServiceNodeFromService(&service.Service{})
		if err != nil {
			logger.WithError(err).Debug("Could not create service node from service")
			return
		}
		sEvt, err := l.conn.GetW(l.GetPath(serviceID), sDat, done)
		if err == client.ErrNoNode {

			logger.Debug("Service deleted, listener shutting down")
			return
		} else if err != nil {

			logger.WithError(err).Error("Could not load service")
			return
		}

		logger = logger.WithFields(log.Fields{
			"servicename":      sDat.Name,
			"desiredstate":     sDat.DesiredState,
			"desiredinstances": sDat.Instances,
		})

		// clean invalid states and set up a watch on the service's states
		if err := CleanServiceStates(l.conn, l.poolid, serviceID); err != nil {

			logger.WithError(err).Error("Could not clean up invalid states on service")
			return
		}
		stateIDs, ssEvt, err := l.conn.ChildrenW(l.GetPath(serviceID), done)
		if err == client.ErrNoNode {

			logger.Debug("Service deleted, listener shutting down")
			return
		} else if err != nil {

			logger.WithError(err).Error("Could not look up states for service")
			return
		}
		reqs, ok := l.getStateRequests(logger, stateIDs)
		if !ok {
			timer.Reset(time.Second)
		}

		// set the state of these services
		dstate := service.DesiredState(sDat.DesiredState)
		switch dstate {
		case service.SVCRun:

			// Resume paused service states
			if _, ok := l.Resume(reqs); !ok {
				timer.Reset(time.Second)
			}

			// Synchronize the number of service states
			if _, ok := l.Sync(sDat.Locked, sDat, reqs); !ok {
				timer.Reset(time.Second)
			}

		case service.SVCPause:

			// Pause running service states
			if _, ok := l.Pause(reqs); !ok {
				timer.Reset(time.Second)
			}

		case service.SVCStop:

			// Stop all service states
			if _, ok := l.Stop(reqs); !ok {
				timer.Reset(time.Second)
			}

		default:
			logger.Warn("Could not process desired state for service")
		}

		logger.Debug("Waiting for service event")
		select {
		case <-sEvt:
		case <-ssEvt:
		case <-timer.C:
		case <-shutdown:

			logger.Debug("Service listener received signal to shut down")
			return
		}

		close(done)
		done = make(chan struct{})
		timer.Stop()
	}
}
1169133
func (r *Session) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, registry string) error {

	u := registry + "images/" + imgData.ID + "/json"

	logrus.Debugf("[registry] Calling PUT %s", u)

	req, err := http.NewRequest("PUT", u, bytes.NewReader(jsonRaw))
	if err != nil {
		return err
	}
	req.Header.Add("Content-type", "application/json")

	res, err := r.client.Do(req)
	if err != nil {
		return fmt.Errorf("Failed to upload metadata: %s", err)
	}
	defer res.Body.Close()
	if res.StatusCode == 401 && strings.HasPrefix(registry, "http://") {
		return newJSONError("HTTP code 401, Docker will not send auth headers over HTTP.", res)
	}
	if res.StatusCode != 200 {
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res)
		}
		var jsonBody map[string]string
		if err := json.Unmarshal(errBody, &jsonBody); err != nil {
			errBody = []byte(err.Error())
		} else if jsonBody["error"] == "Image already exists" {
			return ErrAlreadyExists
		}
		return newJSONError(fmt.Sprintf("HTTP code %d while uploading metadata: %q", res.StatusCode, errBody), res)
	}
	return nil
}
1142888
func (c *Callbacks) OnCNETMsg_SpawnGroup_LoadCompleted(fn func(*dota.CNETMsg_SpawnGroup_LoadCompleted) error) {
	c.onCNETMsg_SpawnGroup_LoadCompleted = append(c.onCNETMsg_SpawnGroup_LoadCompleted, fn)
}
730059
func (c *Callbacks) OnCNETMsg_SpawnGroup_SetCreationTick(fn func(*dota.CNETMsg_SpawnGroup_SetCreationTick) error) {
	c.onCNETMsg_SpawnGroup_SetCreationTick = append(c.onCNETMsg_SpawnGroup_SetCreationTick, fn)
}
209007
func (client *RegistryIndexClient) FindImage(image string) (*registry.Image, error) {
	image, err := client.parseImage(image)
	if err != nil {
		return nil, err
	}
	rImage, err := client.facade.GetRegistryImage(client.ctx, image)
	if datastore.IsErrNoSuchEntity(err) {
		return nil, ErrImageNotFound
	}
	return rImage, err
}
1180396
func (m *Generator) spawn(genbin string) ([]string, error) {
	var args []string
	for k, v := range m.Flags {
		if k == "debug" {
			continue
		}
		args = append(args, fmt.Sprintf("--%s=%s", k, v))
	}
	sort.Strings(args)
	args = append(args, "--version="+version.String())
	args = append(args, m.CustomFlags...)
	cmd := exec.Command(genbin, args...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("%s\n%s", err, string(out))
	}
	res := strings.Split(string(out), "\n")
	for (len(res) > 0) && (res[len(res)-1] == "") {
		res = res[:len(res)-1]
	}
	return res, nil
}
1290684
func (o *KeyServerMonitor) CreateKeyServerMonitorSeed(child *KeyServerMonitorSeed) *bambou.Error {

	return bambou.CurrentSession().CreateChild(o, child)
}
770291
func BuildImage(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
	path := p.Get("path", "").(string)
	tag := p.Get("tag", "").(string)

	log.Infof(c, "Building docker image %s (tag: %s)", path, tag)

	return buildImg(c, path, tag)
}
353139
func (d *Downloader) spawnSync(fetchers []func() error) error {
	errc := make(chan error, len(fetchers))
	d.cancelWg.Add(len(fetchers))
	for _, fn := range fetchers {
		fn := fn
		go func() { defer d.cancelWg.Done(); errc <- fn() }()
	}
	// Wait for the first error, then terminate the others.
	var err error
	for i := 0; i < len(fetchers); i++ {
		if i == len(fetchers)-1 {
			// Close the queue when all fetchers have exited.
			// This will cause the block processor to end when
			// it has processed the queue.
			d.queue.Close()
		}
		if err = <-errc; err != nil {
			break
		}
	}
	d.queue.Close()
	d.Cancel()
	return err
}
629397
func SpawnDetachedProcess(
	cmd string, args []string, _ logger.Logger) (pid int, err error) {
	var files []uintptr
	var devnull *os.File

	defer func() {
		if err != nil && devnull != nil {
			devnull.Close()
		}
	}()

	if devnull, err = os.OpenFile("/dev/null", os.O_RDONLY, 0); err != nil {
		return
	}
	nullfd := devnull.Fd()
	files = append(files, nullfd, nullfd, nullfd)

	attr := syscall.ProcAttr{
		Env:   os.Environ(),
		Sys:   &syscall.SysProcAttr{Setsid: true},
		Files: files,
	}

	pid, err = syscall.ForkExec(cmd, args, &attr)
	return pid, err
}
373541
func (i *Client) Push(c context.Context, state *PushState, source Source) (err error) {
	// This push operation may be a retry after failed finalization call below,
	// no need to reupload contents in that case.
	if !state.uploaded {
		// PUT file to uploadURL.
		if err = i.doPush(c, state, source); err != nil {
			log.Printf("doPush(%s) failed: %s\n%#v", state.digest, err, state)
			return
		}
		state.uploaded = true
	}

	// Optionally notify the server that it's done.
	if state.status.GsUploadUrl != "" {
		end := tracer.Span(i, "finalize", nil)
		defer func() { end(tracer.Args{"err": err}) }()
		// TODO(vadimsh): Calculate MD5 or CRC32C sum while uploading a file and
		// send it to isolated server. That way isolate server can verify that
		// the data safely reached Google Storage (GS provides MD5 and CRC32C of
		// stored files).
		in := isolateservice.HandlersEndpointsV1FinalizeRequest{UploadTicket: state.status.UploadTicket}
		headers := map[string]string{"Cache-Control": "public, max-age=31536000"}
		if err = i.postJSON(c, "/_ah/api/isolateservice/v1/finalize_gs_upload", headers, in, nil); err != nil {
			log.Printf("Push(%s) (finalize) failed: %s\n%#v", state.digest, err, state)
			return
		}
	}
	state.finalized = true
	return
}
929764
func (httpsender *HTTPSender) Spawn(id int) utils.Composer {
	s := *httpsender
	s.id = id

	if httpsender.Config.Logger == nil {
		s.logger = logrus.NewEntry(logrus.New())
		s.logger.Logger.Out = ioutil.Discard
	} else {
		s.logger = httpsender.Config.Logger.WithFields(logrus.Fields{
			"worker": id,
		})
	}

	if httpsender.Debug {
		s.logger.Logger.Level = logrus.DebugLevel
	}

	s.logger.Debugf("Spawning worker")

	if govalidator.IsURL(s.URL) {
		s.Client = new(http.Client)

		if httpsender.Config.Insecure {
			s.Client.Transport = &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
		}
	} else {
		s.err = errors.New("Invalid URL")
	}

	return &s
}
1028699
func (l *Limiter) Spawn(id int) utils.Composer {
	l.keepSending = make(chan struct{}, l.Config.Burst)
	if l.clk == nil {
		l.clk = clock.New()
	}

	go func() {
		for {
			<-l.clk.Timer(1 * time.Second).C
			l.keepSending <- struct{}{}
		}
	}()

	return l
}