<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"syscall"

	"github.com/vrok/have/have"
)

// Implements PkgLocator
type FilesystemPkgLocator struct {
	gopath string
}

func NewFilesystemPkgLocator(gopath string) *FilesystemPkgLocator {
	return &FilesystemPkgLocator{gopath: gopath}
}

func (gpl *FilesystemPkgLocator) Locate(relativePath string) ([]*have.File, error) {
	var fullPkgPath = path.Join(gpl.gopath, relativePath)
	var flist, err = ioutil.ReadDir(fullPkgPath)
	if err != nil {
		return nil, err
	}

	var files []*have.File

	for _, f := range flist {
		if f.IsDir() {
			continue
		}

		if n := f.Name(); strings.HasSuffix(n, ".hav") {
			code, err := ioutil.ReadFile(path.Join(fullPkgPath, n))
			if err != nil {
				return nil, fmt.Errorf("Error reading %s: %s", n, err)
			}

			files = append(files, have.NewFile(path.Join(relativePath, f.Name()), string(code)))
		}
	}
	return files, nil
}

func paths() (gopath, srcpath string) {
	gopath = os.Getenv("GOPATH")
	if gopath == "" {
		fmt.Fprintf(os.Stderr, "GOPATH not set")
		os.Exit(1)
	}

	srcpath = os.Getenv("HAVESRCPATH")
	if srcpath == "" {
		srcpath = path.Join(gopath, "src")
	}

	return
}

func trans(args []string) {
	var pkgs, files []string
	for _, arg := range args {
		if strings.HasSuffix(arg, ".hav") {
			files = append(files, arg)
		} else {
			pkgs = append(pkgs, arg)
		}
	}

	var gopath, srcpath = paths()

	var locator = NewFilesystemPkgLocator(srcpath)

	manager := have.NewPkgManager(locator)

	for _, pkgName := range pkgs {
		pkg, errs := manager.Load(pkgName)

		for _, err := range errs {
			if compErr, ok := err.(*have.CompileError); ok {
				fmt.Fprintf(os.Stderr, "ERROR: %s\n", compErr.PrettyString(manager.Fset))
			} else {
				fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
			}
		}

		if len(errs) > 0 {
			os.Exit(1)
		}

		for _, f := range pkg.Files {
			if f.Name == have.BuiltinsFileName {
				continue
			}
			var output = f.GenerateCode()

			var fullFname = path.Join(gopath, "src", f.Name+".go")
			if strings.HasSuffix(f.Name, ".hav") {
				fullFname = path.Join(gopath, "src", f.Name[0:len(f.Name)-len("hav")]+"go")
			}

			os.MkdirAll(path.Dir(fullFname), 0744)

			var err = ioutil.WriteFile(fullFname, []byte(output), 0644)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error writing file %s: %s", fullFname, err)
				os.Exit(1)
			}
		}
	}
}

// Implements PkgLocator
type RunLocator struct {
	fpl          *FilesystemPkgLocator
	mainPkgFiles []*have.File
}

func NewRunLocator(fpl *FilesystemPkgLocator, mainFilenames []string) (*RunLocator, error) {
	var files []*have.File
	for _, f := range mainFilenames {
		code, err := ioutil.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("Error reading %s: %s", f, err)
		}

		files = append(files, have.NewFile(f, string(code)))
	}
	return &RunLocator{
		fpl:          fpl,
		mainPkgFiles: files,
	}, nil
}

func (rl *RunLocator) Locate(relativePath string) ([]*have.File, error) {
	if relativePath == "main" {
		return rl.mainPkgFiles, nil
	}
	return rl.fpl.Locate(relativePath)
}

func run(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "No source files specified\n")
		os.Exit(1)
	}

	for _, arg := range args {
		if !strings.HasSuffix(arg, ".hav") {
			fmt.Fprintf(os.Stderr, "Not a source file: %s", arg)
		}
	}

	var _, srcpath = paths()

	var locator, err = NewRunLocator(NewFilesystemPkgLocator(srcpath), args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating temporary dir: %s", err)
		os.Exit(1)
	}

	manager := have.NewPkgManager(locator)

	pkg, errs := manager.Load("main")

	for _, err := range errs {
		if compErr, ok := err.(*have.CompileError); ok {
			fmt.Fprintf(os.Stderr, "ERROR: %s\n", compErr.PrettyString(manager.Fset))
		} else {
			fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
		}
	}

	if len(errs) > 0 {
		os.Exit(1)
	}

	tmpDir, err := ioutil.TempDir("", "hav")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating temporary dir: %s", err)
		os.Exit(1)
	}
	defer os.RemoveAll(tmpDir)

	var goFiles []string

	for _, f := range pkg.Files {
		if f.Name == have.BuiltinsFileName {
			continue
		}
		var output = f.GenerateCode()

		outputPath := path.Join(tmpDir, f.Name+".go")
		ioutil.WriteFile(outputPath, []byte(output), 0600)
		goFiles = append(goFiles, outputPath)
	}

	binary, err := exec.LookPath("go")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Couldn't find go binary: %s", err)
		os.Exit(1)
	}

	env := os.Environ()

	err = syscall.Exec(binary, append([]string{"go", "run"}, goFiles...), env)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error execing go binary: %s", err)
		os.Exit(1)
	}
}

func main() {
	flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
	flag.Usage = func() {
		messages := map[string]string{
			"trans": "Translate .hav files to .go",
			"run":   "Run the translated versions of .hav files",
			"help":  "Print this help message",
		}
		fmt.Printf("Usage: have command [arguments]\n\n")
		fmt.Printf("The commands are: \n")
		for command, message := range messages {
			fmt.Printf("\t%s\t%s\n", command, message)
		}
	}
	flag.Parse()

	var args = flag.Args()

	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "Arguments missing\n")
		return
	}

	switch args[0] {
	case "trans":
		trans(args[1:])
	case "run":
		run(args[1:])
	case "help":
		flag.Usage()
	default:
		fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0])
	}
}
<commit_msg>Update command description for run<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"syscall"

	"github.com/vrok/have/have"
)

// Implements PkgLocator
type FilesystemPkgLocator struct {
	gopath string
}

func NewFilesystemPkgLocator(gopath string) *FilesystemPkgLocator {
	return &FilesystemPkgLocator{gopath: gopath}
}

func (gpl *FilesystemPkgLocator) Locate(relativePath string) ([]*have.File, error) {
	var fullPkgPath = path.Join(gpl.gopath, relativePath)
	var flist, err = ioutil.ReadDir(fullPkgPath)
	if err != nil {
		return nil, err
	}

	var files []*have.File

	for _, f := range flist {
		if f.IsDir() {
			continue
		}

		if n := f.Name(); strings.HasSuffix(n, ".hav") {
			code, err := ioutil.ReadFile(path.Join(fullPkgPath, n))
			if err != nil {
				return nil, fmt.Errorf("Error reading %s: %s", n, err)
			}

			files = append(files, have.NewFile(path.Join(relativePath, f.Name()), string(code)))
		}
	}
	return files, nil
}

func paths() (gopath, srcpath string) {
	gopath = os.Getenv("GOPATH")
	if gopath == "" {
		fmt.Fprintf(os.Stderr, "GOPATH not set")
		os.Exit(1)
	}

	srcpath = os.Getenv("HAVESRCPATH")
	if srcpath == "" {
		srcpath = path.Join(gopath, "src")
	}

	return
}

func trans(args []string) {
	var pkgs, files []string
	for _, arg := range args {
		if strings.HasSuffix(arg, ".hav") {
			files = append(files, arg)
		} else {
			pkgs = append(pkgs, arg)
		}
	}

	var gopath, srcpath = paths()

	var locator = NewFilesystemPkgLocator(srcpath)

	manager := have.NewPkgManager(locator)

	for _, pkgName := range pkgs {
		pkg, errs := manager.Load(pkgName)

		for _, err := range errs {
			if compErr, ok := err.(*have.CompileError); ok {
				fmt.Fprintf(os.Stderr, "ERROR: %s\n", compErr.PrettyString(manager.Fset))
			} else {
				fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
			}
		}

		if len(errs) > 0 {
			os.Exit(1)
		}

		for _, f := range pkg.Files {
			if f.Name == have.BuiltinsFileName {
				continue
			}
			var output = f.GenerateCode()

			var fullFname = path.Join(gopath, "src", f.Name+".go")
			if strings.HasSuffix(f.Name, ".hav") {
				fullFname = path.Join(gopath, "src", f.Name[0:len(f.Name)-len("hav")]+"go")
			}

			os.MkdirAll(path.Dir(fullFname), 0744)

			var err = ioutil.WriteFile(fullFname, []byte(output), 0644)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error writing file %s: %s", fullFname, err)
				os.Exit(1)
			}
		}
	}
}

// Implements PkgLocator
type RunLocator struct {
	fpl          *FilesystemPkgLocator
	mainPkgFiles []*have.File
}

func NewRunLocator(fpl *FilesystemPkgLocator, mainFilenames []string) (*RunLocator, error) {
	var files []*have.File
	for _, f := range mainFilenames {
		code, err := ioutil.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("Error reading %s: %s", f, err)
		}

		files = append(files, have.NewFile(f, string(code)))
	}
	return &RunLocator{
		fpl:          fpl,
		mainPkgFiles: files,
	}, nil
}

func (rl *RunLocator) Locate(relativePath string) ([]*have.File, error) {
	if relativePath == "main" {
		return rl.mainPkgFiles, nil
	}
	return rl.fpl.Locate(relativePath)
}

func run(args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "No source files specified\n")
		os.Exit(1)
	}

	for _, arg := range args {
		if !strings.HasSuffix(arg, ".hav") {
			fmt.Fprintf(os.Stderr, "Not a source file: %s", arg)
		}
	}

	var _, srcpath = paths()

	var locator, err = NewRunLocator(NewFilesystemPkgLocator(srcpath), args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating temporary dir: %s", err)
		os.Exit(1)
	}

	manager := have.NewPkgManager(locator)

	pkg, errs := manager.Load("main")

	for _, err := range errs {
		if compErr, ok := err.(*have.CompileError); ok {
			fmt.Fprintf(os.Stderr, "ERROR: %s\n", compErr.PrettyString(manager.Fset))
		} else {
			fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
		}
	}

	if len(errs) > 0 {
		os.Exit(1)
	}

	tmpDir, err := ioutil.TempDir("", "hav")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating temporary dir: %s", err)
		os.Exit(1)
	}
	defer os.RemoveAll(tmpDir)

	var goFiles []string

	for _, f := range pkg.Files {
		if f.Name == have.BuiltinsFileName {
			continue
		}
		var output = f.GenerateCode()

		outputPath := path.Join(tmpDir, f.Name+".go")
		ioutil.WriteFile(outputPath, []byte(output), 0600)
		goFiles = append(goFiles, outputPath)
	}

	binary, err := exec.LookPath("go")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Couldn't find go binary: %s", err)
		os.Exit(1)
	}

	env := os.Environ()

	err = syscall.Exec(binary, append([]string{"go", "run"}, goFiles...), env)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error execing go binary: %s", err)
		os.Exit(1)
	}
}

func main() {
	flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
	flag.Usage = func() {
		messages := map[string]string{
			"trans": "Translate .hav files to .go",
			"run":   "Translate and then run .hav files",
			"help":  "Print this help message",
		}
		fmt.Printf("Usage: have command [arguments]\n\n")
		fmt.Printf("The commands are: \n")
		for command, message := range messages {
			fmt.Printf("\t%s\t%s\n", command, message)
		}
	}
	flag.Parse()

	var args = flag.Args()

	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "Arguments missing\n")
		return
	}

	switch args[0] {
	case "trans":
		trans(args[1:])
	case "run":
		run(args[1:])
	case "help":
		flag.Usage()
	default:
		fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0])
	}
}
<|endoftext|>


<commit_before>package adeptus

import (
	"fmt"
	"regexp"
	"strings"
)

var (
	regex_xp = regexp.MustCompile(`(?i)\(?\d+xp\)?`) // Match `150xp`, `150XP` and `(150xp)`
)

type Upgrade interface {
}

type RawUpgrade struct {
	mark string
	name string
	cost string
	line int
}

// ParseUpgrade generate an upgrade from a raw line
func ParseUpgrade(line int, raw string) (RawUpgrade, error) {
	upgrade := RawUpgrade{
		line: line,
	}

	// Get the fields of the line
	fields := strings.Fields(raw)

	// The minimum number of fields is 2
	if len(fields) < 2 {
		return upgrade, fmt.Errorf("Error on line %d: expected at least mark and label.", line)
	}

	// Check that the mark is a valid one
	if !in(fields[0], []string{"*", "+", "-"}) {
		return upgrade, fmt.Errorf("Error on line %d: \"%s\" is not a valid mark (\"*\", \"+\", \"-\").", line, fields[0])
	}

	// Set the upgrade mark
	mark := fields[0]
	fields = fields[1:]

	// Check if a field seems to be a cost field
	var cost string
	for i, field := range fields {
		if !regex_xp.MatchString(field) {
			continue
		}

		cost = regexp.MustCompile(`\d+`).FindString(field)
		fields = append(fields[:i], fields[i+1:]...)
		break
	}

	// The remaining line is the name of the upgrade
	if len(fields) == 0 {
		return upgrade, fmt.Errorf("Error on line %d: name should not be empty.", line)
	}

	// Set the upgrade attributes at the end to return empty upgrade in case of error
	upgrade.mark = mark
	upgrade.cost = cost
	upgrade.name = strings.Join(fields, " ")

	return upgrade, nil
}
<commit_msg>Removes regex from upgrade.<commit_after>package adeptus

import (
	"fmt"
	"strings"
)

type Upgrade interface {
}

type RawUpgrade struct {
	mark string
	name string
	cost string
	line int
}

// ParseUpgrade generate an upgrade from a raw line
func ParseUpgrade(line int, raw string) (RawUpgrade, error) {
	upgrade := RawUpgrade{
		line: line,
	}

	// Get the fields of the line
	fields := strings.Fields(raw)

	// The minimum number of fields is 2
	if len(fields) < 2 {
		return upgrade, fmt.Errorf("Error on line %d: expected at least mark and label.", line)
	}

	// Check that the mark is a valid one
	if !in(fields[0], []string{"*", "+", "-"}) {
		return upgrade, fmt.Errorf("Error on line %d: \"%s\" is not a valid mark (\"*\", \"+\", \"-\").", line, fields[0])
	}

	// Set the upgrade mark
	mark := fields[0]
	fields = fields[1:]

	// Check if a field seems to be a cost field
	var cost string
	for i, field := range fields {

		// matches (250xp)
		if strings.HasPrefix(field, "(") && strings.HasSuffix(field, "xp)") {
			cost = strings.TrimSuffix(strings.TrimPrefix(field, "("), "xp)")
			// TODO: should be integer
			if len(cost) == 0 {
				return upgrade, fmt.Errorf("Error on line %d: xp has no value. Expected number.", line)
			}
		}

		// matches 250xp
		if strings.HasPrefix(field, "xp") {
			cost = strings.TrimSuffix(field, "xp")
			// TODO: should be integer
			if len(cost) == 0 {
				return upgrade, fmt.Errorf("Error on line %d: xp has no value. Expected number.", line)
			}
		}

		if len(cost) != 0 {
			fields = append(fields[:i], fields[i+1:]...)
			break
		}
	}

	// The remaining line is the name of the upgrade
	if len(fields) == 0 {
		return upgrade, fmt.Errorf("Error on line %d: name should not be empty.", line)
	}

	// Set the upgrade attributes at the end to return empty upgrade in case of error
	upgrade.mark = mark
	upgrade.cost = cost
	upgrade.name = strings.Join(fields, " ")

	return upgrade, nil
}
<|endoftext|>


<commit_before>package s3

import "testing"

var configTests = []struct {
	s   string
	cfg Config
}{
	{"s3://eu-central-1/bucketname", Config{
		URL:    "eu-central-1",
		Bucket: "bucketname",
	}},
	{"s3:eu-central-1/foobar", Config{
		URL:    "eu-central-1",
		Bucket: "foobar",
	}},
	{"s3:https://hostname:9999/foobar", Config{
		URL:    "https://hostname:9999",
		Bucket: "foobar",
	}},
	{"s3:http://hostname:9999/foobar", Config{
		URL:    "http://hostname:9999",
		Bucket: "foobar",
	}},
}

func TestParseConfig(t *testing.T) {
	for i, test := range configTests {
		cfg, err := ParseConfig(test.s)
		if err != nil {
			t.Errorf("test %d failed: %v", i, err)
			continue
		}

		if cfg != test.cfg {
			t.Errorf("test %d: wrong config, want:\n  %v\ngot:\n  %v",
				i, test.cfg, cfg)
			continue
		}
	}
}
<commit_msg>Fix s3 tests<commit_after>package s3

import "testing"

var configTests = []struct {
	s   string
	cfg Config
}{
	{"s3://eu-central-1/bucketname", Config{
		Endpoint: "eu-central-1",
		Bucket:   "bucketname",
	}},
	{"s3:eu-central-1/foobar", Config{
		Endpoint: "eu-central-1",
		Bucket:   "foobar",
	}},
	{"s3:https://hostname:9999/foobar", Config{
		Endpoint: "hostname:9999",
		Bucket:   "foobar",
	}},
	{"s3:http://hostname:9999/foobar", Config{
		Endpoint: "hostname:9999",
		Bucket:   "foobar",
		UseHTTP:  true,
	}},
}

func TestParseConfig(t *testing.T) {
	for i, test := range configTests {
		cfg, err := ParseConfig(test.s)
		if err != nil {
			t.Errorf("test %d failed: %v", i, err)
			continue
		}

		if cfg != test.cfg {
			t.Errorf("test %d: wrong config, want:\n  %v\ngot:\n  %v",
				i, test.cfg, cfg)
			continue
		}
	}
}
<|endoftext|>


<commit_before>package ovmanager

import (
	"fmt"
	"net"
	"strconv"
	"strings"
	"sync"

	"github.com/Sirupsen/logrus"
	"github.com/docker/libnetwork/datastore"
	"github.com/docker/libnetwork/discoverapi"
	"github.com/docker/libnetwork/driverapi"
	"github.com/docker/libnetwork/idm"
	"github.com/docker/libnetwork/netlabel"
	"github.com/docker/libnetwork/types"
)

const (
	networkType  = "overlay"
	vxlanIDStart = 4096
	vxlanIDEnd   = (1 << 24) - 1
)

type networkTable map[string]*network

type driver struct {
	config   map[string]interface{}
	networks networkTable
	store    datastore.DataStore
	vxlanIdm *idm.Idm
	sync.Mutex
}

type subnet struct {
	subnetIP *net.IPNet
	gwIP     *net.IPNet
	vni      uint32
}

type network struct {
	id      string
	driver  *driver
	subnets []*subnet
	sync.Mutex
}

// Init registers a new instance of overlay driver
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
	var err error
	c := driverapi.Capability{
		DataScope: datastore.GlobalScope,
	}

	d := &driver{
		networks: networkTable{},
		config:   config,
	}

	d.vxlanIdm, err = idm.New(nil, "vxlan-id", 1, vxlanIDEnd)
	if err != nil {
		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
	}

	return dc.RegisterDriver(networkType, d, c)
}

func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
	if id == "" {
		return nil, fmt.Errorf("invalid network id for overlay network")
	}

	if ipV4Data == nil {
		return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
	}

	n := &network{
		id:      id,
		driver:  d,
		subnets: []*subnet{},
	}

	opts := make(map[string]string)
	vxlanIDList := make([]uint32, 0, len(ipV4Data))
	for key, val := range option {
		if key == netlabel.OverlayVxlanIDList {
			logrus.Debugf("overlay network option: %s", val)
			valStrList := strings.Split(val, ",")
			for _, idStr := range valStrList {
				vni, err := strconv.Atoi(idStr)
				if err != nil {
					return nil, fmt.Errorf("invalid vxlan id value %q passed", idStr)
				}

				vxlanIDList = append(vxlanIDList, uint32(vni))
			}
		} else {
			opts[key] = val
		}
	}

	for i, ipd := range ipV4Data {
		s := &subnet{
			subnetIP: ipd.Pool,
			gwIP:     ipd.Gateway,
		}

		if len(vxlanIDList) > i {
			s.vni = vxlanIDList[i]
		}

		if err := n.obtainVxlanID(s); err != nil {
			n.releaseVxlanID()
			return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
		}

		n.subnets = append(n.subnets, s)
	}

	val := fmt.Sprintf("%d", n.subnets[0].vni)
	for _, s := range n.subnets[1:] {
		val = val + fmt.Sprintf(",%d", s.vni)
	}
	opts[netlabel.OverlayVxlanIDList] = val

	d.Lock()
	d.networks[id] = n
	d.Unlock()

	return opts, nil
}

func (d *driver) NetworkFree(id string) error {
	if id == "" {
		return fmt.Errorf("invalid network id passed while freeing overlay network")
	}

	d.Lock()
	n, ok := d.networks[id]
	d.Unlock()

	if !ok {
		return fmt.Errorf("overlay network with id %s not found", id)
	}

	// Release all vxlan IDs in one shot.
	n.releaseVxlanID()

	d.Lock()
	delete(d.networks, id)
	d.Unlock()

	return nil
}

func (n *network) obtainVxlanID(s *subnet) error {
	var (
		err error
		vni uint64
	)

	n.Lock()
	vni = uint64(s.vni)
	n.Unlock()

	if vni == 0 {
		vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd)
		if err != nil {
			return err
		}

		n.Lock()
		s.vni = uint32(vni)
		n.Unlock()
		return nil
	}

	return n.driver.vxlanIdm.GetSpecificID(vni)
}

func (n *network) releaseVxlanID() {
	n.Lock()
	vnis := make([]uint32, 0, len(n.subnets))
	for _, s := range n.subnets {
		vnis = append(vnis, s.vni)
		s.vni = 0
	}
	n.Unlock()

	for _, vni := range vnis {
		n.driver.vxlanIdm.Release(uint64(vni))
	}
}

func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
}

func (d *driver) DeleteNetwork(nid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) DeleteEndpoint(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
	return nil, types.NotImplementedErrorf("not implemented")
}

// Join method is invoked when a Sandbox is attached to an endpoint.
func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

// Leave method is invoked when a Sandbox detaches from an endpoint.
func (d *driver) Leave(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) Type() string {
	return networkType
}

// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

// DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}
<commit_msg>Create vxlan-id space from 0 instead of starting from 1<commit_after>package ovmanager

import (
	"fmt"
	"net"
	"strconv"
	"strings"
	"sync"

	"github.com/Sirupsen/logrus"
	"github.com/docker/libnetwork/datastore"
	"github.com/docker/libnetwork/discoverapi"
	"github.com/docker/libnetwork/driverapi"
	"github.com/docker/libnetwork/idm"
	"github.com/docker/libnetwork/netlabel"
	"github.com/docker/libnetwork/types"
)

const (
	networkType  = "overlay"
	vxlanIDStart = 4096
	vxlanIDEnd   = (1 << 24) - 1
)

type networkTable map[string]*network

type driver struct {
	config   map[string]interface{}
	networks networkTable
	store    datastore.DataStore
	vxlanIdm *idm.Idm
	sync.Mutex
}

type subnet struct {
	subnetIP *net.IPNet
	gwIP     *net.IPNet
	vni      uint32
}

type network struct {
	id      string
	driver  *driver
	subnets []*subnet
	sync.Mutex
}

// Init registers a new instance of overlay driver
func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
	var err error
	c := driverapi.Capability{
		DataScope: datastore.GlobalScope,
	}

	d := &driver{
		networks: networkTable{},
		config:   config,
	}

	d.vxlanIdm, err = idm.New(nil, "vxlan-id", 0, vxlanIDEnd)
	if err != nil {
		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
	}

	return dc.RegisterDriver(networkType, d, c)
}

func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
	if id == "" {
		return nil, fmt.Errorf("invalid network id for overlay network")
	}

	if ipV4Data == nil {
		return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
	}

	n := &network{
		id:      id,
		driver:  d,
		subnets: []*subnet{},
	}

	opts := make(map[string]string)
	vxlanIDList := make([]uint32, 0, len(ipV4Data))
	for key, val := range option {
		if key == netlabel.OverlayVxlanIDList {
			logrus.Debugf("overlay network option: %s", val)
			valStrList := strings.Split(val, ",")
			for _, idStr := range valStrList {
				vni, err := strconv.Atoi(idStr)
				if err != nil {
					return nil, fmt.Errorf("invalid vxlan id value %q passed", idStr)
				}

				vxlanIDList = append(vxlanIDList, uint32(vni))
			}
		} else {
			opts[key] = val
		}
	}

	for i, ipd := range ipV4Data {
		s := &subnet{
			subnetIP: ipd.Pool,
			gwIP:     ipd.Gateway,
		}

		if len(vxlanIDList) > i {
			s.vni = vxlanIDList[i]
		}

		if err := n.obtainVxlanID(s); err != nil {
			n.releaseVxlanID()
			return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
		}

		n.subnets = append(n.subnets, s)
	}

	val := fmt.Sprintf("%d", n.subnets[0].vni)
	for _, s := range n.subnets[1:] {
		val = val + fmt.Sprintf(",%d", s.vni)
	}
	opts[netlabel.OverlayVxlanIDList] = val

	d.Lock()
	d.networks[id] = n
	d.Unlock()

	return opts, nil
}

func (d *driver) NetworkFree(id string) error {
	if id == "" {
		return fmt.Errorf("invalid network id passed while freeing overlay network")
	}

	d.Lock()
	n, ok := d.networks[id]
	d.Unlock()

	if !ok {
		return fmt.Errorf("overlay network with id %s not found", id)
	}

	// Release all vxlan IDs in one shot.
	n.releaseVxlanID()

	d.Lock()
	delete(d.networks, id)
	d.Unlock()

	return nil
}

func (n *network) obtainVxlanID(s *subnet) error {
	var (
		err error
		vni uint64
	)

	n.Lock()
	vni = uint64(s.vni)
	n.Unlock()

	if vni == 0 {
		vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd)
		if err != nil {
			return err
		}

		n.Lock()
		s.vni = uint32(vni)
		n.Unlock()
		return nil
	}

	return n.driver.vxlanIdm.GetSpecificID(vni)
}

func (n *network) releaseVxlanID() {
	n.Lock()
	vnis := make([]uint32, 0, len(n.subnets))
	for _, s := range n.subnets {
		vnis = append(vnis, s.vni)
		s.vni = 0
	}
	n.Unlock()

	for _, vni := range vnis {
		n.driver.vxlanIdm.Release(uint64(vni))
	}
}

func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
}

func (d *driver) DeleteNetwork(nid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) DeleteEndpoint(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
	return nil, types.NotImplementedErrorf("not implemented")
}

// Join method is invoked when a Sandbox is attached to an endpoint.
func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

// Leave method is invoked when a Sandbox detaches from an endpoint.
func (d *driver) Leave(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) Type() string {
	return networkType
}

// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

// DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
	return types.NotImplementedErrorf("not implemented")
}

func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
	return types.NotImplementedErrorf("not implemented")
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"errors"
	"fmt"
	"io"
	"os"

	"github.com/spf13/cobra"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/client-go/kubernetes"

	"k8s.io/helm/cmd/helm/installer"
	"k8s.io/helm/pkg/getter"
	"k8s.io/helm/pkg/helm/helmpath"
	"k8s.io/helm/pkg/repo"
)

const initDesc = `
This command installs Tiller (the Helm server-side component) onto your
Kubernetes Cluster and sets up local configuration in $HELM_HOME (default ~/.helm/).

As with the rest of the Helm commands, 'helm init' discovers Kubernetes clusters
by reading $KUBECONFIG (default '~/.kube/config') and using the default context.

To set up just a local environment, use '--client-only'. That will configure
$HELM_HOME, but not attempt to connect to a Kubernetes cluster and install the Tiller
deployment.

When installing Tiller, 'helm init' will attempt to install the latest released
version. You can specify an alternative image with '--tiller-image'. For those
frequently working on the latest code, the flag '--canary-image' will install
the latest pre-release version of Tiller (e.g. the HEAD commit in the GitHub
repository on the master branch).

To dump a manifest containing the Tiller deployment YAML, combine the
'--dry-run' and '--debug' flags.
`

const (
	stableRepository         = "stable"
	localRepository          = "local"
	localRepositoryIndexFile = "index.yaml"
)

var (
	stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
	// This is the IPv4 loopback, not localhost, because we have to force IPv4
	// for Dockerized Helm: https://github.com/kubernetes/helm/issues/1410
	localRepositoryURL = "http://127.0.0.1:8879/charts"
)

type initCmd struct {
	image          string
	clientOnly     bool
	canary         bool
	upgrade        bool
	namespace      string
	dryRun         bool
	skipRefresh    bool
	out            io.Writer
	home           helmpath.Home
	opts           installer.Options
	kubeClient     kubernetes.Interface
	serviceAccount string
}

func newInitCmd(out io.Writer) *cobra.Command {
	i := &initCmd{
		out: out,
	}

	cmd := &cobra.Command{
		Use:   "init",
		Short: "initialize Helm on both client and server",
		Long:  initDesc,
		RunE: func(cmd *cobra.Command, args []string) error {
			if len(args) != 0 {
				return errors.New("This command does not accept arguments")
			}
			i.namespace = settings.TillerNamespace
			i.home = settings.Home
			return i.run()
		},
	}

	f := cmd.Flags()
	f.StringVarP(&i.image, "tiller-image", "i", "", "override Tiller image")
	f.BoolVar(&i.canary, "canary-image", false, "use the canary Tiller image")
	f.BoolVar(&i.upgrade, "upgrade", false, "upgrade if Tiller is already installed")
	f.BoolVarP(&i.clientOnly, "client-only", "c", false, "if set does not install Tiller")
	f.BoolVar(&i.dryRun, "dry-run", false, "do not install local or remote")
	f.BoolVar(&i.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")

	f.BoolVar(&tlsEnable, "tiller-tls", false, "install Tiller with TLS enabled")
	f.BoolVar(&tlsVerify, "tiller-tls-verify", false, "install Tiller with TLS enabled and to verify remote certificates")
	f.StringVar(&tlsKeyFile, "tiller-tls-key", "", "path to TLS key file to install with Tiller")
	f.StringVar(&tlsCertFile, "tiller-tls-cert", "", "path to TLS certificate file to install with Tiller")
	f.StringVar(&tlsCaCertFile, "tls-ca-cert", "", "path to CA root certificate")

	f.StringVar(&stableRepositoryURL, "stable-repo-url", stableRepositoryURL, "URL for stable repository")
	f.StringVar(&localRepositoryURL, "local-repo-url", localRepositoryURL, "URL for local repository")

	f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install Tiller with net=host")
	f.StringVar(&i.serviceAccount, "service-account", "", "name of service account")

	return cmd
}

// tlsOptions sanitizes the tls flags as well as checks for the existence of required
// tls files indicated by those flags, if any.
func (i *initCmd) tlsOptions() error {
	i.opts.EnableTLS = tlsEnable || tlsVerify
	i.opts.VerifyTLS = tlsVerify

	if i.opts.EnableTLS {
		missing := func(file string) bool {
			_, err := os.Stat(file)
			return os.IsNotExist(err)
		}
		if i.opts.TLSKeyFile = tlsKeyFile; i.opts.TLSKeyFile == "" || missing(i.opts.TLSKeyFile) {
			return errors.New("missing required TLS key file")
		}
		if i.opts.TLSCertFile = tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) {
			return errors.New("missing required TLS certificate file")
		}
		if i.opts.VerifyTLS {
			if i.opts.TLSCaCertFile = tlsCaCertFile; i.opts.TLSCaCertFile == "" || missing(i.opts.TLSCaCertFile) {
				return errors.New("missing required TLS CA file")
			}
		}
	}
	return nil
}

// run initializes local config and installs Tiller to Kubernetes cluster.
func (i *initCmd) run() error {
	if err := i.tlsOptions(); err != nil {
		return err
	}
	i.opts.Namespace = i.namespace
	i.opts.UseCanary = i.canary
	i.opts.ImageSpec = i.image
	i.opts.ServiceAccount = i.serviceAccount

	if settings.Debug {
		writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error {
			w := i.out
			if !first {
				// YAML starting document boundary marker
				if _, err := fmt.Fprintln(w, "---"); err != nil {
					return err
				}
			}
			if _, err := fmt.Fprintln(w, "apiVersion:", apiVersion); err != nil {
				return err
			}
			if _, err := fmt.Fprintln(w, "kind:", kind); err != nil {
				return err
			}
			if _, err := fmt.Fprint(w, body); err != nil {
				return err
			}
			if !last {
				return nil
			}
			// YAML ending document boundary marker
			_, err := fmt.Fprintln(w, "...")
			return err
		}

		var body string
		var err error

		// write Deployment manifest
		if body, err = installer.DeploymentManifest(&i.opts); err != nil {
			return err
		}
		if err := writeYAMLManifest("extensions/v1beta1", "Deployment", body, true, false); err != nil {
			return err
		}

		// write Service manifest
		if body, err = installer.ServiceManifest(i.namespace); err != nil {
			return err
		}
		if err := writeYAMLManifest("v1", "Service", body, false, !i.opts.EnableTLS); err != nil {
			return err
		}

		// write Secret manifest
		if i.opts.EnableTLS {
			if body, err = installer.SecretManifest(&i.opts); err != nil {
				return err
			}
			if err := writeYAMLManifest("v1", "Secret", body, false, true); err != nil {
				return err
			}
		}
	}

	if i.dryRun {
		return nil
	}

	if err := ensureDirectories(i.home, i.out); err != nil {
		return err
	}
	if err := ensureDefaultRepos(i.home, i.out, i.skipRefresh); err != nil {
		return err
	}
	if err := ensureRepoFileFormat(i.home.RepositoryFile(), i.out); err != nil {
		return err
	}
	fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home)

	if !i.clientOnly {
		if i.kubeClient == nil {
			_, c, err := getKubeClient(kubeContext)
			if err != nil {
				return fmt.Errorf("could not get kubernetes client: %s", err)
			}
			i.kubeClient = c
		}
		if err := installer.Install(i.kubeClient, &i.opts); err != nil {
			if !apierrors.IsAlreadyExists(err) {
				return fmt.Errorf("error installing: %s", err)
			}
			if i.upgrade {
				if err := installer.Upgrade(i.kubeClient, &i.opts); err != nil {
					return fmt.Errorf("error when upgrading: %s", err)
				}
				fmt.Fprintln(i.out, "\nTiller (the helm server-side component) has been upgraded to the current version.")
			} else {
				fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster.\n"+
					"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)")
			}
		} else {
			fmt.Fprintln(i.out, "\nTiller (the helm server-side component) has been installed into your Kubernetes Cluster.")
		}
	} else {
		fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set")
	}

	fmt.Fprintln(i.out, "Happy Helming!")
	return nil
}

// ensureDirectories checks to see if $HELM_HOME exists.
//
// If $HELM_HOME does not exist, this function will create it.
func ensureDirectories(home helmpath.Home, out io.Writer) error {
	configDirectories := []string{
		home.String(),
		home.Repository(),
		home.Cache(),
		home.LocalRepository(),
		home.Plugins(),
		home.Starters(),
		home.Archive(),
	}
	for _, p := range configDirectories {
		if fi, err := os.Stat(p); err != nil {
			fmt.Fprintf(out, "Creating %s \n", p)
			if err := os.MkdirAll(p, 0755); err != nil {
				return fmt.Errorf("Could not create %s: %s", p, err)
			}
		} else if !fi.IsDir() {
			return fmt.Errorf("%s must be a directory", p)
		}
	}

	return nil
}

func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) error {
	repoFile := home.RepositoryFile()
	if fi, err := os.Stat(repoFile); err != nil {
		fmt.Fprintf(out, "Creating %s \n", repoFile)
		f := repo.NewRepoFile()
		sr, err := initStableRepo(home.CacheIndex(stableRepository), skipRefresh)
		if err != nil {
			return err
		}
		lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"))
		if err != nil {
			return err
		}
		f.Add(sr)
		f.Add(lr)
		if err := f.WriteFile(repoFile, 0644); err != nil {
			return err
		}
	} else if fi.IsDir() {
		return fmt.Errorf("%s must be a file, not a directory", repoFile)
	}
	return nil
}

func initStableRepo(cacheFile string, skipRefresh bool) (*repo.Entry, error) {
	c := repo.Entry{
		Name:  stableRepository,
		URL:   stableRepositoryURL,
		Cache: cacheFile,
	}
	r, err := repo.NewChartRepository(&c, getter.All(settings))
	if err != nil {
		return nil, err
	}

	if skipRefresh {
		return &c, nil
	}

	// In this case, the cacheFile is always absolute. So passing empty string
	// is safe.
	if err := r.DownloadIndexFile(""); err != nil {
		return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", stableRepositoryURL, err.Error())
	}

	return &c, nil
}

func initLocalRepo(indexFile, cacheFile string) (*repo.Entry, error) {
	if fi, err := os.Stat(indexFile); err != nil {
		i := repo.NewIndexFile()
		if err := i.WriteFile(indexFile, 0644); err != nil {
			return nil, err
		}

		//TODO: take this out and replace with helm update functionality
		os.Symlink(indexFile, cacheFile)
	} else if fi.IsDir() {
		return nil, fmt.Errorf("%s must be a file, not a directory", indexFile)
	}

	return &repo.Entry{
		Name:  localRepository,
		URL:   localRepositoryURL,
		Cache: cacheFile,
	}, nil
}

func ensureRepoFileFormat(file string, out io.Writer) error {
	r, err := repo.LoadRepositoriesFile(file)
	if err == repo.ErrRepoOutOfDate {
		fmt.Fprintln(out, "Updating repository file format...")
		if err := r.WriteFile(file, 0644); err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>Capitalize 'helm' text in init.go.<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"errors"
	"fmt"
	"io"
	"os"

	"github.com/spf13/cobra"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/client-go/kubernetes"

	"k8s.io/helm/cmd/helm/installer"
	"k8s.io/helm/pkg/getter"
	"k8s.io/helm/pkg/helm/helmpath"
	"k8s.io/helm/pkg/repo"
)

const initDesc = `
This command installs Tiller (the Helm server-side component) onto your
Kubernetes Cluster and sets up local configuration in $HELM_HOME (default ~/.helm/).

As with the rest of the Helm commands, 'helm init' discovers Kubernetes clusters
by reading $KUBECONFIG (default '~/.kube/config') and using the default context.

To set up just a local environment, use '--client-only'. That will configure
$HELM_HOME, but not attempt to connect to a Kubernetes cluster and install the Tiller
deployment.

When installing Tiller, 'helm init' will attempt to install the latest released
version. You can specify an alternative image with '--tiller-image'. For those
frequently working on the latest code, the flag '--canary-image' will install
the latest pre-release version of Tiller (e.g. the HEAD commit in the GitHub
repository on the master branch).

To dump a manifest containing the Tiller deployment YAML, combine the
'--dry-run' and '--debug' flags.
`

const (
	stableRepository         = "stable"
	localRepository          = "local"
	localRepositoryIndexFile = "index.yaml"
)

var (
	stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
	// This is the IPv4 loopback, not localhost, because we have to force IPv4
	// for Dockerized Helm: https://github.com/kubernetes/helm/issues/1410
	localRepositoryURL = "http://127.0.0.1:8879/charts"
)

type initCmd struct {
	image          string
	clientOnly     bool
	canary         bool
	upgrade        bool
	namespace      string
	dryRun         bool
	skipRefresh    bool
	out            io.Writer
	home           helmpath.Home
	opts           installer.Options
	kubeClient     kubernetes.Interface
	serviceAccount string
}

func newInitCmd(out io.Writer) *cobra.Command {
	i := &initCmd{
		out: out,
	}

	cmd := &cobra.Command{
		Use:   "init",
		Short: "initialize Helm on both client and server",
		Long:  initDesc,
		RunE: func(cmd *cobra.Command, args []string) error {
			if len(args) != 0 {
				return errors.New("This command does not accept arguments")
			}
			i.namespace = settings.TillerNamespace
			i.home = settings.Home
			return i.run()
		},
	}

	f := cmd.Flags()
	f.StringVarP(&i.image, "tiller-image", "i", "", "override Tiller image")
	f.BoolVar(&i.canary, "canary-image", false, "use the canary Tiller image")
	f.BoolVar(&i.upgrade, "upgrade", false, "upgrade if Tiller is already installed")
	f.BoolVarP(&i.clientOnly, "client-only", "c", false, "if set does not install Tiller")
	f.BoolVar(&i.dryRun, "dry-run", false, "do not install local or remote")
	f.BoolVar(&i.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")

	f.BoolVar(&tlsEnable, "tiller-tls", false, "install Tiller with TLS enabled")
	f.BoolVar(&tlsVerify, "tiller-tls-verify", false, "install Tiller with TLS enabled and to verify remote certificates")
	f.StringVar(&tlsKeyFile, "tiller-tls-key", "", "path to TLS key file to install with Tiller")
	f.StringVar(&tlsCertFile, "tiller-tls-cert", "", "path to TLS certificate file to install with Tiller")
	f.StringVar(&tlsCaCertFile, "tls-ca-cert", "", "path to CA root certificate")

	f.StringVar(&stableRepositoryURL, "stable-repo-url", stableRepositoryURL, "URL for stable repository")
	f.StringVar(&localRepositoryURL, "local-repo-url", localRepositoryURL, "URL for local repository")

	f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install Tiller with net=host")
	f.StringVar(&i.serviceAccount, "service-account", "", "name of service account")

	return cmd
}

// tlsOptions sanitizes the tls flags as well as checks for the existence of required
// tls files indicated by those flags, if any.
func (i *initCmd) tlsOptions() error {
	i.opts.EnableTLS = tlsEnable || tlsVerify
	i.opts.VerifyTLS = tlsVerify

	if i.opts.EnableTLS {
		missing := func(file string) bool {
			_, err := os.Stat(file)
			return os.IsNotExist(err)
		}
		if i.opts.TLSKeyFile = tlsKeyFile; i.opts.TLSKeyFile == "" || missing(i.opts.TLSKeyFile) {
			return errors.New("missing required TLS key file")
		}
		if i.opts.TLSCertFile = tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) {
			return errors.New("missing required TLS certificate file")
		}
		if i.opts.VerifyTLS {
			if i.opts.TLSCaCertFile = tlsCaCertFile; i.opts.TLSCaCertFile == "" || missing(i.opts.TLSCaCertFile) {
				return errors.New("missing required TLS CA file")
			}
		}
	}
	return nil
}

// run initializes local config and installs Tiller to Kubernetes cluster.
func (i *initCmd) run() error {
	if err := i.tlsOptions(); err != nil {
		return err
	}
	i.opts.Namespace = i.namespace
	i.opts.UseCanary = i.canary
	i.opts.ImageSpec = i.image
	i.opts.ServiceAccount = i.serviceAccount

	if settings.Debug {
		writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error {
			w := i.out
			if !first {
				// YAML starting document boundary marker
				if _, err := fmt.Fprintln(w, "---"); err != nil {
					return err
				}
			}
			if _, err := fmt.Fprintln(w, "apiVersion:", apiVersion); err != nil {
				return err
			}
			if _, err := fmt.Fprintln(w, "kind:", kind); err != nil {
				return err
			}
			if _, err := fmt.Fprint(w, body); err != nil {
				return err
			}
			if !last {
				return nil
			}
			// YAML ending document boundary marker
			_, err := fmt.Fprintln(w, "...")
			return err
		}

		var body string
		var err error

		// write Deployment manifest
		if body, err = installer.DeploymentManifest(&i.opts); err != nil {
			return err
		}
		if err := writeYAMLManifest("extensions/v1beta1", "Deployment", body, true, false); err != nil {
			return err
		}

		// write Service manifest
		if body, err = installer.ServiceManifest(i.namespace); err != nil {
			return err
		}
		if err := writeYAMLManifest("v1", "Service", body, false, !i.opts.EnableTLS); err != nil {
			return err
		}

		// write Secret manifest
		if i.opts.EnableTLS {
			if body, err = installer.SecretManifest(&i.opts); err != nil {
				return err
			}
			if err := writeYAMLManifest("v1", "Secret", body, false, true); err != nil {
				return err
			}
		}
	}

	if i.dryRun {
		return nil
	}

	if err := ensureDirectories(i.home, i.out); err != nil {
		return err
	}
	if err := ensureDefaultRepos(i.home, i.out, i.skipRefresh); err != nil {
		return err
	}
	if err := ensureRepoFileFormat(i.home.RepositoryFile(), i.out); err != nil {
		return err
	}
	fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home)

	if !i.clientOnly {
		if i.kubeClient == nil {
			_, c, err := getKubeClient(kubeContext)
			if err != nil {
				return fmt.Errorf("could not get kubernetes client: %s", err)
			}
			i.kubeClient = c
		}
		if err := installer.Install(i.kubeClient, &i.opts); err != nil {
			if !apierrors.IsAlreadyExists(err) {
				return fmt.Errorf("error installing: %s", err)
			}
			if i.upgrade {
				if err := installer.Upgrade(i.kubeClient, &i.opts); err != nil {
					return fmt.Errorf("error when upgrading: %s", err)
				}
				fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been upgraded to the current version.")
			} else {
				fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster.\n"+
					"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)")
			}
		} else {
			fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.")
		}
	} else {
		fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set")
	}

	fmt.Fprintln(i.out, "Happy Helming!")
	return nil
}

// ensureDirectories checks to see if $HELM_HOME exists.
//
// If $HELM_HOME does not exist, this function will create it.
func ensureDirectories(home helmpath.Home, out io.Writer) error {
	configDirectories := []string{
		home.String(),
		home.Repository(),
		home.Cache(),
		home.LocalRepository(),
		home.Plugins(),
		home.Starters(),
		home.Archive(),
	}
	for _, p := range configDirectories {
		if fi, err := os.Stat(p); err != nil {
			fmt.Fprintf(out, "Creating %s \n", p)
			if err := os.MkdirAll(p, 0755); err != nil {
				return fmt.Errorf("Could not create %s: %s", p, err)
			}
		} else if !fi.IsDir() {
			return fmt.Errorf("%s must be a directory", p)
		}
	}

	return nil
}

func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) error {
	repoFile := home.RepositoryFile()
	if fi, err := os.Stat(repoFile); err != nil {
		fmt.Fprintf(out, "Creating %s \n", repoFile)
		f := repo.NewRepoFile()
		sr, err := initStableRepo(home.CacheIndex(stableRepository), skipRefresh)
		if err != nil {
			return err
		}
		lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"))
		if err != nil {
			return err
		}
		f.Add(sr)
		f.Add(lr)
		if err := f.WriteFile(repoFile, 0644); err != nil {
			return err
		}
	} else if fi.IsDir() {
		return fmt.Errorf("%s must be a file, not a directory", repoFile)
	}
	return nil
}

func initStableRepo(cacheFile string, skipRefresh bool) (*repo.Entry, error) {
	c := repo.Entry{
		Name:  stableRepository,
		URL:   stableRepositoryURL,
		Cache: cacheFile,
	}
	r, err := repo.NewChartRepository(&c, getter.All(settings))
	if err != nil {
		return nil, err
	}

	if skipRefresh {
		return &c, nil
	}

	// In this case, the cacheFile is always absolute. So passing empty string
	// is safe.
	if err := r.DownloadIndexFile(""); err != nil {
		return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", stableRepositoryURL, err.Error())
	}

	return &c, nil
}

func initLocalRepo(indexFile, cacheFile string) (*repo.Entry, error) {
	if fi, err := os.Stat(indexFile); err != nil {
		i := repo.NewIndexFile()
		if err := i.WriteFile(indexFile, 0644); err != nil {
			return nil, err
		}

		//TODO: take this out and replace with helm update functionality
		os.Symlink(indexFile, cacheFile)
	} else if fi.IsDir() {
		return nil, fmt.Errorf("%s must be a file, not a directory", indexFile)
	}

	return &repo.Entry{
		Name:  localRepository,
		URL:   localRepositoryURL,
		Cache: cacheFile,
	}, nil
}

func ensureRepoFileFormat(file string, out io.Writer) error {
	r, err := repo.LoadRepositoriesFile(file)
	if err == repo.ErrRepoOutOfDate {
		fmt.Fprintln(out, "Updating repository file format...")
		if err := r.WriteFile(file, 0644); err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package velocity

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"time"

	"github.com/gosimple/slug"
	"golang.org/x/crypto/ssh"
	git "gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/transport"
	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
)

type Clone struct {
	BaseStep      `yaml:",inline"`
	GitRepository GitRepository `json:"-" yaml:"-"`
	CommitHash    string        `json:"-" yaml:"-"`
	Submodule     bool          `json:"submodule" yaml:"submodule"`
}

func NewClone() *Clone {
	return &Clone{
		Submodule: false,
		BaseStep: BaseStep{
			Type:          "clone",
			OutputStreams: []string{"clone"},
		},
	}
}

func (c Clone) GetDetails() string {
	return fmt.Sprintf("submodule: %v", c.Submodule)
}

func (c *Clone) Execute(emitter Emitter, params map[string]Parameter) error {
	emitter.SetStreamName("clone")
	emitter.SetStatus(StateRunning)
	emitter.Write([]byte(fmt.Sprintf("%s\n## %s\n\x1b[0m", infoANSI, c.Description)))

	emitter.Write([]byte(fmt.Sprintf("Cloning %s", c.GitRepository.Address)))

	repo, dir, err := GitClone(&c.GitRepository, false, true, c.Submodule, emitter)
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Println("Done.")
	// defer os.RemoveAll(dir)

	w, err := repo.Worktree()
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Printf("Checking out %s", c.CommitHash)
	err = w.Checkout(&git.CheckoutOptions{
		Hash: plumbing.NewHash(c.CommitHash),
	})
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Println("Done.")

	os.Chdir(dir)
	emitter.SetStatus(StateSuccess)
	emitter.Write([]byte(fmt.Sprintf("%s\n### SUCCESS \x1b[0m", successANSI)))
	return nil
}

func (cdB *Clone) Validate(params map[string]Parameter) error {
	return nil
}

func (c *Clone) SetParams(params map[string]Parameter) error {
	return nil
}

func (c *Clone) SetGitRepositoryAndCommitHash(r GitRepository, hash string) error {
	c.GitRepository = r
	c.CommitHash = hash
	return nil
}

type SSHKeyError string

func (s SSHKeyError) Error() string {
	return string(s)
}

type GitRepository struct {
	Address    string `json:"address"`
	PrivateKey string `json:"privateKey"`
}

func GitClone(
	r *GitRepository,
	bare bool,
	full bool,
	submodule bool,
	emitter Emitter,
) (*git.Repository, string, error) {
	psuedoRandom := rand.NewSource(time.Now().UnixNano())
	randNumber := rand.New(psuedoRandom)
	dir := fmt.Sprintf("/tmp/velocity-workspace/velocity_%s-%d", slug.Make(r.Address), randNumber.Int63())
	os.RemoveAll(dir)
	err := os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		log.Fatal(err)
		return nil, "", err
	}

	isGit := r.Address[:3] == "git"

	var auth transport.AuthMethod

	if isGit {
		log.Printf("git repository: %s", r.Address)
		signer, err := ssh.ParsePrivateKey([]byte(r.PrivateKey))
		if err != nil {
			os.RemoveAll(dir)
			return nil, "", SSHKeyError(err.Error())
		}
		auth = &gitssh.PublicKeys{User: "git", Signer: signer}
	}

	cloneOpts := &git.CloneOptions{
		URL:      r.Address,
		Auth:     auth,
		Progress: emitter,
	}

	if !full {
		cloneOpts.Depth = 1
	}

	if submodule {
		cloneOpts.RecurseSubmodules = 5
	}

	repo, err := git.PlainClone(dir, bare, cloneOpts)

	if err != nil {
		os.RemoveAll(dir)
		return nil, "", err
	}

	if !bare {
		w, _ := repo.Worktree()
		status, _ := w.Status()

		log.Println(status.String())
		w.Reset(&git.ResetOptions{
			Mode: git.HardReset,
		})
	}

	return repo, dir, nil
}
<commit_msg>[backend] Added cloning description<commit_after>package velocity

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"time"

	"github.com/gosimple/slug"
	"golang.org/x/crypto/ssh"
	git "gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/transport"
	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
)

type Clone struct {
	BaseStep      `yaml:",inline"`
	GitRepository GitRepository `json:"-" yaml:"-"`
	CommitHash    string        `json:"-" yaml:"-"`
	Submodule     bool          `json:"submodule" yaml:"submodule"`
}

func NewClone() *Clone {
	return &Clone{
		Submodule: false,
		BaseStep: BaseStep{
			Type:          "clone",
			OutputStreams: []string{"clone"},
		},
	}
}

func (c Clone) GetDetails() string {
	return fmt.Sprintf("submodule: %v", c.Submodule)
}

func (c *Clone) Execute(emitter Emitter, params map[string]Parameter) error {
	emitter.SetStreamName("clone")
	emitter.SetStatus(StateRunning)
	emitter.Write([]byte(fmt.Sprintf("%s\n## Cloning %s\n\x1b[0m", infoANSI, c.GitRepository.Address)))

	emitter.Write([]byte(fmt.Sprintf("Cloning %s", c.GitRepository.Address)))

	repo, dir, err := GitClone(&c.GitRepository, false, true, c.Submodule, emitter)
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Println("Done.")
	// defer os.RemoveAll(dir)

	w, err := repo.Worktree()
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Printf("Checking out %s", c.CommitHash)
	err = w.Checkout(&git.CheckoutOptions{
		Hash: plumbing.NewHash(c.CommitHash),
	})
	if err != nil {
		log.Println(err)
		emitter.SetStatus(StateFailed)
		emitter.Write([]byte(fmt.Sprintf("%s\n### FAILED: %s \x1b[0m", errorANSI, err)))
		return err
	}
	log.Println("Done.")

	os.Chdir(dir)
	emitter.SetStatus(StateSuccess)
	emitter.Write([]byte(fmt.Sprintf("%s\n### SUCCESS \x1b[0m", successANSI)))
	return nil
}

func (cdB *Clone) Validate(params map[string]Parameter) error {
	return nil
}

func (c *Clone) SetParams(params map[string]Parameter) error {
	return nil
}

func (c *Clone) SetGitRepositoryAndCommitHash(r GitRepository, hash string) error {
	c.GitRepository = r
	c.CommitHash = hash
	return nil
}

type SSHKeyError string

func (s SSHKeyError) Error() string {
	return string(s)
}

type GitRepository struct {
	Address    string `json:"address"`
	PrivateKey string `json:"privateKey"`
}

func GitClone(
	r *GitRepository,
	bare bool,
	full bool,
	submodule bool,
	emitter Emitter,
) (*git.Repository, string, error) {
	psuedoRandom := rand.NewSource(time.Now().UnixNano())
	randNumber := rand.New(psuedoRandom)
	dir := fmt.Sprintf("/tmp/velocity-workspace/velocity_%s-%d", slug.Make(r.Address), randNumber.Int63())
	os.RemoveAll(dir)
	err := os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		log.Fatal(err)
		return nil, "", err
	}

	isGit := r.Address[:3] == "git"

	var auth transport.AuthMethod

	if isGit {
		log.Printf("git repository: %s", r.Address)
		signer, err := ssh.ParsePrivateKey([]byte(r.PrivateKey))
		if err != nil {
			os.RemoveAll(dir)
			return nil, "", SSHKeyError(err.Error())
		}
		auth = &gitssh.PublicKeys{User: "git", Signer: signer}
	}

	cloneOpts := &git.CloneOptions{
		URL:      r.Address,
		Auth:     auth,
		Progress: emitter,
	}

	if !full {
		cloneOpts.Depth = 1
	}

	if submodule {
		cloneOpts.RecurseSubmodules = 5
	}

	repo, err := git.PlainClone(dir, bare, cloneOpts)

	if err != nil {
		os.RemoveAll(dir)
		return nil, "", err
	}

	if !bare {
		w, _ := repo.Worktree()
		status, _ := w.Status()

		log.Println(status.String())
		w.Reset(&git.ResetOptions{
			Mode: git.HardReset,
		})
	}

	return repo, dir, nil
}
<|endoftext|>


<commit_before>// Command json performs similar functionality to:
// alias json='python -m json.tool'
// Unlike python 2, this script handles unicode nicely.
// In general, it adheres to the UNIX philosophy:
// Simply pipe unformatted JSON data to the command and formatted JSON comes out.
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/mdwhatcott/helps"
)

func main() {
	log.SetFlags(log.Llongfile)

	if input, err := ioutil.ReadAll(os.Stdin); err != nil {
		log.Fatalf("Error reading from stdin: %s", err)
	} else if formatted, err := helps.FormatJSONSafe(input); err != nil {
		log.Fatalf("Error formatting JSON: %s\n%s", err, string(input))
	} else {
		fmt.Println(string(formatted))
	}
}
<commit_msg>Shorter logging<commit_after>// Command json performs similar functionality to:
// alias json='python -m json.tool'
// Unlike python 2, this script handles unicode nicely.
// In general, it adheres to the UNIX philosophy:
// Simply pipe unformatted JSON data to the command and formatted JSON comes out.
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/mdwhatcott/helps"
)

func main() {
	log.SetFlags(log.Lshortfile)

	if input, err := ioutil.ReadAll(os.Stdin); err != nil {
		log.Fatalf("Error reading from stdin: %s", err)
	} else if formatted, err := helps.FormatJSONSafe(input); err != nil {
		log.Fatalf("Error formatting JSON: %s\n%s", err, string(input))
	} else {
		fmt.Println(string(formatted))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"sort"

	"github.com/zyedidia/tcell"
)

type Tab struct {
	// This contains all the views in this tab
	// There is generally only one view per tab, but you can have
	// multiple views with splits
	views []*View
	// This is the current view for this tab
	CurView int

	tree *SplitTree
}

// NewTabFromView creates a new tab and puts the given view in the tab
func NewTabFromView(v *View) *Tab {
	t := new(Tab)
	t.views = append(t.views, v)
	t.views[0].Num = 0

	t.tree = new(SplitTree)
	t.tree.kind = VerticalSplit
	t.tree.children = []Node{NewLeafNode(t.views[0], t.tree)}

	w, h := screen.Size()
	t.tree.width = w
	t.tree.height = h

	if globalSettings["infobar"].(bool) {
		t.tree.height--
	}

	t.Resize()

	return t
}

// SetNum sets all this tab's views to have the correct tab number
func (t *Tab) SetNum(num int) {
	t.tree.tabNum = num
	for _, v := range t.views {
		v.TabNum = num
	}
}

func (t *Tab) Cleanup() {
	t.tree.Cleanup()
}

func (t *Tab) Resize() {
	w, h := screen.Size()
	t.tree.width = w
	t.tree.height = h

	if globalSettings["infobar"].(bool) {
		t.tree.height--
	}

	t.tree.ResizeSplits()

	for i, v := range t.views {
		v.Num = i
	}
}

// CurView returns the current view
func CurView() *View {
	curTab := tabs[curTab]
	return curTab.views[curTab.CurView]
}

// TabbarString returns the string that should be displayed in the tabbar
// It also returns a map containing which indicies correspond to which tab number
// This is useful when we know that the mouse click has occurred at an x location
// but need to know which tab that corresponds to to accurately change the tab
func TabbarString() (string, map[int]int) {
	str := ""
	indicies := make(map[int]int)
	for i, t := range tabs {
		if i == curTab {
			str += "["
		} else {
			str += " "
		}
		str += t.views[t.CurView].Buf.GetName()
		if i == curTab {
			str += "]"
		} else {
			str += " "
		}
		indicies[len(str)-1] = i + 1
		str += " "
	}
	return str, indicies
}

// TabbarHandleMouseEvent checks the given mouse event if it is clicking on the tabbar
// If it is it changes the current tab accordingly
// This function returns true if the tab is changed
func TabbarHandleMouseEvent(event tcell.Event) bool {
	// There is no tabbar displayed if there are less than 2 tabs
	if len(tabs) <= 1 {
		return false
	}

	switch e := event.(type) {
	case *tcell.EventMouse:
		button := e.Buttons()
		// Must be a left click
		if button == tcell.Button1 {
			x, y := e.Position()
			if y != 0 {
				return false
			}
			str, indicies := TabbarString()
			if x >= len(str) {
				return false
			}
			var tabnum int
			var keys []int
			for k := range indicies {
				keys = append(keys, k)
			}
			sort.Ints(keys)
			for _, k := range keys {
				if x <= k {
					tabnum = indicies[k] - 1
					break
				}
			}
			curTab = tabnum
			return true
		}
	}

	return false
}

// DisplayTabs displays the tabbar at the top of the editor if there are multiple tabs
func DisplayTabs() {
	if len(tabs) <= 1 {
		return
	}

	str, _ := TabbarString()

	tabBarStyle := defStyle.Reverse(true)
	if style, ok := colorscheme["tabbar"]; ok {
		tabBarStyle = style
	}

	// Maybe there is a unicode filename?
	fileRunes := []rune(str)
	w, _ := screen.Size()
	for x := 0; x < w; x++ {
		if x < len(fileRunes) {
			screen.SetContent(x, 0, fileRunes[x], nil, tabBarStyle)
		} else {
			screen.SetContent(x, 0, ' ', nil, tabBarStyle)
		}
	}
}
<commit_msg>adding tab scrolling and additional tab indicators<commit_after>package main

import (
	"sort"

	"github.com/zyedidia/tcell"
)

var tabBarOffset int

type Tab struct {
	// This contains all the views in this tab
	// There is generally only one view per tab, but you can have
	// multiple views with splits
	views []*View
	// This is the current view for this tab
	CurView int

	tree *SplitTree
}

// NewTabFromView creates a new tab and puts the given view in the tab
func NewTabFromView(v *View) *Tab {
	t := new(Tab)
	t.views = append(t.views, v)
	t.views[0].Num = 0

	t.tree = new(SplitTree)
	t.tree.kind = VerticalSplit
	t.tree.children = []Node{NewLeafNode(t.views[0], t.tree)}

	w, h := screen.Size()
	t.tree.width = w
	t.tree.height = h

	if globalSettings["infobar"].(bool) {
		t.tree.height--
	}

	t.Resize()

	return t
}

// SetNum sets all this tab's views to have the correct tab number
func (t *Tab) SetNum(num int) {
	t.tree.tabNum = num
	for _, v := range t.views {
		v.TabNum = num
	}
}

func (t *Tab) Cleanup() {
	t.tree.Cleanup()
}

func (t *Tab) Resize() {
	w, h := screen.Size()
	t.tree.width = w
	t.tree.height = h

	if globalSettings["infobar"].(bool) {
		t.tree.height--
	}

	t.tree.ResizeSplits()

	for i, v := range t.views {
		v.Num = i
	}
}

// CurView returns the current view
func CurView() *View {
	curTab := tabs[curTab]
	return curTab.views[curTab.CurView]
}

// TabbarString returns the string that should be displayed in the tabbar
// It also returns a map containing which indicies correspond to which tab number
// This is useful when we know that the mouse click has occurred at an x location
// but need to know which tab that corresponds to to accurately change the tab
func TabbarString() (string, map[int]int) {
	str := ""
	indicies := make(map[int]int)
	for i, t := range tabs {
		if i == curTab {
			str += "["
		} else {
			str += " "
		}
		str += t.views[t.CurView].Buf.GetName()
		if i == curTab {
			str += "]"
		} else {
			str += " "
		}
		indicies[len(str)-1] = i + 1
		str += " "
	}
	return str, indicies
}

// TabbarHandleMouseEvent checks the given mouse event if it is clicking on the tabbar
// If it is it changes the current tab accordingly
// This function returns true if the tab is changed
func TabbarHandleMouseEvent(event tcell.Event) bool {
	// There is no tabbar displayed if there are less than 2 tabs
	if len(tabs) <= 1 {
		return false
	}

	switch e := event.(type) {
	case *tcell.EventMouse:
		button := e.Buttons()
		// Must be a left click
		if button == tcell.Button1 {
			x, y := e.Position()
			if y != 0 {
				return false
			}
			str, indicies := TabbarString()
			if x + tabBarOffset >= len(str) {
				return false
			}
			var tabnum int
			var keys []int
			for k := range indicies {
				keys = append(keys, k)
			}
			sort.Ints(keys)
			for _, k := range keys {
				if x + tabBarOffset <= k {
					tabnum = indicies[k] - 1
					break
				}
			}
			curTab = tabnum
			return true
		}
	}

	return false
}

// DisplayTabs displays the tabbar at the top of the editor if there are multiple tabs
func DisplayTabs() {
	if len(tabs) <= 1 {
		return
	}

	str, indicies := TabbarString()

	tabBarStyle := defStyle.Reverse(true)
	if style, ok := colorscheme["tabbar"]; ok {
		tabBarStyle = style
	}

	// Maybe there is a unicode filename?
	fileRunes := []rune(str)
	w, _ := screen.Size()
	tooWide := (w < len(fileRunes))

	// if the entire tab-bar is longer than the screen is wide,
	// then it should be truncated appropriately to keep the
	// active tab visible on the UI.
	if tooWide == true {
		// first we have to work out where the selected tab is
		// out of the total length of the tab bar. this is done
		// by extracting the hit-areas from the indicies map
		// that was constructed by `TabbarString()`
		var keys []int
		for offset := range indicies {
			keys = append(keys, offset)
		}
		// sort them to be in ascending order so that values will
		// correctly reflect the displayed ordering of the tabs
		sort.Ints(keys)
		// record the offset of each tab and the previous tab so
		// we can find the position of the tab's hit-box.
		previousTabOffset := 0
		currentTabOffset := 0
		for _, k := range keys {
			tabIndex := indicies[k] - 1
			if tabIndex == curTab {
				currentTabOffset = k
				break
			}
			// this is +2 because there are two padding spaces that aren't accounted
			// for in the display. please note that this is for cosmetic purposes only.
			previousTabOffset = k + 2
		}
		// get the width of the hitbox of the active tab, from there calculate the offsets
		// to the left and right of it to approximately center it on the tab bar display.
		centeringOffset := (w - (currentTabOffset - previousTabOffset))
		leftBuffer := previousTabOffset - (centeringOffset / 2)
		rightBuffer := currentTabOffset + (centeringOffset / 2)

		// check to make sure we haven't overshot the bounds of the string,
		// if we have, then take that remainder and put it on the left side
		overshotRight := rightBuffer - len(fileRunes)
		if overshotRight > 0 {
			leftBuffer = leftBuffer + overshotRight
		}

		overshotLeft := leftBuffer - 0
		if overshotLeft < 0 {
			leftBuffer = 0
			rightBuffer = leftBuffer + (w - 1)
		} else {
			rightBuffer = leftBuffer + (w - 2)
		}

		if rightBuffer > len(fileRunes) - 1 {
			rightBuffer = len(fileRunes) - 1
		}

		// construct a new buffer of text to put the
		// newly formatted tab bar text into.
		var displayText []rune

		// if the left-side of the tab bar isn't at the start
		// of the constructed tab bar text, then show that are
		// more tabs to the left by displaying a "+"
		if leftBuffer != 0 {
			displayText = append(displayText, '+')
		}
		// copy the runes in from the original tab bar text string
		// into the new display buffer
		for x := leftBuffer; x < rightBuffer; x++ {
			displayText = append(displayText, fileRunes[x])
		}
		// if there is more text to the right of the right-most
		// column in the tab bar text, then indicate there are more
		// tabs to ther right by displaying a "+"
		if rightBuffer < len(fileRunes) - 1 {
			displayText = append(displayText, '+')
		}

		// now store the offset from zero of the left-most text
		// that is being displayed. This is to ensure that when
		// clicking on the tab bar, the correct tab gets selected.
		tabBarOffset = leftBuffer

		// use the constructed buffer as the display buffer to print
		// onscreen.
		fileRunes = displayText
	}

	// iterate over the width of the terminal display and for each column,
	// write a character into the tab display area with the appropraite style.
	for x := 0; x < w; x++ {
		if x < len(fileRunes) {
			screen.SetContent(x, 0, fileRunes[x], nil, tabBarStyle)
		} else {
			screen.SetContent(x, 0, ' ', nil, tabBarStyle)
		}
	}
}
<|endoftext|>


<commit_before>package deployment

import (
	"fmt"

	"git.containerum.net/ch/kube-client/pkg/model"
	"github.com/containerum/chkit/pkg/model/container"
)

type Deployment struct {
	Name       string
	Replicas   int
	Status     *Status
	Containers []container.Container
	origin     *model.Deployment
}

func DeploymentFromKube(kubeDeployment model.Deployment) Deployment {
	var status *Status
	if kubeDeployment.Status != nil {
		st := StatusFromKubeStatus(*kubeDeployment.Status)
		status = &st
	}
	containers := make([]container.Container, 0, len(kubeDeployment.Containers))
	for _, kubeContainer := range kubeDeployment.Containers {
		containers = append(containers, container.Container{Container: kubeContainer})
	}
	return Deployment{
		Name:       kubeDeployment.Name,
		Replicas:   kubeDeployment.Replicas,
		Status:     status,
		Containers: containers,
		origin:     &kubeDeployment,
	}
}

func (depl *Deployment) ToKube() model.Deployment {
	containers := make([]model.Container, 0, len(depl.Containers))
	for _, cont := range depl.Containers {
		containers = append(containers, cont.Container)
	}
	kubeDepl := model.Deployment{
		Name:       depl.Name,
		Replicas:   int(depl.Replicas),
		Containers: containers,
	}
	depl.origin = &kubeDepl
	return kubeDepl
}

func (depl *Deployment) StatusString() string {
	if depl.Status != nil {
		return fmt.Sprintf("running %d/%d",
			depl.Status.AvailableReplicas, depl.Replicas)
	}
	return fmt.Sprintf("local\nreplicas %d", depl.Replicas)
}
<commit_msg>add container list<commit_after>package deployment

import (
	"fmt"

	"git.containerum.net/ch/kube-client/pkg/model"
	"github.com/containerum/chkit/pkg/model/container"
)

type Deployment struct {
	Name       string
	Replicas   int
	Status     *Status
	Containers container.ContainerList
	origin     *model.Deployment
}

func DeploymentFromKube(kubeDeployment model.Deployment) Deployment {
	var status *Status
	if kubeDeployment.Status != nil {
		st := StatusFromKubeStatus(*kubeDeployment.Status)
		status = &st
	}
	containers := make([]container.Container, 0, len(kubeDeployment.Containers))
	for _, kubeContainer := range kubeDeployment.Containers {
		containers = append(containers, container.Container{Container: kubeContainer})
	}
	return Deployment{
		Name:       kubeDeployment.Name,
		Replicas:   kubeDeployment.Replicas,
		Status:     status,
		Containers: containers,
		origin:     &kubeDeployment,
	}
}

func (depl *Deployment) ToKube() model.Deployment {
	containers := make([]model.Container, 0, len(depl.Containers))
	for _, cont := range depl.Containers {
		containers = append(containers, cont.Container)
	}
	kubeDepl := model.Deployment{
		Name:       depl.Name,
		Replicas:   int(depl.Replicas),
		Containers: containers,
	}
	depl.origin = &kubeDepl
	return kubeDepl
}

func (depl *Deployment) StatusString() string {
	if depl.Status != nil {
		return fmt.Sprintf("running %d/%d",
			depl.Status.AvailableReplicas, depl.Replicas)
	}
	return fmt.Sprintf("local\nreplicas %d", depl.Replicas)
}
<|endoftext|>


<commit_before>// Package main has two sides:
// - User mode: shell
// - tool mode: unix socket server for handling namespace operations
// When started, the program choses their side based on the argv[0].
// The name "nash" indicates a user shell and the name -nashd- indicates
// the namespace server tool.
package main

import (
	"flag"
	"fmt"
	"os"
	"os/user"

	"github.com/NeowayLabs/nash"
)

var (
	// version is set at build time
	VersionString = "No version provided"

	version     bool
	debug       bool
	file        string
	command     string
	addr        string
	noInit      bool
	interactive bool
)

func init() {
	flag.BoolVar(&version, "version", false, "Show version")
	flag.BoolVar(&debug, "debug", false, "enable debug")
	flag.BoolVar(&noInit, "noinit", false, "do not load init/init.sh file")
	flag.StringVar(&command, "c", "", "command to execute")
	flag.BoolVar(&interactive, "i", false, "Interactive mode (default if no args)")

	if os.Args[0] == "-nashd-" || (len(os.Args) > 1 && os.Args[1] == "-daemon") {
		flag.Bool("daemon", false, "force enable nashd mode")
		flag.StringVar(&addr, "addr", "", "rcd unix file")
	}
}

func main() {
	var args []string
	var shell *nash.Shell
	var err error

	flag.Parse()

	if version {
		fmt.Printf("build tag: %s\n", VersionString)
		return
	}

	if len(flag.Args()) > 0 {
		args = flag.Args()
		file = args[0]
	}

	if shell, err = initShell(); err != nil {
		goto Error
	}

	shell.SetDebug(debug)

	if addr != "" {
		startNashd(shell, addr)
		return
	}

	if (file == "" && command == "") || interactive {
		if err = cli(shell); err != nil {
			goto Error
		}

		return
	}

	if file != "" {
		if err = shell.ExecFile(file, args...); err != nil {
			goto Error
		}
	}

	if command != "" {
		err = shell.ExecuteString("<argument -c>", command)
		if err != nil {
			goto Error
		}
	}

Error:
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		os.Exit(1)
	}
}

func getnashpath() (string, error) {
	nashpath := os.Getenv("NASHPATH")
	if nashpath != "" {
		return nashpath, nil
	}

	usr, err := user.Current()
	if err != nil {
		return "", fmt.Errorf("unable to infer nash directory. "+
			"You must set NASHPATH environment variable explicity: %s",
			err.Error())
	}
	if usr.HomeDir == "" {
		return "", fmt.Errorf("User %s doesn't have a home directory. "+
			"Set NASHPATH environment variable to desired location.", usr.Name)
	}
	if usr.HomeDir == "" {
		return "", fmt.Errorf("Unable to automatically infer NASHPATH, requires setting it explicity.")
	}

	return fmt.Sprintf("%s%c%s", usr.HomeDir, os.PathSeparator, ".nash"), nil
}

func initShell() (*nash.Shell, error) {
	shell, err := nash.New()
	if err != nil {
		return nil, err
	}

	nashpath, err := getnashpath()
	if err != nil {
		return nil, err
	}

	os.Mkdir(nashpath, 0755)
	shell.SetDotDir(nashpath)

	return shell, nil
}
<commit_msg>remove dumb duplicate if<commit_after>// Package main has two sides:
// - User mode: shell
// - tool mode: unix socket server for handling namespace operations
// When started, the program choses their side based on the argv[0].
// The name "nash" indicates a user shell and the name -nashd- indicates
// the namespace server tool.
package main

import (
	"flag"
	"fmt"
	"os"
	"os/user"

	"github.com/NeowayLabs/nash"
)

var (
	// version is set at build time
	VersionString = "No version provided"

	version     bool
	debug       bool
	file        string
	command     string
	addr        string
	noInit      bool
	interactive bool
)

func init() {
	flag.BoolVar(&version, "version", false, "Show version")
	flag.BoolVar(&debug, "debug", false, "enable debug")
	flag.BoolVar(&noInit, "noinit", false, "do not load init/init.sh file")
	flag.StringVar(&command, "c", "", "command to execute")
	flag.BoolVar(&interactive, "i", false, "Interactive mode (default if no args)")

	if os.Args[0] == "-nashd-" || (len(os.Args) > 1 && os.Args[1] == "-daemon") {
		flag.Bool("daemon", false, "force enable nashd mode")
		flag.StringVar(&addr, "addr", "", "rcd unix file")
	}
}

func main() {
	var args []string
	var shell *nash.Shell
	var err error

	flag.Parse()

	if version {
		fmt.Printf("build tag: %s\n", VersionString)
		return
	}

	if len(flag.Args()) > 0 {
		args = flag.Args()
		file = args[0]
	}

	if shell, err = initShell(); err != nil {
		goto Error
	}

	shell.SetDebug(debug)

	if addr != "" {
		startNashd(shell, addr)
		return
	}

	if (file == "" && command == "") || interactive {
		if err = cli(shell); err != nil {
			goto Error
		}

		return
	}

	if file != "" {
		if err = shell.ExecFile(file, args...); err != nil {
			goto Error
		}
	}

	if command != "" {
		err = shell.ExecuteString("<argument -c>", command)
		if err != nil {
			goto Error
		}
	}

Error:
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		os.Exit(1)
	}
}

func getnashpath() (string, error) {
	nashpath := os.Getenv("NASHPATH")
	if nashpath != "" {
		return nashpath, nil
	}

	usr, err := user.Current()
	if err != nil {
		return "", fmt.Errorf("unable to infer nash directory. "+
			"You must set NASHPATH environment variable explicity: %s",
			err.Error())
	}
	if usr.HomeDir == "" {
		return "", fmt.Errorf("User %s doesn't have a home directory. "+
			"Set NASHPATH environment variable to desired location.", usr.Name)
	}

	return fmt.Sprintf("%s%c%s", usr.HomeDir, os.PathSeparator, ".nash"), nil
}

func initShell() (*nash.Shell, error) {
	shell, err := nash.New()
	if err != nil {
		return nil, err
	}

	nashpath, err := getnashpath()
	if err != nil {
		return nil, err
	}

	os.Mkdir(nashpath, 0755)
	shell.SetDotDir(nashpath)

	return shell, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Rook Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package mds

import (
	"fmt"

	"github.com/pkg/errors"
	"github.com/rook/rook/pkg/clusterd"
	"github.com/rook/rook/pkg/operator/ceph/cluster/mon"
	"github.com/rook/rook/pkg/operator/ceph/controller"
	"github.com/rook/rook/pkg/operator/k8sutil"
	apps "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	mdsDaemonCommand = "ceph-mds"
	// MDS cache memory limit should be set to 50-60% of RAM reserved for the MDS container
	// MDS uses approximately 125% of the value of mds_cache_memory_limit in RAM.
	// Eventually we will tune this automatically: http://tracker.ceph.com/issues/36663
	mdsCacheMemoryLimitFactor = 0.5
)

func (c *Cluster) makeDeployment(mdsConfig *mdsConfig) *apps.Deployment {
	podSpec := v1.PodTemplateSpec{
		ObjectMeta: metav1.ObjectMeta{
			Name:   mdsConfig.ResourceName,
			Labels: c.podLabels(mdsConfig),
		},
		Spec: v1.PodSpec{
			InitContainers: []v1.Container{
				c.makeChownInitContainer(mdsConfig),
			},
			Containers: []v1.Container{
				c.makeMdsDaemonContainer(mdsConfig),
			},
			RestartPolicy:     v1.RestartPolicyAlways,
			Volumes:           controller.DaemonVolumes(mdsConfig.DataPathMap, mdsConfig.ResourceName),
			HostNetwork:       c.clusterSpec.Network.IsHost(),
			PriorityClassName: c.fs.Spec.MetadataServer.PriorityClassName,
		},
	}
	// Replace default unreachable node toleration
	k8sutil.AddUnreachableNodeToleration(&podSpec.Spec)

	if c.clusterSpec.Network.IsHost() {
		podSpec.Spec.DNSPolicy = v1.DNSClusterFirstWithHostNet
	}
	c.fs.Spec.MetadataServer.Annotations.ApplyToObjectMeta(&podSpec.ObjectMeta)
	c.fs.Spec.MetadataServer.Placement.ApplyToPodSpec(&podSpec.Spec)

	replicas := int32(1)
	d := &apps.Deployment{
		ObjectMeta: metav1.ObjectMeta{
			Name:      mdsConfig.ResourceName,
			Namespace: c.fs.Namespace,
			Labels:    c.podLabels(mdsConfig),
		},
		Spec: apps.DeploymentSpec{
			Selector: &metav1.LabelSelector{
				MatchLabels: podSpec.Labels,
			},
			Template: podSpec,
			Replicas: &replicas,
			Strategy: apps.DeploymentStrategy{
				Type: apps.RecreateDeploymentStrategyType,
			},
		},
	}
	k8sutil.AddRookVersionLabelToDeployment(d)
	c.fs.Spec.MetadataServer.Annotations.ApplyToObjectMeta(&d.ObjectMeta)
	controller.AddCephVersionLabelToDeployment(c.clusterInfo.CephVersion, d)
	k8sutil.SetOwnerRef(&d.ObjectMeta, &c.ownerRef)
	return d
}

func (c *Cluster) makeChownInitContainer(mdsConfig *mdsConfig) v1.Container {
	return controller.ChownCephDataDirsInitContainer(
		*mdsConfig.DataPathMap,
		c.clusterSpec.CephVersion.Image,
		controller.DaemonVolumeMounts(mdsConfig.DataPathMap, mdsConfig.ResourceName),
		c.fs.Spec.MetadataServer.Resources,
		mon.PodSecurityContext(),
	)
}

func (c *Cluster) makeMdsDaemonContainer(mdsConfig *mdsConfig) v1.Container {
	args := append(
		controller.DaemonFlags(c.clusterInfo, mdsConfig.DaemonID),
		"--foreground",
	)

	container := v1.Container{
		Name: "mds",
		Command: []string{
			"ceph-mds",
		},
		Args:         args,
		Image:        c.clusterSpec.CephVersion.Image,
		VolumeMounts: controller.DaemonVolumeMounts(mdsConfig.DataPathMap, mdsConfig.ResourceName),
		Env: append(
			controller.DaemonEnvVars(c.clusterSpec.CephVersion.Image),
		),
		Resources:       c.fs.Spec.MetadataServer.Resources,
		SecurityContext: mon.PodSecurityContext(),
	}

	return container
}

func (c *Cluster) podLabels(mdsConfig *mdsConfig) map[string]string {
	labels := controller.PodLabels(AppName, c.fs.Namespace, "mds", mdsConfig.DaemonID)
	labels["rook_file_system"] = c.fs.Name
	return labels
}

func getMdsDeployments(context *clusterd.Context, namespace, fsName string) (*apps.DeploymentList, error) {
	fsLabelSelector := fmt.Sprintf("rook_file_system=%s", fsName)
	deps, err := k8sutil.GetDeployments(context.Clientset, namespace, fsLabelSelector)
	if err != nil {
		return nil, errors.Wrapf(err, "could not get deployments for filesystem %s (matching label selector %q)", fsName, fsLabelSelector)
	}
	return deps, nil
}

func deleteMdsDeployment(context *clusterd.Context, namespace string, deployment *apps.Deployment) error {
	// Delete the mds deployment
	logger.Infof("deleting mds deployment %s", deployment.Name)
	var gracePeriod int64
	propagation := metav1.DeletePropagationForeground
	options := &metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod, PropagationPolicy: &propagation}
	if err := context.Clientset.AppsV1().Deployments(namespace).Delete(deployment.GetName(), options); err != nil {
		return errors.Wrapf(err, "failed to delete mds deployment %s", deployment.GetName())
	}
	return nil
}
<commit_msg>ceph: mds controller do not set owner ref twice<commit_after>/*
Copyright 2016 The Rook Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package mds

import (
	"fmt"

	"github.com/pkg/errors"
	"github.com/rook/rook/pkg/clusterd"
	"github.com/rook/rook/pkg/operator/ceph/cluster/mon"
	"github.com/rook/rook/pkg/operator/ceph/controller"
	"github.com/rook/rook/pkg/operator/k8sutil"
	apps "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	mdsDaemonCommand = "ceph-mds"
	// MDS cache memory limit should be set to 50-60% of RAM reserved for the MDS container
	// MDS uses approximately 125% of the value of mds_cache_memory_limit in RAM.
	// Eventually we will tune this automatically: http://tracker.ceph.com/issues/36663
	mdsCacheMemoryLimitFactor = 0.5
)

func (c *Cluster) makeDeployment(mdsConfig *mdsConfig) *apps.Deployment {
	podSpec := v1.PodTemplateSpec{
		ObjectMeta: metav1.ObjectMeta{
			Name:   mdsConfig.ResourceName,
			Labels: c.podLabels(mdsConfig),
		},
		Spec: v1.PodSpec{
			InitContainers: []v1.Container{
				c.makeChownInitContainer(mdsConfig),
			},
			Containers: []v1.Container{
				c.makeMdsDaemonContainer(mdsConfig),
			},
			RestartPolicy:     v1.RestartPolicyAlways,
			Volumes:           controller.DaemonVolumes(mdsConfig.DataPathMap, mdsConfig.ResourceName),
			HostNetwork:       c.clusterSpec.Network.IsHost(),
			PriorityClassName: c.fs.Spec.MetadataServer.PriorityClassName,
		},
	}
	// Replace default unreachable node toleration
	k8sutil.AddUnreachableNodeToleration(&podSpec.Spec)

	if c.clusterSpec.Network.IsHost() {
		podSpec.Spec.DNSPolicy = v1.DNSClusterFirstWithHostNet
	}
	c.fs.Spec.MetadataServer.Annotations.ApplyToObjectMeta(&podSpec.ObjectMeta)
	c.fs.Spec.MetadataServer.Placement.ApplyToPodSpec(&podSpec.Spec)

	replicas := int32(1)
	d := &apps.Deployment{
		ObjectMeta: metav1.ObjectMeta{
			Name:      mdsConfig.ResourceName,
			Namespace: c.fs.Namespace,
			Labels:    c.podLabels(mdsConfig),
		},
		Spec: apps.DeploymentSpec{
			Selector: &metav1.LabelSelector{
				MatchLabels: podSpec.Labels,
			},
			Template: podSpec,
			Replicas: &replicas,
			Strategy: apps.DeploymentStrategy{
				Type: apps.RecreateDeploymentStrategyType,
			},
		},
	}
	k8sutil.AddRookVersionLabelToDeployment(d)
	c.fs.Spec.MetadataServer.Annotations.ApplyToObjectMeta(&d.ObjectMeta)
	controller.AddCephVersionLabelToDeployment(c.clusterInfo.CephVersion, d)

	return d
}

func (c *Cluster) makeChownInitContainer(mdsConfig *mdsConfig) v1.Container {
	return controller.ChownCephDataDirsInitContainer(
		*mdsConfig.DataPathMap,
		c.clusterSpec.CephVersion.Image,
		controller.DaemonVolumeMounts(mdsConfig.DataPathMap, mdsConfig.ResourceName),
		c.fs.Spec.MetadataServer.Resources,
		mon.PodSecurityContext(),
	)
}

func (c *Cluster) makeMdsDaemonContainer(mdsConfig *mdsConfig) v1.Container {
	args := append(
		controller.DaemonFlags(c.clusterInfo, mdsConfig.DaemonID),
		"--foreground",
	)

	container := v1.Container{
		Name: "mds",
		Command: []string{
			"ceph-mds",
		},
		Args:         args,
		Image:        c.clusterSpec.CephVersion.Image,
		VolumeMounts: controller.DaemonVolumeMounts(mdsConfig.DataPathMap, mdsConfig.ResourceName),
		Env: append(
			controller.DaemonEnvVars(c.clusterSpec.CephVersion.Image),
		),
		Resources:       c.fs.Spec.MetadataServer.Resources,
		SecurityContext: mon.PodSecurityContext(),
	}

	return container
}

func (c *Cluster) podLabels(mdsConfig *mdsConfig) map[string]string {
	labels := controller.PodLabels(AppName, c.fs.Namespace, "mds", mdsConfig.DaemonID)
	labels["rook_file_system"] = c.fs.Name
	return labels
}

func getMdsDeployments(context *clusterd.Context, namespace, fsName string) (*apps.DeploymentList, error) {
	fsLabelSelector := fmt.Sprintf("rook_file_system=%s", fsName)
	deps, err := k8sutil.GetDeployments(context.Clientset, namespace, fsLabelSelector)
	if err != nil {
		return nil, errors.Wrapf(err, "could not get deployments for filesystem %s (matching label selector %q)", fsName, fsLabelSelector)
	}
	return deps, nil
}

func deleteMdsDeployment(context *clusterd.Context, namespace string, deployment *apps.Deployment) error {
	// Delete the mds deployment
	logger.Infof("deleting mds deployment %s", deployment.Name)
	var gracePeriod int64
	propagation := metav1.DeletePropagationForeground
	options := &metav1.DeleteOptions{GracePeriodSeconds: &gracePeriod, PropagationPolicy: &propagation}
	if err := context.Clientset.AppsV1().Deployments(namespace).Delete(deployment.GetName(), options); err != nil {
		return errors.Wrapf(err, "failed to delete mds deployment %s", deployment.GetName())
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"

	"github.com/jessevdk/go-flags"
	"github.com/lestrrat/peco"
	"github.com/nsf/termbox-go"
)

func showHelp() {
	const v = `
Usage: percol [options] [FILE]

Options:
  -h, --help            show this help message and exit
  --rcfile=RCFILE       path to the settings file
  --query=QUERY         pre-input query
`
	os.Stderr.Write([]byte(v))
}

type CmdOptions struct {
	Help   bool   `short:"h" long:"help" description:"show this help message and exit"`
	TTY    string `long:"tty" description:"path to the TTY (usually, the value of $TTY)"`
	Query  string `long:"query"`
	Rcfile string `long:"rcfile" descriotion:"path to the settings file"`
}

func main() {
	var err error

	opts := &CmdOptions{}
	p := flags.NewParser(opts, flags.PrintErrors)
	args, err := p.Parse() // &opts, os.Args)
	if err != nil {
		panic(err)
		os.Exit(1)
	}

	if opts.Help {
		showHelp()
		os.Exit(1)
	}

	var in *os.File

	// receive in from either a file or Stdin
	if len(args) > 0 {
		in, err = os.Open(args[0])
		if err != nil {
			os.Exit(1)
		}
	} else if !peco.IsTty() {
		in = os.Stdin
	}

	ctx := peco.NewCtx()
	defer func() {
		if result := ctx.Result(); result != "" {
			os.Stdout.WriteString(result)
		}
		os.Exit(ctx.ExitStatus)
	}()

	if opts.Rcfile == "" {
		user, err := user.Current()
		if err == nil { // silently ignore failure for user.Current()
			file := filepath.Join(user.HomeDir, ".peco", "config.json")
			_, err := os.Stat(file)
			if err == nil {
				opts.Rcfile = file
			}
		}
	}

	if opts.Rcfile != "" {
		err = ctx.ReadConfig(opts.Rcfile)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}

	if err = ctx.ReadBuffer(in); err != nil {
		// Nothing to process, bail out
		fmt.Fprintln(os.Stderr, "You must supply something to work with via filename or stdin")
		os.Exit(1)
	}

	err = peco.TtyReady()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer peco.TtyTerm()

	err = termbox.Init()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer termbox.Close()

	view := ctx.NewView()
	filter := ctx.NewFilter()
	input := ctx.NewInput()

	go view.Loop()
	go filter.Loop()
	go input.Loop()

	if len(opts.Query) > 0 {
		ctx.ExecQuery(string(string(opts.Query)))
	} else {
		view.Refresh()
	}

	ctx.WaitDone()
}
<commit_msg>Avoid using os.Exit()<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"

	"github.com/jessevdk/go-flags"
	"github.com/lestrrat/peco"
	"github.com/nsf/termbox-go"
)

func showHelp() {
	const v = `
Usage: percol [options] [FILE]

Options:
  -h, --help            show this help message and exit
  --rcfile=RCFILE       path to the settings file
  --query=QUERY         pre-input query
`
	os.Stderr.Write([]byte(v))
}

type CmdOptions struct {
	Help   bool   `short:"h" long:"help" description:"show this help message and exit"`
	TTY    string `long:"tty" description:"path to the TTY (usually, the value of $TTY)"`
	Query  string `long:"query"`
	Rcfile string `long:"rcfile" descriotion:"path to the settings file"`
}

func main() {
	var err error

	opts := &CmdOptions{}
	p := flags.NewParser(opts, flags.PrintErrors)
	args, err := p.Parse() // &opts, os.Args)
	if err != nil {
		panic(err)
		os.Exit(1)
	}

	if opts.Help {
		showHelp()
		os.Exit(1)
	}

	var in *os.File

	// receive in from either a file or Stdin
	if len(args) > 0 {
		in, err = os.Open(args[0])
		if err != nil {
			os.Exit(1)
		}
	} else if !peco.IsTty() {
		in = os.Stdin
	}

	ctx := peco.NewCtx()
	defer func() {
		if result := ctx.Result(); result != "" {
			os.Stdout.WriteString(result)
		}
		os.Exit(ctx.ExitStatus)
	}()

	if opts.Rcfile == "" {
		user, err := user.Current()
		if err == nil { // silently ignore failure for user.Current()
			file := filepath.Join(user.HomeDir, ".peco", "config.json")
			_, err := os.Stat(file)
			if err == nil {
				opts.Rcfile = file
			}
		}
	}

	if opts.Rcfile != "" {
		err = ctx.ReadConfig(opts.Rcfile)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			ctx.ExitStatus = 1
			return
		}
	}

	if err = ctx.ReadBuffer(in); err != nil {
		// Nothing to process, bail out
		fmt.Fprintln(os.Stderr, "You must supply something to work with via filename or stdin")
		ctx.ExitStatus = 1
		return
	}

	err = peco.TtyReady()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		ctx.ExitStatus = 1
		return
	}
	defer peco.TtyTerm()

	err = termbox.Init()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		ctx.ExitStatus = 1
		return
	}
	defer termbox.Close()

	view := ctx.NewView()
	filter := ctx.NewFilter()
	input := ctx.NewInput()

	go view.Loop()
	go filter.Loop()
	go input.Loop()

	if len(opts.Query) > 0 {
		ctx.ExecQuery(string(string(opts.Query)))
	} else {
		view.Refresh()
	}

	ctx.WaitDone()
}
<|endoftext|>