mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-06 21:51:33 +00:00
Initial commit to add links and inject env
This commit is contained in:
@@ -957,6 +957,20 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
||||
}
|
||||
|
||||
func getLinksJSON(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
out := []APILink{}
|
||||
name := r.FormValue("name")
|
||||
|
||||
links := srv.runtime.links.Get(name)
|
||||
for _, l := range links {
|
||||
out = append(out, APILink{l.To, l.From, l.Addr, l.Alias})
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeHttpHandler(srv *Server, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// log the request
|
||||
@@ -1012,6 +1026,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
|
||||
"/containers/{name:.*}/json": getContainersByName,
|
||||
"/containers/{name:.*}/top": getContainersTop,
|
||||
"/containers/{name:.*}/attach/ws": wsContainersAttach,
|
||||
"/links/json": getLinksJSON,
|
||||
},
|
||||
"POST": {
|
||||
"/auth": postAuth,
|
||||
|
||||
@@ -120,3 +120,10 @@ type APICopy struct {
|
||||
Resource string
|
||||
HostPath string
|
||||
}
|
||||
|
||||
type APILink struct {
|
||||
To string
|
||||
From string
|
||||
Addr string
|
||||
Alias string
|
||||
}
|
||||
|
||||
+31
@@ -1112,6 +1112,37 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) CmdLink(args ...string) error {
|
||||
cmd := Subcmd("link", "[OPTIONS] CONTAINER", "Get the links for a container")
|
||||
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("name", cmd.Arg(0))
|
||||
|
||||
body, _, err := cli.call("GET", "/links/json?"+v.Encode(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var links []APILink
|
||||
if err := json.Unmarshal(body, &links); err != nil {
|
||||
return err
|
||||
}
|
||||
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
|
||||
|
||||
fmt.Fprintf(w, "FROM\tTO\tADDRESS\tALIAS")
|
||||
fmt.Fprintf(w, "\n")
|
||||
for _, l := range links {
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s", l.From, l.To, l.Addr, l.Alias)
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
w.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) CmdCommit(args ...string) error {
|
||||
cmd := Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY [TAG]]", "Create a new image from a container's changes")
|
||||
flComment := cmd.String("m", "", "Commit message")
|
||||
|
||||
@@ -91,6 +91,7 @@ type HostConfig struct {
|
||||
ContainerIDFile string
|
||||
LxcConf []KeyValuePair
|
||||
PortBindings map[Port][]PortBinding
|
||||
Links []Link
|
||||
}
|
||||
|
||||
type BindMap struct {
|
||||
@@ -179,6 +180,9 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||
var flLxcOpts ListOpts
|
||||
cmd.Var(&flLxcOpts, "lxc-conf", "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
|
||||
|
||||
var flLinks ListOpts
|
||||
cmd.Var(&flLinks, "link", "Add link to another container (containerid:port:alias)")
|
||||
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
@@ -250,6 +254,22 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
|
||||
// Merge in exposed ports to the map of published ports
|
||||
for _, e := range flExpose {
|
||||
if strings.Contains(e, ":") {
|
||||
return nil, nil, cmd, fmt.Errorf("Invalid port format for -expose: %s", e)
|
||||
}
|
||||
p := NewPort(splitProtoPort(e))
|
||||
if _, exists := ports[p]; !exists {
|
||||
ports[p] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
links, err := parseLinks(flLinks)
|
||||
if err != nil {
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
|
||||
config := &Config{
|
||||
Hostname: *flHostname,
|
||||
Domainname: domainname,
|
||||
@@ -280,6 +300,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||
ContainerIDFile: *flContainerIDFile,
|
||||
LxcConf: lxcConf,
|
||||
PortBindings: portBindings,
|
||||
Links: links,
|
||||
}
|
||||
|
||||
if capabilities != nil && *flMemory > 0 && !capabilities.SwapLimit {
|
||||
@@ -805,6 +826,31 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
||||
"-e", "container=lxc",
|
||||
"-e", "HOSTNAME="+container.Config.Hostname,
|
||||
)
|
||||
|
||||
if hostConfig != nil && hostConfig.Links != nil {
|
||||
runtime := container.runtime
|
||||
for _, l := range hostConfig.Links {
|
||||
linkedContainer := runtime.Get(l.From)
|
||||
if linkedContainer == nil {
|
||||
return fmt.Errorf("Cannot locate container for link: %s AS %s", l.From, l.Alias)
|
||||
}
|
||||
if !linkedContainer.State.Running {
|
||||
return fmt.Errorf("Cannot link a non running container: %s AS %s", l.From, l.Alias)
|
||||
}
|
||||
|
||||
// Check for linkedContainer exposed ports
|
||||
//
|
||||
// Hide ports that are not requested
|
||||
|
||||
l.To = utils.TruncateID(container.ID)
|
||||
l.Addr = fmt.Sprintf("%s:%s", linkedContainer.NetworkSettings.IPAddress, l.Port)
|
||||
if err := runtime.links.RegisterLink(l); err != nil {
|
||||
return nil
|
||||
}
|
||||
params = append(params, "-e", l.ToEnv())
|
||||
}
|
||||
}
|
||||
|
||||
if container.Config.WorkingDir != "" {
|
||||
workingDir := path.Clean(container.Config.WorkingDir)
|
||||
utils.Debugf("[working dir] working dir is %s", workingDir)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Link struct {
|
||||
From string
|
||||
To string
|
||||
Addr string
|
||||
Alias string
|
||||
Port string
|
||||
}
|
||||
|
||||
type LinkRepository struct {
|
||||
links map[string]Link
|
||||
}
|
||||
|
||||
func (l *Link) ToEnv() string {
|
||||
return fmt.Sprintf("%s_ADDR=%s", strings.ToUpper(l.Alias), l.Addr)
|
||||
}
|
||||
|
||||
func NewLinkRepository(root string) (*LinkRepository, error) {
|
||||
r := &LinkRepository{make(map[string]Link)}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Return all links for a container
|
||||
func (l *LinkRepository) Get(id string) []Link {
|
||||
id = strings.Trim(strings.ToLower(id), "")
|
||||
out := []Link{}
|
||||
for _, link := range l.links {
|
||||
if link.To == id || link.From == id {
|
||||
out = append(out, link)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Returns the link for a current alias
|
||||
func (l *LinkRepository) GetByAlias(alias string) (Link, error) {
|
||||
link, exists := l.links[alias]
|
||||
if !exists {
|
||||
return link, fmt.Errorf("Link does not exist for alias: %s", alias)
|
||||
}
|
||||
return link, nil
|
||||
}
|
||||
|
||||
// Create a new link with a unique alias
|
||||
func (l *LinkRepository) RegisterLink(link Link) error {
|
||||
if _, exists := l.links[link.Alias]; exists {
|
||||
return fmt.Errorf("A link for %s already exists", link.Alias)
|
||||
}
|
||||
utils.Debugf("Registering link: %v", link)
|
||||
l.links[link.Alias] = link
|
||||
return nil
|
||||
}
|
||||
@@ -35,6 +35,7 @@ type Runtime struct {
|
||||
volumes *Graph
|
||||
srv *Server
|
||||
config *DaemonConfig
|
||||
links *LinkRepository
|
||||
}
|
||||
|
||||
var sysInitPath string
|
||||
@@ -452,6 +453,11 @@ func NewRuntime(config *DaemonConfig) (*Runtime, error) {
|
||||
}
|
||||
}
|
||||
runtime.UpdateCapabilities(false)
|
||||
links, err := NewLinkRepository("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtime.links = links
|
||||
return runtime, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -281,3 +281,30 @@ func migratePortMappings(config *Config) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Links come in the format of
|
||||
// id:port:alias
|
||||
func parseLink(rawLink string) (Link, error) {
|
||||
parts, err := utils.PartParser("id:port:alias", rawLink)
|
||||
if err != nil {
|
||||
return Link{}, err
|
||||
}
|
||||
|
||||
return Link{
|
||||
From: parts["id"],
|
||||
Alias: parts["alias"],
|
||||
Port: parts["port"],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseLinks(rawLinks []string) ([]Link, error) {
|
||||
out := make([]Link, len(rawLinks))
|
||||
for i, l := range rawLinks {
|
||||
link, err := parseLink(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = link
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package docker
|
||||
|
||||
// Returns a new virtual container for interfacing with the host interfaces
|
||||
func NewHostContainer() (*Container, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Returns a new virutal container for interfacing with the docker daemon
|
||||
func NewDockerContainer() (*Container, error) {
|
||||
return nil, nil
|
||||
}
|
||||
Reference in New Issue
Block a user