Exemple #1
0
func TestSubscribe(t *testing.T) {
	mgr := NewEventManager()
	topic := events.NewEventType(vsphere.VMEvent{}).Topic()
	mgr.Subscribe(topic, "tester", callback)
	subs := mgr.Subscribers()
	assert.Equal(t, 1, len(subs))
	assert.Equal(t, 1, mgr.Subscribed())

	mgr.Subscribe(topic, "tester2", callback)
	subs = mgr.Subscribers()

	// should still have 1 topic
	assert.Equal(t, 1, len(subs))
	// now two subscribers for that topic
	assert.Equal(t, 2, mgr.Subscribed())

	mgr.Subscribe(events.NewEventType(&vsphere.VMEvent{}).Topic(), "tester3", callback)
	subs = mgr.Subscribers()
	// should still have 1 topic
	assert.Equal(t, 1, len(subs))
	// now two subscribers for that topic
	assert.Equal(t, 3, mgr.Subscribed())

	mgr.Unsubscribe(topic, "tester2")
	subs = mgr.Subscribers()
	// should still have 1 topic
	assert.Equal(t, 1, len(subs))
	// now two subscribers for that topic
	assert.Equal(t, 2, mgr.Subscribed())

	mgr.Unsubscribe(events.NewEventType(&vsphere.VMEvent{}).Topic(), "tester3")
	subs = mgr.Subscribers()
	// should still have 1 topic
	assert.Equal(t, 1, len(subs))
	// now one subscribers for that topic
	assert.Equal(t, 1, mgr.Subscribed())

}
Exemple #2
0
func TestPublishContainerEvent(t *testing.T) {

	NewContainerCache()
	containerEvents = make([]events.Event, 0)
	Config = Configuration{}

	mgr := event.NewEventManager()
	Config.EventManager = mgr
	mgr.Subscribe(events.NewEventType(events.ContainerEvent{}).Topic(), "testing", containerCallback)

	// create new running container and place in cache
	id := "123439"
	container := newTestContainer(id)
	addTestVM(container)
	container.SetState(StateRunning)
	Containers.Put(container)

	publishContainerEvent(id, time.Now().UTC(), events.ContainerPoweredOff)
	time.Sleep(time.Millisecond * 30)

	assert.Equal(t, 1, len(containerEvents))
	assert.Equal(t, id, containerEvents[0].Reference())
	assert.Equal(t, events.ContainerPoweredOff, containerEvents[0].String())
}
Exemple #3
0
// engageContext connects the given network context into a vsphere environment
// using an event manager, and a container cache. This hooks up a callback to
// react to vsphere events, as well as populate the context with any containers
// that are present.
func engageContext(ctx context.Context, netctx *Context, em event.EventManager) error {
	var err error

	// grab the context lock so that we do not unbind any containers
	// that stop out of band. this could cause, for example, for us
	// to bind a container when it has already been unbound by an
	// event callback
	netctx.Lock()
	defer netctx.Unlock()

	// subscribe to the event stream for Vm events
	if em == nil {
		return fmt.Errorf("event manager is required for default network context")
	}

	sub := fmt.Sprintf("%s(%p)", "netCtx", netctx)
	topic := events.NewEventType(events.ContainerEvent{}).Topic()
	em.Subscribe(topic, sub, func(ie events.Event) {
		handleEvent(netctx, ie)
	})

	defer func() {
		if err != nil {
			em.Unsubscribe(topic, sub)
		}
	}()

	for _, c := range exec.Containers.Containers(nil) {
		log.Debugf("adding container %s", c.ExecConfig.ID)
		h := c.NewHandle(ctx)
		defer h.Close()

		// add any user created networks that show up in container's config
		for n, ne := range h.ExecConfig.Networks {
			var s []*Scope
			s, err = netctx.findScopes(&n)
			if err != nil {
				if _, ok := err.(ResourceNotFoundError); !ok {
					return err
				}
			}

			if len(s) > 0 {
				continue
			}

			pools := make([]string, len(ne.Network.Pools))
			for i := range ne.Network.Pools {
				pools[i] = ne.Network.Pools[i].String()
			}

			log.Debugf("adding scope %s", n)
			if _, err = netctx.newScope(ne.Network.Type, n, &ne.Network.Gateway, ne.Network.Gateway.IP, ne.Network.Nameservers, pools); err != nil {
				return err
			}
		}

		if c.CurrentState() == exec.StateRunning {
			if _, err = netctx.bindContainer(h); err != nil {
				return err
			}
		}
	}

	return nil
}
Exemple #4
0
func (vme *VMEvent) Topic() string {
	if vme.Type == "" {
		vme.Type = events.NewEventType(vme)
	}
	return vme.Type.Topic()
}
Exemple #5
0
func Init(ctx context.Context, sess *session.Session, source extraconfig.DataSource, _ extraconfig.DataSink) error {
	initializer.once.Do(func() {
		var err error
		defer func() {
			if err != nil {
				initializer.err = err
			}
		}()
		f := find.NewFinder(sess.Vim25(), false)

		extraconfig.Decode(source, &Config)

		log.Debugf("Decoded VCH config for execution: %#v", Config)
		ccount := len(Config.ComputeResources)
		if ccount != 1 {
			err = fmt.Errorf("expected singular compute resource element, found %d", ccount)
			log.Error(err)
			return
		}

		cr := Config.ComputeResources[0]
		var r object.Reference
		r, err = f.ObjectReference(ctx, cr)
		if err != nil {
			err = fmt.Errorf("could not get resource pool or virtual app reference from %q: %s", cr.String(), err)
			log.Error(err)
			return
		}
		switch o := r.(type) {
		case *object.VirtualApp:
			Config.VirtualApp = o
			Config.ResourcePool = o.ResourcePool
		case *object.ResourcePool:
			Config.ResourcePool = o
		default:
			err = fmt.Errorf("could not get resource pool or virtual app from reference %q: object type is wrong", cr.String())
			log.Error(err)
			return
		}

		// we want to monitor the cluster, so create a vSphere Event Collector
		// The cluster managed object will either be a proper vSphere Cluster or
		// a specific host when standalone mode
		ec := vsphere.NewCollector(sess.Vim25(), sess.Cluster.Reference().String())

		// start the collection of vsphere events
		err = ec.Start()
		if err != nil {
			err = fmt.Errorf("%s failed to start: %s", ec.Name(), err)
			log.Error(err)
			return
		}

		// create the event manager &  register the existing collector
		Config.EventManager = event.NewEventManager(ec)

		// subscribe the exec layer to the event stream for Vm events
		Config.EventManager.Subscribe(events.NewEventType(vsphere.VMEvent{}).Topic(), "exec", eventCallback)
		// subscribe callback to handle vm registered event
		Config.EventManager.Subscribe(events.NewEventType(vsphere.VMEvent{}).Topic(), "registeredVMEvent", func(ie events.Event) {
			registeredVMCallback(sess, ie)
		})

		// instantiate the container cache now
		NewContainerCache()

		// Grab the AboutInfo about our host environment
		about := sess.Vim25().ServiceContent.About
		Config.VCHMhz = NCPU(ctx)
		Config.VCHMemoryLimit = MemTotal(ctx)
		Config.HostOS = about.OsType
		Config.HostOSVersion = about.Version
		Config.HostProductName = about.Name
		log.Debugf("Host - OS (%s), version (%s), name (%s)", about.OsType, about.Version, about.Name)
		log.Debugf("VCH limits - %d Mhz, %d MB", Config.VCHMhz, Config.VCHMemoryLimit)

		// sync container cache
		if err = Containers.sync(ctx, sess); err != nil {
			return
		}
	})
	return initializer.err
}