<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/technoweenie/grohl"
	"github.com/flynn/flynn/discoverd/client"
	"github.com/flynn/flynn/host/ports"
	"github.com/flynn/flynn/host/sampi"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/pkg/attempt"
	"github.com/flynn/flynn/pkg/cluster"
	rpc "github.com/flynn/flynn/pkg/rpcplus/comborpc"
)

// Attempts is the attempt strategy that is used to connect to discoverd.
var Attempts = attempt.Strategy{
	Min:   5,
	Total: 10 * time.Second,
	Delay: 200 * time.Millisecond,
}

// A command line flag to accumulate multiple key-value pairs into Metadata,
// e.g. flynn-host -meta foo=bar -meta bar=foo
type MetaFlag map[string]string

func (a MetaFlag) Set(val string) error {
	kv := strings.SplitN(val, "=", 2)
	a[kv[0]] = kv[1]
	return nil
}

func (a MetaFlag) String() string {
	res := make([]string, 0, len(a))
	for k, v := range a {
		res = append(res, k+"="+v)
	}
	return strings.Join(res, ", ")
}

func init() {
	log.SetFlags(log.Lshortfile | log.Lmicroseconds)
}

func main() {
	hostname, _ := os.Hostname()
	externalAddr := flag.String("external", "", "external IP of host")
	bindAddr := flag.String("bind", "", "bind containers to this IP")
	configFile := flag.String("config", "", "configuration file")
	manifestFile := flag.String("manifest", "/etc/flynn-host.json", "manifest file")
	stateFile := flag.String("state", "", "state file")
	hostID := flag.String("id", strings.Replace(hostname, "-", "", -1), "host id")
	force := flag.Bool("force", false, "kill all containers booted by flynn-host before starting")
	volPath := flag.String("volpath", "/var/lib/flynn-host", "directory to create volumes in")
	backendName := flag.String("backend", "libvirt-lxc", "runner backend (docker or libvirt-lxc)")
	metadata := make(MetaFlag)
	flag.Var(&metadata, "meta", "key=value pair to add as metadata")
	flag.Parse()
	grohl.AddContext("app", "host")
	grohl.Log(grohl.Data{"at": "start"})
	g := grohl.NewContext(grohl.Data{"fn": "main"})

	if strings.Contains(*hostID, "-") {
		log.Fatal("host id must not contain dashes")
	}

	portAlloc := map[string]*ports.Allocator{
		"tcp": ports.NewAllocator(55000, 65535),
		"udp": ports.NewAllocator(55000, 65535),
	}

	sh := newShutdownHandler()
	state := NewState()
	var backend Backend
	var err error

	switch *backendName {
	case "libvirt-lxc":
		backend, err = NewLibvirtLXCBackend(state, portAlloc, *volPath, "/tmp/flynn-host-logs", "/usr/bin/flynn-init")
	case "docker":
		backend, err = NewDockerBackend(state, portAlloc, *bindAddr)
	default:
		log.Fatalf("unknown backend %q", *backendName)
	}
	if err != nil {
		sh.Fatal(err)
	}

	if err := serveHTTP(&Host{state: state, backend: backend}, &attachHandler{state: state, backend: backend}, sh); err != nil {
		sh.Fatal(err)
	}

	if *stateFile != "" {
		sh.BeforeExit(func() { os.Remove(*stateFile) })
		if err := state.Restore(*stateFile, backend); err != nil {
			sh.Fatal(err)
		}
	}

	sh.BeforeExit(func() { backend.Cleanup() })
<commit_msg>host: Support custom flynn-init path<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/technoweenie/grohl"
	"github.com/flynn/flynn/discoverd/client"
	"github.com/flynn/flynn/host/ports"
	"github.com/flynn/flynn/host/sampi"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/pkg/attempt"
	"github.com/flynn/flynn/pkg/cluster"
	rpc "github.com/flynn/flynn/pkg/rpcplus/comborpc"
)

// Attempts is the attempt strategy that is used to connect to discoverd.
var Attempts = attempt.Strategy{
	Min:   5,
	Total: 10 * time.Second,
	Delay: 200 * time.Millisecond,
}

// A command line flag to accumulate multiple key-value pairs into Metadata,
// e.g. flynn-host -meta foo=bar -meta bar=foo
type MetaFlag map[string]string

func (a MetaFlag) Set(val string) error {
	kv := strings.SplitN(val, "=", 2)
	a[kv[0]] = kv[1]
	return nil
}

func (a MetaFlag) String() string {
	res := make([]string, 0, len(a))
	for k, v := range a {
		res = append(res, k+"="+v)
	}
	return strings.Join(res, ", ")
}

func init() {
	log.SetFlags(log.Lshortfile | log.Lmicroseconds)
}

func main() {
	hostname, _ := os.Hostname()
	externalAddr := flag.String("external", "", "external IP of host")
	bindAddr := flag.String("bind", "", "bind containers to this IP")
	configFile := flag.String("config", "", "configuration file")
	manifestFile := flag.String("manifest", "/etc/flynn-host.json", "manifest file")
	stateFile := flag.String("state", "", "state file")
	hostID := flag.String("id", strings.Replace(hostname, "-", "", -1), "host id")
	force := flag.Bool("force", false, "kill all containers booted by flynn-host before starting")
	volPath := flag.String("volpath", "/var/lib/flynn-host", "directory to create volumes in")
	backendName := flag.String("backend", "libvirt-lxc", "runner backend (docker or libvirt-lxc)")
	flynnInit := flag.String("flynn-init", "/usr/bin/flynn-init", "path to flynn-init binary")
	metadata := make(MetaFlag)
	flag.Var(&metadata, "meta", "key=value pair to add as metadata")
	flag.Parse()
	grohl.AddContext("app", "host")
	grohl.Log(grohl.Data{"at": "start"})
	g := grohl.NewContext(grohl.Data{"fn": "main"})

	if strings.Contains(*hostID, "-") {
		log.Fatal("host id must not contain dashes")
	}

	portAlloc := map[string]*ports.Allocator{
		"tcp": ports.NewAllocator(55000, 65535),
		"udp": ports.NewAllocator(55000, 65535),
	}

	sh := newShutdownHandler()
	state := NewState()
	var backend Backend
	var err error

	switch *backendName {
	case "libvirt-lxc":
		backend, err = NewLibvirtLXCBackend(state, portAlloc, *volPath, "/tmp/flynn-host-logs", *flynnInit)
	case "docker":
		backend, err = NewDockerBackend(state, portAlloc, *bindAddr)
	default:
		log.Fatalf("unknown backend %q", *backendName)
	}
	if err != nil {
		sh.Fatal(err)
	}

	if err := serveHTTP(&Host{state: state, backend: backend}, &attachHandler{state: state, backend: backend}, sh); err != nil {
		sh.Fatal(err)
	}

	if *stateFile != "" {
		sh.BeforeExit(func() { os.Remove(*stateFile) })
		if err := state.Restore(*stateFile, backend); err != nil {
			sh.Fatal(err)
		}
	}

	sh.BeforeExit(func() { backend.Cleanup() })

{'fraction_non_alphanumeric': 0.17739403453689168, 'fraction_numerical': 0.009733124018838305, 'mean_word_length': 4.501727115716753, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5121581', 'n_tokens_mistral': 2452, 'n_tokens_neox': 2339, 'n_words': 535}