func (w *Worker) DoWork(rawEvent []byte, eventHandlers map[string]EventHandler, apiClient *client.RancherClient,
	workers chan *Worker) {
	defer func() { workers <- w }()

	event := &Event{}
	err := json.Unmarshal(rawEvent, &event)
	if err != nil {
		log.WithFields(log.Fields{
			"err": err,
		}).Error("Error unmarshalling event")
		return
	}

	if event.Name != "ping" {
		log.WithFields(log.Fields{
			"event": string(rawEvent[:]),
		}).Debug("Processing event.")
	}

	unlocker := locks.Lock(event.ResourceId)
	if unlocker == nil {
		log.WithFields(log.Fields{
			"resourceId": event.ResourceId,
		}).Debug("Resource locked. Dropping event")
		return
	}
	defer unlocker.Unlock()

	if fn, ok := eventHandlers[event.Name]; ok {
		err = fn(event, apiClient)
		if err != nil {
			log.WithFields(log.Fields{
				"eventName":  event.Name,
				"eventId":    event.Id,
				"resourceId": event.ResourceId,
				"err":        err,
			}).Error("Error processing event")

			reply := &client.Publish{
				Name:                 event.ReplyTo,
				PreviousIds:          []string{event.Id},
				Transitioning:        "error",
				TransitioningMessage: err.Error(),
			}
			_, err := apiClient.Publish.Create(reply)
			if err != nil {
				log.WithFields(log.Fields{
					"err": err,
				}).Error("Error sending error-reply")
			}
		}
	} else {
		log.WithFields(log.Fields{
			"eventName": event.Name,
		}).Warn("No event handler registered for event")
	}
}
Exemple #2
0
func (h *StartHandler) Handle(event *docker.APIEvents) error {
	// Note: event.ID == container's ID
	lock := locks.Lock("start." + event.ID)
	if lock == nil {
		log.Infof("Container locked. Can't run StartHandler. ID: [%s]", event.ID)
		return nil
	}
	defer lock.Unlock()

	c, err := h.Client.InspectContainer(event.ID)
	if err != nil {
		return err
	}

	rancherIP, err := h.getRancherIP(c)
	if err != nil {
		return err
	}

	if rancherIP == "" {
		if c.Config.Labels[RancherDns] == "true" {
			return setupResolvConf(c)
		}
		return nil
	}

	if !c.State.Running {
		log.Infof("Container [%s] not running. Can't assign IP [%s].", c.ID, rancherIP)
		return nil
	}

	pid := c.State.Pid
	log.Infof("Assigning IP [%s], ContainerId [%s], Pid [%v]", rancherIP, event.ID, pid)
	if err := configureIP(strconv.Itoa(pid), rancherIP); err != nil {
		// If it stopped running, don't return error
		c, inspectErr := h.Client.InspectContainer(event.ID)
		if inspectErr != nil {
			log.Warn("Failed to inspect container: ", event.ID, inspectErr)
			return err
		}

		if !c.State.Running {
			log.Infof("Container [%s] not running. Can't assign IP [%s].", c.ID, rancherIP)
			return nil
		}

		return err
	}

	return setupResolvConf(c)
}
Exemple #3
0
func TestLocking(t *testing.T) {
	dockerClient := prep(t)

	eventId := "fake id"
	lock := locks.Lock("start." + eventId)

	handler := &StartHandler{Client: dockerClient}
	event := &docker.APIEvents{ID: eventId}

	if err := handler.Handle(event); err != nil {
		// If the lock didn't work, this would fail because of the fake id.
		t.Fatal(err)
	}

	lock.Unlock()

	if err := handler.Handle(event); err == nil {
		// Unlocked, should return error
		t.Fatal(err)
	}
}
func (h *SendToRancherHandler) Handle(event *docker.APIEvents) error {
	// rancher_state_watcher sends a simulated event to the event router to initiate ip injection.
	// This event should not be sent.
	if event.From == simulatedEvent {
		return nil
	}

	// Note: event.ID == container's ID
	lock := locks.Lock(event.Status + event.ID)
	if lock == nil {
		log.Warnf("Container locked. Can't run SendToRancherHandler. Event: [%s], ID: [%s]", event.Status, event.ID)
		return nil
	}
	defer lock.Unlock()

	container, err := h.client.InspectContainer(event.ID)
	if err != nil {
		if _, ok := err.(*docker.NoSuchContainer); !ok {
			return err
		}
	}

	containerEvent := &rclient.ContainerEvent{
		ExternalStatus:    event.Status,
		ExternalId:        event.ID,
		ExternalFrom:      event.From,
		ExternalTimestamp: int64(event.Time),
		ReportedHostUuid:  h.hostUuid,
	}
	if container != nil {
		containerEvent.DockerInspect = container

	}

	if _, err := h.rancher.ContainerEvent.Create(containerEvent); err != nil {
		return err
	}

	return nil
}