cord-776 create build / runtime containers for autmation uservices

Change-Id: I246973192adef56a250ffe93a5f65fff488840c1
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/LICENSE b/switchq/vendor/github.com/lunixbochs/vtclean/LICENSE
new file mode 100644
index 0000000..42e8263
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Ryan Hileman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/README.md b/switchq/vendor/github.com/lunixbochs/vtclean/README.md
new file mode 100644
index 0000000..ddd1372
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/README.md
@@ -0,0 +1,44 @@
+vtclean
+----
+
+Clean up raw terminal output by stripping escape sequences, optionally preserving color.
+
+Get it: `go get github.com/lunixbochs/vtclean/vtclean`
+
+API:
+
+    import "github.com/lunixbochs/vtclean"
+    vtclean.Clean(line string, color bool) string
+
+Command line example:
+
+    $ echo -e '\x1b[1;32mcolor example
+    color forced to stop at end of line
+    backspace is ba\b\bgood
+    no beeps!\x07\x07' | ./vtclean -color
+
+    color example
+    color forced to stop at end of line
+    backspace is good
+    no beeps!
+
+Go example:
+
+    package main
+
+    import (
+        "fmt"
+        "github.com/lunixbochs/vtclean"
+    )
+
+    func main() {
+        line := vtclean.Clean(
+            "\033[1;32mcolor, " +
+            "curs\033[Aor, " +
+            "backspace\b\b\b\b\b\b\b\b\b\b\b\033[K", false)
+        fmt.Println(line)
+    }
+
+Output:
+
+    color, cursor
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/io.go b/switchq/vendor/github.com/lunixbochs/vtclean/io.go
new file mode 100644
index 0000000..31be007
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/io.go
@@ -0,0 +1,93 @@
+package vtclean
+
+import (
+	"bufio"
+	"bytes"
+	"io"
+)
+
+type reader struct {
+	io.Reader
+	scanner *bufio.Scanner
+	buf     []byte
+
+	color bool
+}
+
+func NewReader(r io.Reader, color bool) io.Reader {
+	return &reader{Reader: r, color: color}
+}
+
+func (r *reader) scan() bool {
+	if r.scanner == nil {
+		r.scanner = bufio.NewScanner(r.Reader)
+	}
+	if len(r.buf) > 0 {
+		return true
+	}
+	if r.scanner.Scan() {
+		r.buf = []byte(Clean(r.scanner.Text(), r.color) + "\n")
+		return true
+	}
+	return false
+}
+
+func (r *reader) fill(p []byte) int {
+	n := len(r.buf)
+	copy(p, r.buf)
+	if len(p) < len(r.buf) {
+		r.buf = r.buf[len(p):]
+		n = len(p)
+	} else {
+		r.buf = nil
+	}
+	return n
+}
+
+func (r *reader) Read(p []byte) (int, error) {
+	n := r.fill(p)
+	if n < len(p) {
+		if !r.scan() {
+			if n == 0 {
+				return 0, io.EOF
+			}
+			return n, nil
+		}
+		n += r.fill(p[n:])
+	}
+	return n, nil
+}
+
+type writer struct {
+	io.Writer
+	buf   []byte
+	color bool
+}
+
+func NewWriter(w io.Writer, color bool) io.WriteCloser {
+	return &writer{Writer: w, color: color}
+}
+
+func (w *writer) Write(p []byte) (int, error) {
+	buf := append(w.buf, p...)
+	lines := bytes.Split(buf, []byte("\n"))
+	if len(lines) > 0 {
+		last := len(lines) - 1
+		w.buf = lines[last]
+		count := 0
+		for _, line := range lines[:last] {
+			n, err := w.Writer.Write([]byte(Clean(string(line), w.color) + "\n"))
+			count += n
+			if err != nil {
+				return count, err
+			}
+		}
+	}
+	return len(p), nil
+}
+
+func (w *writer) Close() error {
+	cl := Clean(string(w.buf), w.color)
+	_, err := w.Writer.Write([]byte(cl))
+	return err
+}
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/line.go b/switchq/vendor/github.com/lunixbochs/vtclean/line.go
new file mode 100644
index 0000000..7272d91
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/line.go
@@ -0,0 +1,107 @@
+package vtclean
+
+type char struct {
+	char  byte
+	vt100 []byte
+}
+
+func chars(p []byte) []char {
+	tmp := make([]char, len(p))
+	for i, v := range p {
+		tmp[i].char = v
+	}
+	return tmp
+}
+
+type lineEdit struct {
+	buf       []char
+	pos, size int
+	vt100     []byte
+}
+
+func newLineEdit(length int) *lineEdit {
+	return &lineEdit{buf: make([]char, length)}
+}
+
+func (l *lineEdit) Vt100(p []byte) {
+	l.vt100 = p
+}
+
+func (l *lineEdit) Move(x int) {
+	if x < 0 && l.pos <= -x {
+		l.pos = 0
+	} else if x > 0 && l.pos+x > l.size {
+		l.pos = l.size
+	} else {
+		l.pos += x
+	}
+}
+
+func (l *lineEdit) Write(p []byte) {
+	c := chars(p)
+	if len(c) > 0 {
+		c[0].vt100 = l.vt100
+		l.vt100 = nil
+	}
+	if len(l.buf)-l.pos < len(c) {
+		l.buf = append(l.buf[:l.pos], c...)
+	} else {
+		copy(l.buf[l.pos:], c)
+	}
+	l.pos += len(c)
+	if l.pos > l.size {
+		l.size = l.pos
+	}
+}
+
+func (l *lineEdit) Insert(p []byte) {
+	c := chars(p)
+	if len(c) > 0 {
+		c[0].vt100 = l.vt100
+		l.vt100 = nil
+	}
+	l.size += len(c)
+	c = append(c, l.buf[l.pos:]...)
+	l.buf = append(l.buf[:l.pos], c...)
+}
+
+func (l *lineEdit) Delete(n int) {
+	most := l.size - l.pos
+	if n > most {
+		n = most
+	}
+	copy(l.buf[l.pos:], l.buf[l.pos+n:])
+	l.size -= n
+}
+
+func (l *lineEdit) Clear() {
+	for i := 0; i < len(l.buf); i++ {
+		l.buf[i].char = ' '
+	}
+}
+func (l *lineEdit) ClearLeft() {
+	for i := 0; i < l.pos+1; i++ {
+		l.buf[i].char = ' '
+	}
+}
+func (l *lineEdit) ClearRight() {
+	l.size = l.pos
+}
+
+func (l *lineEdit) Bytes() []byte {
+	length := 0
+	buf := l.buf[:l.size]
+	for _, v := range buf {
+		length += 1 + len(v.vt100)
+	}
+	tmp := make([]byte, 0, length)
+	for _, v := range buf {
+		tmp = append(tmp, v.vt100...)
+		tmp = append(tmp, v.char)
+	}
+	return tmp
+}
+
+func (l *lineEdit) String() string {
+	return string(l.Bytes())
+}
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/regex.txt b/switchq/vendor/github.com/lunixbochs/vtclean/regex.txt
new file mode 100644
index 0000000..e55e7f2
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/regex.txt
@@ -0,0 +1,14 @@
+this is the source definitions for the scary escape code regex
+
+# from tests in Terminal.app, this regex should cover all basic \e[ and \e] cases
+^([\[\]]([\d\?]+)?(;[\d\?]+)*)?.
+
+# this catches any case the above does not
+# make sure to not include any special characters the main regex finds (like ?)
+\[[^a-zA-Z0-9@\?]+.
+
+# esc + paren + any single char
+[\(\)].
+
+# didn't re-check this one (not included)
+[\[K]\d+;\d+
diff --git a/switchq/vendor/github.com/lunixbochs/vtclean/vtclean.go b/switchq/vendor/github.com/lunixbochs/vtclean/vtclean.go
new file mode 100644
index 0000000..1e74237
--- /dev/null
+++ b/switchq/vendor/github.com/lunixbochs/vtclean/vtclean.go
@@ -0,0 +1,81 @@
+package vtclean
+
+import (
+	"bytes"
+	"regexp"
+	"strconv"
+)
+
+// see regex.txt for a slightly separated version of this regex
+var vt100re = regexp.MustCompile(`^\033([\[\]]([\d\?]+)?(;[\d\?]+)*)?(.)`)
+var vt100exc = regexp.MustCompile(`^\033(\[[^a-zA-Z0-9@\?]+|[\(\)]).`)
+
+func Clean(line string, color bool) string {
+	var edit = newLineEdit(len(line))
+	lineb := []byte(line)
+
+	hadColor := false
+	for i := 0; i < len(lineb); {
+		c := lineb[i]
+		switch c {
+		case '\b':
+			edit.Move(-1)
+		case '\033':
+			// set terminal title
+			if bytes.HasPrefix(lineb[i:], []byte("\x1b]0;")) {
+				pos := bytes.Index(lineb[i:], []byte("\a"))
+				if pos != -1 {
+					i += pos + 1
+					continue
+				}
+			}
+			if m := vt100exc.Find(lineb[i:]); m != nil {
+				i += len(m)
+			} else if m := vt100re.FindSubmatch(lineb[i:]); m != nil {
+				i += len(m[0])
+				num := string(m[2])
+				n, err := strconv.Atoi(num)
+				if err != nil || n > 10000 {
+					n = 1
+				}
+				switch m[4][0] {
+				case 'm':
+					if color {
+						hadColor = true
+						edit.Vt100(m[0])
+					}
+				case '@':
+					edit.Insert(bytes.Repeat([]byte{' '}, n))
+				case 'C':
+					edit.Move(n)
+				case 'D':
+					edit.Move(-n)
+				case 'P':
+					edit.Delete(n)
+				case 'K':
+					switch num {
+					case "", "0":
+						edit.ClearRight()
+					case "1":
+						edit.ClearLeft()
+					case "2":
+						edit.Clear()
+					}
+				}
+			} else {
+				i += 1
+			}
+			continue
+		default:
+			if c == '\n' || c >= ' ' {
+				edit.Write([]byte{c})
+			}
+		}
+		i += 1
+	}
+	out := edit.Bytes()
+	if hadColor {
+		out = append(out, []byte("\033[0m")...)
+	}
+	return string(out)
+}