func (c *Crew) DoOp(ctx context.Context, op *CrewOp) error {
	for mid, m := range op.Update {
		c.Logf("Crew.Do Update %s", mid)
		if err := c.SetMachine(ctx, mid, m.SpecSource, m.State); err != nil {
			return err
		}
	}
	for _, mid := range op.Delete {
		c.Logf("Crew.Do Delete %s", mid)
		if err := c.DeleteMachine(ctx, mid); err != nil {
			return err
		}
	}
	return nil
}
DoOp executes the given CrewOp.
package sio
import (
	"context"
	"encoding/json"
	"github.com/Comcast/sheens/core"
	"github.com/Comcast/sheens/crew"
	"github.com/Comcast/sheens/match"
)
var (
	CaptainMachine = "captain"
)
type CrewOp struct {
	Update map[string]*crew.Machine `json:"update,omitempty"`
	Delete []string                 `json:"delete,omitempty"`
}
func AsCrewOp(msg interface{}) (*CrewOp, error) {
	js, err := json.Marshal(&msg)
	if err != nil {
		return nil, err
	}
	var op CrewOp
	if err = json.Unmarshal(js, &op); err != nil {
		return nil, err
	}
	if op.Update == nil && op.Delete == nil {
		return nil, nil
	}
	return &op, nil
}