<commit_before>package backend

import (
	"fmt"
	"io"
	"runtime"
	"sync"
	"time"

	"code.google.com/p/go-uuid/uuid"

	"github.com/fsouza/go-dockerclient"
	"github.com/pkg/sftp"
	"github.com/travis-ci/worker/lib/context"
	"github.com/travis-ci/worker/lib/metrics"
	"golang.org/x/crypto/ssh"
	gocontext "golang.org/x/net/context"
)

type DockerProvider struct {
	client *docker.Client

	cpuSetsMutex sync.Mutex
	cpuSets      []bool
}

type DockerInstance struct {
	client    *docker.Client
	provider  *DockerProvider
	container *docker.Container
}

func NewDockerProvider(config map[string]string) (*DockerProvider, error) {
	endpoint, ok := config["endpoint"]
	if !ok {
		return nil, fmt.Errorf("expected config key endpoint")
	}

	client, err := docker.NewClient(endpoint)
	if err != nil {
		return nil, err
	}

	cpuSetSize := runtime.NumCPU()
	if cpuSetSize < 2 {
		cpuSetSize = 2
	}

	return &DockerProvider{
		client:  client,
		cpuSets: make([]bool, cpuSetSize),
	}, nil
}

func (p *DockerProvider) Start(ctx gocontext.Context, startAttributes StartAttributes) (Instance, error) {
	cpuSets, err := p.checkoutCPUSets()
	if err != nil && cpuSets != "" {
		return nil, err
	}

	imageID, err := p.imageForLanguage(startAttributes.Language)
	if err != nil {
		return nil, err
	}
<commit_msg>Add support for TLS docker client<commit_after>package backend

import (
	"fmt"
	"io"
	"runtime"
	"sync"
	"time"

	"code.google.com/p/go-uuid/uuid"

	"github.com/fsouza/go-dockerclient"
	"github.com/pkg/sftp"
	"github.com/travis-ci/worker/lib/context"
	"github.com/travis-ci/worker/lib/metrics"
	"golang.org/x/crypto/ssh"
	gocontext "golang.org/x/net/context"
)

var (
	errMissingEndpointConfig = fmt.Errorf("expected config key endpoint")
)

type DockerProvider struct {
	client *docker.Client

	cpuSetsMutex sync.Mutex
	cpuSets      []bool
}

type DockerInstance struct {
	client    *docker.Client
	provider  *DockerProvider
	container *docker.Container
}

func NewDockerProvider(config map[string]string) (*DockerProvider, error) {
	client, err := buildClient(config)
	if err != nil {
		return nil, err
	}

	cpuSetSize := runtime.NumCPU()
	if cpuSetSize < 2 {
		cpuSetSize = 2
	}

	return &DockerProvider{
		client:  client,
		cpuSets: make([]bool, cpuSetSize),
	}, nil
}

func buildClient(config map[string]string) (*docker.Client, error) {
	endpoint, ok := config["endpoint"]
	if !ok {
		return nil, errMissingEndpointConfig
	}

	if path, ok := config["cert_path"]; ok {
		ca := fmt.Sprintf("%s/ca.pem", path)
		cert := fmt.Sprintf("%s/cert.pem", path)
		key := fmt.Sprintf("%s/key.pem", path)
		return docker.NewTLSClient(endpoint, cert, key, ca)
	}

	return docker.NewClient(endpoint)
}

func (p *DockerProvider) Start(ctx gocontext.Context, startAttributes StartAttributes) (Instance, error) {
	cpuSets, err := p.checkoutCPUSets()
	if err != nil && cpuSets != "" {
		return nil, err
	}

	imageID, err := p.imageForLanguage(startAttributes.Language)
	if err != nil {
		return nil, err
	}

{'fraction_non_alphanumeric': 0.1390284757118928, 'fraction_numerical': 0.001340033500837521, 'mean_word_length': 4.22027972027972, 'pattern_counts': {'":': 0, '<': 5, '<?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': '2603097', 'n_tokens_mistral': 1133, 'n_tokens_neox': 1075, 'n_words': 238}