HTTPS and File Uploads (#139)

* Add a few fixes

* Use CopyToContainer instead of bind mounts

* Remove a local compose file

* Changes according to the comments

* Rebase with master
This commit is contained in:
Jonathan Leibiusky
2017-05-12 16:20:09 -03:00
committed by Marcos Nils
parent 61a0bb4db1
commit 8df6373327
8 changed files with 267 additions and 54 deletions

View File

@@ -1,8 +1,11 @@
package services
import (
"archive/tar"
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strconv"
@@ -199,7 +202,64 @@ func ResizeConnection(name string, cols, rows uint) error {
return c.ContainerResize(context.Background(), name, types.ResizeOptions{Height: rows, Width: cols})
}
func CreateInstance(session *Session, dindImage string) (*Instance, error) {
func CopyToContainer(containerName, destination, fileName string, content io.Reader) error {
r, w := io.Pipe()
b, readErr := ioutil.ReadAll(content)
if readErr != nil {
return readErr
}
t := tar.NewWriter(w)
go func() {
t.WriteHeader(&tar.Header{Name: fileName, Mode: 0600, Size: int64(len(b))})
t.Write(b)
t.Close()
w.Close()
}()
return c.CopyToContainer(context.Background(), containerName, destination, r, types.CopyToContainerOptions{AllowOverwriteDirWithFile: true})
}
func CreateInstance(session *Session, conf InstanceConfig) (*Instance, error) {
var nodeName string
var containerName string
for i := 1; ; i++ {
nodeName = fmt.Sprintf("node%d", i)
containerName = fmt.Sprintf("%s_%s", session.Id[:8], nodeName)
exists := false
for _, instance := range session.Instances {
if instance.Name == containerName {
exists = true
break
}
}
if !exists {
break
}
}
// Make sure directories are available for the new instance container
containerDir := "/var/run/pwd"
containerCertDir := fmt.Sprintf("%s/certs", containerDir)
env := []string{}
// Write certs to container cert dir
if len(conf.ServerCert) > 0 {
env = append(env, "DOCKER_TLSCERT=/var/run/pwd/certs/cert.pem")
}
if len(conf.ServerKey) > 0 {
env = append(env, "DOCKER_TLSKEY=/var/run/pwd/certs/key.pem")
}
if len(conf.CACert) > 0 {
// if ca cert is specified, verify that clients that connects present a certificate signed by the CA
env = append(env, "DOCKER_TLSCACERT=/var/run/pwd/certs/ca.pem")
}
if len(conf.ServerCert) > 0 || len(conf.ServerKey) > 0 || len(conf.CACert) > 0 {
// if any of the certs is specified, enable TLS
env = append(env, "DOCKER_TLSENABLE=true")
} else {
env = append(env, "DOCKER_TLSENABLE=false")
}
h := &container.HostConfig{
NetworkMode: container.NetworkMode(session.Id),
Privileged: true,
@@ -222,42 +282,37 @@ func CreateInstance(session *Session, dindImage string) (*Instance, error) {
t := true
h.Resources.OomKillDisable = &t
var nodeName string
var containerName string
for i := 1; ; i++ {
nodeName = fmt.Sprintf("node%d", i)
containerName = fmt.Sprintf("%s_%s", session.Id[:8], nodeName)
exists := false
for _, instance := range session.Instances {
if instance.Name == containerName {
exists = true
break
}
}
if !exists {
break
}
}
conf := &container.Config{Hostname: nodeName,
env = append(env, fmt.Sprintf("PWD_IP_ADDRESS=%s", session.PwdIpAddress))
cf := &container.Config{Hostname: nodeName,
Image: dindImage,
Tty: true,
OpenStdin: true,
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Env: []string{fmt.Sprintf("PWD_IP_ADDRESS=%s", session.PwdIpAddress)},
Env: env,
}
networkConf := &network.NetworkingConfig{
map[string]*network.EndpointSettings{
session.Id: &network.EndpointSettings{Aliases: []string{nodeName}},
},
}
container, err := c.ContainerCreate(context.Background(), conf, h, networkConf, containerName)
container, err := c.ContainerCreate(context.Background(), cf, h, networkConf, containerName)
if err != nil {
return nil, err
}
if err := copyIfSet(conf.ServerCert, "cert.pem", containerCertDir, containerName); err != nil {
return nil, err
}
if err := copyIfSet(conf.ServerKey, "key.pem", containerCertDir, containerName); err != nil {
return nil, err
}
if err := copyIfSet(conf.CACert, "ca.pem", containerCertDir, containerName); err != nil {
return nil, err
}
err = c.ContainerStart(context.Background(), container.ID, types.ContainerStartOptions{})
if err != nil {
return nil, err
@@ -271,6 +326,13 @@ func CreateInstance(session *Session, dindImage string) (*Instance, error) {
return &Instance{Name: containerName, Hostname: cinfo.Config.Hostname, IP: cinfo.NetworkSettings.Networks[session.Id].IPAddress}, nil
}
func copyIfSet(content []byte, fileName, path, containerName string) error {
if len(content) > 0 {
return CopyToContainer(containerName, path, fileName, bytes.NewReader(content))
}
return nil
}
func DeleteContainer(id string) error {
return c.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{Force: true, RemoveVolumes: true})
}