func Deploy(sched interfaces.Scheduler, options interfaces.DependencyGraphOptions, inplace bool, stopChan <-chan struct{}) (string, error) {
	if options.FlowName == "" {
		options.FlowName = interfaces.DefaultFlowName
	}
	var task string
	if inplace {
		log.Println("Going to deploy flow:", options.FlowName)
		depGraph, err := sched.BuildDependencyGraph(options)
		if err != nil {
			return "", err
		}
		var ch <-chan struct{}
		if stopChan == nil {
			ch := make(chan struct{})
			defer close(ch)
		} else {
			ch = stopChan
		}
		depGraph.Deploy(ch)
	} else {
		log.Printf("Scheduling deployment of %s flow", options.FlowName)
		var err error
		task, err = sched.CreateDeployment(options)
		if err != nil {
			return "", err
		}
		log.Printf("Scheduled deployment task %s", task)
	}
	log.Println("Done")
	return task, nil
}
Deploy deploys the dependency graph either in-place or by creating deployment task for a standalone process
package scheduler
import (
	"log"
	"strconv"
	"strings"
	"github.com/Mirantis/k8s-AppController/pkg/client"
	"github.com/Mirantis/k8s-AppController/pkg/interfaces"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/client-go/pkg/labels"
)
type scheduler struct {
	client      client.Interface
	selector    labels.Selector
	concurrency int
}
var _ interfaces.Scheduler = &scheduler{}
func New(client client.Interface, selector labels.Selector, concurrency int) interfaces.Scheduler {
	if selector == nil {
		selector, _ = labels.Parse("")
	}
	return &scheduler{
		client:      client,
		selector:    selector,
		concurrency: concurrency,
	}
}
func (sched *scheduler) Serialize(options interfaces.DependencyGraphOptions) map[string]string {
	result := map[string]string{
		"selector":                     sched.selector.String(),
		"concurrency":                  strconv.Itoa(sched.concurrency),
		"flowName":                     options.FlowName,
		"exportedOnly":                 strconv.FormatBool(options.ExportedOnly),
		"allowUndeclaredArgs":          strconv.FormatBool(options.AllowUndeclaredArgs),
		"replicaCount":                 strconv.Itoa(options.ReplicaCount),
		"fixedNumberOfReplicas":        strconv.FormatBool(options.FixedNumberOfReplicas),
		"minReplicaCount":              strconv.Itoa(options.MinReplicaCount),
		"maxReplicaCount":              strconv.Itoa(options.MaxReplicaCount),
		"allowDeleteExternalResources": strconv.FormatBool(options.AllowDeleteExternalResources),
	}
	for key, value := range options.Args {
		result["arg."+key] = value
	}
	return result
}
func FromConfig(client client.Interface, cfg map[string]string) (interfaces.Scheduler, interfaces.DependencyGraphOptions, error) {
	var concurrency int
	var opts interfaces.DependencyGraphOptions
	var selector labels.Selector
	getters := []func() error{
		func() error { return getSelector(cfg, "selector", &selector) },
		func() error { return getInt(cfg, "concurrency", &concurrency) },
		func() error { return getString(cfg, "flowName", &opts.FlowName) },
		func() error { return getBool(cfg, "exportedOnly", &opts.ExportedOnly) },
		func() error { return getBool(cfg, "allowUndeclaredArgs", &opts.AllowDeleteExternalResources) },
		func() error { return getInt(cfg, "replicaCount", &opts.ReplicaCount) },
		func() error { return getBool(cfg, "fixedNumberOfReplicas", &opts.FixedNumberOfReplicas) },
		func() error { return getInt(cfg, "minReplicaCount", &opts.MinReplicaCount) },
		func() error { return getInt(cfg, "maxReplicaCount", &opts.MaxReplicaCount) },
		func() error { return getBool(cfg, "allowDeleteExternalResources", &opts.AllowDeleteExternalResources) },
	}
	for _, getter := range getters {
		if err := getter(); err != nil {
			return nil, opts, err
		}
	}
	opts.Args = map[string]string{}
	for key, value := range cfg {
		if strings.HasPrefix(key, "arg.") {
			opts.Args[key[4:]] = value
		}
	}
	if opts.FlowName == "" {
		opts.FlowName = interfaces.DefaultFlowName
	}
	return New(client, selector, concurrency), opts, nil
}
func getInt(cfg map[string]string, key string, out *int) (err error) {
	val := cfg[key]
	if val == "" {
		*out = 0
		return nil
	}
	*out, err = strconv.Atoi(val)
	return
}
func getBool(cfg map[string]string, key string, out *bool) (err error) {
	val := cfg[key]
	if val == "" {
		*out = false
		return nil
	}
	*out, err = strconv.ParseBool(val)
	return
}
func getString(cfg map[string]string, key string, out *string) error {
	*out = cfg[key]
	return nil
}
func getSelector(cfg map[string]string, key string, out *labels.Selector) (err error) {
	*out, err = labels.Parse(cfg[key])
	return err
}
func (sched *scheduler) CreateDeployment(options interfaces.DependencyGraphOptions) (string, error) {
	cm := &v1.ConfigMap{}
	cm.Data = sched.Serialize(options)
	cm.GenerateName = "appcontrollerdeployment-"
	cm.Labels = map[string]string{"AppController": "FlowDeployment"}
	task, err := sched.client.ConfigMaps().Create(cm)
	if err != nil {
		return "", err
	}
	return task.Name, nil
}