<commit_before>package server

import (
	"net/http"
	"net/url"

	"github.com/fsouza/go-dockerclient"
)

type TasksResource struct {
	Docker            *docker.Client
	DockerHubUsername string
}

type TaskRequest struct {
	Task Task `json:"task"`
}

type Task struct {
	Version string `json:"version"`
	Command string `json:"command"`
}

func (tr *TasksResource) Create(u *url.URL, h http.Header, req *TaskRequest) (int, http.Header, interface{}, error) {

	return http.StatusCreated, nil, nil, nil
}<commit_msg>First naive implementation of task execution where output is just sent to console, but task is executed with Docker, output is streamed, and container is cleaned up.<commit_after>package server

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"net/url"

	"github.com/fsouza/go-dockerclient"
)

type TasksResource struct {
	Docker            *docker.Client
	DockerHubUsername string
}

type TaskRequest struct {
	Task Task `json:"task"`
}

type Task struct {
	Version string `json:"version"`
	Command string `json:"command"`
}

func (tr *TasksResource) Create(u *url.URL, h http.Header, req *TaskRequest) (int, http.Header, interface{}, error) {
	serviceName := u.Query().Get("name")
	taskName := fmt.Sprintf("%s-%s-task", serviceName, req.Task.Version)
	imageName := fmt.Sprintf("%s/%s:%s", tr.DockerHubUsername, serviceName, req.Task.Version)

	container, err := tr.Docker.CreateContainer(docker.CreateContainerOptions{
		Name: taskName,
		Config: &docker.Config{
			Image:        imageName,
			Cmd:          []string{req.Task.Command},
			AttachStdout: true,
			AttachStderr: true,
		},
	})
	if err != nil {
		return http.StatusInternalServerError, nil, nil, err
	}

	log.Printf("%#v", container)
	tr.Docker.StartContainer(container.ID, &docker.HostConfig{})

	var buf bytes.Buffer
	err = tr.Docker.AttachToContainer(docker.AttachToContainerOptions{
		Container:    container.ID,
		OutputStream: &buf,
		Logs:         true,
		Stdout:       true,
		Stderr:       true,
		Stream:       true,
	})
	if err != nil {
		return http.StatusInternalServerError, nil, nil, err
	}
	log.Println(buf.String())

	err = tr.Docker.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID})
	if err != nil {
		return http.StatusInternalServerError, nil, nil, err
	}

	return http.StatusCreated, nil, nil, nil
}
{'fraction_non_alphanumeric': 0.12824956672443674, 'fraction_numerical': 0.0, 'mean_word_length': 4.097130242825607, 'pattern_counts': {'":': 0, '<': 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': '2066290', 'n_tokens_mistral': 795, 'n_tokens_neox': 755, 'n_words': 196}