113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
package runner
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"git.ohea.xyz/cursorius/server/config"
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/client"
|
|
"github.com/docker/docker/pkg/stdcopy"
|
|
"github.com/op/go-logging"
|
|
)
|
|
|
|
var log = logging.MustGetLogger("cursorius-server")
|
|
|
|
type Run struct {
|
|
Name string
|
|
}
|
|
|
|
func runJob(job config.Job) {
|
|
if job.Folder != nil {
|
|
log.Debugf("Job configured with folder \"%v\"", *job.Folder)
|
|
|
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
|
if err != nil {
|
|
log.Errorf("Could not create docker clien: %va", err)
|
|
return
|
|
}
|
|
|
|
hostname, err := os.Hostname()
|
|
if err != nil {
|
|
log.Errorf("Could not get hostname: %v", err)
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
resp, err := cli.ContainerCreate(ctx,
|
|
&container.Config{
|
|
Image: "cursorius:latest",
|
|
Cmd: []string{"/launcher.sh"},
|
|
Tty: false,
|
|
Env: []string{fmt.Sprintf("CURSORIUS_SRC_DIR=%s", *job.Folder)},
|
|
},
|
|
&container.HostConfig{
|
|
VolumesFrom: []string{hostname},
|
|
},
|
|
nil, nil, "",
|
|
)
|
|
if err != nil {
|
|
log.Errorf("Could not create container: %v", err)
|
|
return
|
|
}
|
|
|
|
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
|
log.Errorf("Could not start container: %v", err)
|
|
return
|
|
}
|
|
statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
|
|
select {
|
|
case err := <-errCh:
|
|
if err != nil {
|
|
log.Errorf("Container returned error: %v", err)
|
|
return
|
|
}
|
|
case retCode := <-statusCh:
|
|
log.Debugf("Container finished running with return code: %v", retCode)
|
|
}
|
|
|
|
out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true})
|
|
if err != nil {
|
|
log.Errorf("Could not get container logs: %v", err)
|
|
return
|
|
}
|
|
|
|
var stdOut bytes.Buffer
|
|
var stdErr bytes.Buffer
|
|
|
|
stdcopy.StdCopy(&stdOut, &stdErr, out)
|
|
|
|
log.Debugf("%s", stdOut.Bytes())
|
|
log.Debugf("%s", stdErr.Bytes())
|
|
|
|
} else if job.URL != nil {
|
|
log.Debugf("Job configured with URL \"%v\"", *job.URL)
|
|
}
|
|
}
|
|
|
|
func runnerListen(ch chan Run, jobs map[string]config.Job) {
|
|
for {
|
|
run := <-ch
|
|
log.Debugf("Got Run: %v", run)
|
|
job, exists := jobs[run.Name]
|
|
if exists {
|
|
log.Infof("Launching run for job %v", run.Name)
|
|
go runJob(job)
|
|
} else {
|
|
log.Errorf("No configured job with name %v", run.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func StartRunner(jobs map[string]config.Job) (chan Run, error) {
|
|
ch := make(chan Run)
|
|
|
|
go runnerListen(ch, jobs)
|
|
|
|
return ch, nil
|
|
}
|