Skip to content

Commit

Permalink
Add server info
Browse files Browse the repository at this point in the history
Based off of #128
  • Loading branch information
jwilder committed Jan 2, 2016
1 parent 3b55980 commit 5043565
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 107 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,21 @@ type SwarmNode struct {
Name string
Address Address
}

// Accessible from the root in templates as .Docker
type Docker struct {
Name string
NumContainers int
NumImages int
Version string
ApiVersion string
GoVersion string
OperatingSystem string
Architecture string
}

// Host environment variables accessible from root in templates as .Env

```

For example, this is a JSON version of an emitted RuntimeContainer struct:
Expand Down
51 changes: 42 additions & 9 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
package dockergen

import "os"
import (
"os"
"sync"

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

var (
mu sync.RWMutex
dockerInfo Docker
dockerEnv *docker.Env
)

type Context []*RuntimeContainer

func (c *Context) Env() map[string]string {
return splitKeyValueSlice(os.Environ())
}

func (c *Context) Docker() Docker {
mu.RLock()
defer mu.RUnlock()
return dockerInfo
}

func SetServerInfo(d *docker.Env) {
mu.Lock()
defer mu.Unlock()
dockerInfo = Docker{
Name: d.Get("Name"),
NumContainers: d.GetInt("Containers"),
NumImages: d.GetInt("Images"),
Version: dockerEnv.Get("Version"),
ApiVersion: dockerEnv.Get("ApiVersion"),
GoVersion: dockerEnv.Get("GoVersion"),
OperatingSystem: dockerEnv.Get("Os"),
Architecture: dockerEnv.Get("Arch"),
}
}

func SetDockerEnv(d *docker.Env) {
mu.Lock()
defer mu.Unlock()
dockerEnv = d
}

type Address struct {
IP string
IP6LinkLocal string
Expand Down Expand Up @@ -51,7 +89,6 @@ type RuntimeContainer struct {
IP string
IP6LinkLocal string
IP6Global string
Server Server
}

func (r *RuntimeContainer) Equals(o RuntimeContainer) bool {
Expand Down Expand Up @@ -91,14 +128,10 @@ type SwarmNode struct {
Address Address
}

type Server struct {
Name string
NumContainers int
NumImages int
Docker Docker
}

type Docker struct {
Name string
NumContainers int
NumImages int
Version string
ApiVersion string
GoVersion string
Expand Down
94 changes: 0 additions & 94 deletions docker_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package dockergen
import (
"errors"
"fmt"
"log"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -120,99 +119,6 @@ func splitDockerImage(img string) (string, string, string) {
return registry, repository, tag
}

func GetContainers(client *docker.Client) ([]*RuntimeContainer, error) {
apiContainers, err := client.ListContainers(docker.ListContainersOptions{
All: false,
Size: false,
})
if err != nil {
return nil, err
}

containers := []*RuntimeContainer{}
for _, apiContainer := range apiContainers {
container, err := client.InspectContainer(apiContainer.ID)
if err != nil {
log.Printf("error inspecting container: %s: %s\n", apiContainer.ID, err)
continue
}

registry, repository, tag := splitDockerImage(container.Config.Image)
runtimeContainer := &RuntimeContainer{
ID: container.ID,
Image: DockerImage{
Registry: registry,
Repository: repository,
Tag: tag,
},
Name: strings.TrimLeft(container.Name, "/"),
Hostname: container.Config.Hostname,
Gateway: container.NetworkSettings.Gateway,
Addresses: []Address{},
Networks: []Network{},
Env: make(map[string]string),
Volumes: make(map[string]Volume),
Node: SwarmNode{},
Labels: make(map[string]string),
IP: container.NetworkSettings.IPAddress,
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
IP6Global: container.NetworkSettings.GlobalIPv6Address,
}
for k, v := range container.NetworkSettings.Ports {
address := Address{
IP: container.NetworkSettings.IPAddress,
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
IP6Global: container.NetworkSettings.GlobalIPv6Address,
Port: k.Port(),
Proto: k.Proto(),
}
if len(v) > 0 {
address.HostPort = v[0].HostPort
address.HostIP = v[0].HostIP
}
runtimeContainer.Addresses = append(runtimeContainer.Addresses,
address)

}
for k, v := range container.NetworkSettings.Networks {
network := Network{
IP: v.IPAddress,
Name: k,
Gateway: v.Gateway,
EndpointID: v.EndpointID,
IPv6Gateway: v.IPv6Gateway,
GlobalIPv6Address: v.GlobalIPv6Address,
MacAddress: v.MacAddress,
GlobalIPv6PrefixLen: v.GlobalIPv6PrefixLen,
IPPrefixLen: v.IPPrefixLen,
}

runtimeContainer.Networks = append(runtimeContainer.Networks,
network)
}
for k, v := range container.Volumes {
runtimeContainer.Volumes[k] = Volume{
Path: k,
HostPath: v,
ReadWrite: container.VolumesRW[k],
}
}
if container.Node != nil {
runtimeContainer.Node.ID = container.Node.ID
runtimeContainer.Node.Name = container.Node.Name
runtimeContainer.Node.Address = Address{
IP: container.Node.IP,
}
}

runtimeContainer.Env = splitKeyValueSlice(container.Config.Env)
runtimeContainer.Labels = container.Config.Labels
containers = append(containers, runtimeContainer)
}
return containers, nil

}

// pathExists returns whether the given file or directory exists or not
func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
Expand Down
114 changes: 110 additions & 4 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ type generator struct {
TLSVerify bool
TLSCert, TLSCaCert, TLSKey string

dockerInfo Server

wg sync.WaitGroup
}

Expand All @@ -45,6 +43,14 @@ func NewGenerator(gc GeneratorConfig) (*generator, error) {
return nil, fmt.Errorf("Unable to create docker client: %s", err)
}

apiVersion, err := client.Version()
if err != nil {
log.Printf("error retrieving docker server version info: %s\n", err)
}

// Grab the docker daemon info once and hold onto it
SetDockerEnv(apiVersion)

return &generator{
Client: client,
Endpoint: gc.Endpoint,
Expand All @@ -66,7 +72,7 @@ func (g *generator) Generate() error {
}

func (g *generator) generateFromContainers(client *docker.Client) {
containers, err := GetContainers(client)
containers, err := g.getContainers(client)
if err != nil {
log.Printf("error listing containers: %s\n", err)
return
Expand Down Expand Up @@ -99,7 +105,7 @@ func (g *generator) generateAtInterval(client *docker.Client, configs ConfigFile
for {
select {
case <-ticker.C:
containers, err := GetContainers(client)
containers, err := g.getContainers(client)
if err != nil {
log.Printf("Error listing containers: %s\n", err)
continue
Expand Down Expand Up @@ -238,3 +244,103 @@ func (g *generator) sendSignalToContainer(client *docker.Client, config Config)
}
}
}

func (g *generator) getContainers(client *docker.Client) ([]*RuntimeContainer, error) {
apiInfo, err := client.Info()
if err != nil {
log.Printf("error retrieving docker server info: %s\n", err)
}

SetServerInfo(apiInfo)

apiContainers, err := client.ListContainers(docker.ListContainersOptions{
All: false,
Size: false,
})
if err != nil {
return nil, err
}

containers := []*RuntimeContainer{}
for _, apiContainer := range apiContainers {
container, err := client.InspectContainer(apiContainer.ID)
if err != nil {
log.Printf("error inspecting container: %s: %s\n", apiContainer.ID, err)
continue
}

registry, repository, tag := splitDockerImage(container.Config.Image)
runtimeContainer := &RuntimeContainer{
ID: container.ID,
Image: DockerImage{
Registry: registry,
Repository: repository,
Tag: tag,
},
Name: strings.TrimLeft(container.Name, "/"),
Hostname: container.Config.Hostname,
Gateway: container.NetworkSettings.Gateway,
Addresses: []Address{},
Networks: []Network{},
Env: make(map[string]string),
Volumes: make(map[string]Volume),
Node: SwarmNode{},
Labels: make(map[string]string),
IP: container.NetworkSettings.IPAddress,
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
IP6Global: container.NetworkSettings.GlobalIPv6Address,
}
for k, v := range container.NetworkSettings.Ports {
address := Address{
IP: container.NetworkSettings.IPAddress,
IP6LinkLocal: container.NetworkSettings.LinkLocalIPv6Address,
IP6Global: container.NetworkSettings.GlobalIPv6Address,
Port: k.Port(),
Proto: k.Proto(),
}
if len(v) > 0 {
address.HostPort = v[0].HostPort
address.HostIP = v[0].HostIP
}
runtimeContainer.Addresses = append(runtimeContainer.Addresses,
address)

}
for k, v := range container.NetworkSettings.Networks {
network := Network{
IP: v.IPAddress,
Name: k,
Gateway: v.Gateway,
EndpointID: v.EndpointID,
IPv6Gateway: v.IPv6Gateway,
GlobalIPv6Address: v.GlobalIPv6Address,
MacAddress: v.MacAddress,
GlobalIPv6PrefixLen: v.GlobalIPv6PrefixLen,
IPPrefixLen: v.IPPrefixLen,
}

runtimeContainer.Networks = append(runtimeContainer.Networks,
network)
}
for k, v := range container.Volumes {
runtimeContainer.Volumes[k] = Volume{
Path: k,
HostPath: v,
ReadWrite: container.VolumesRW[k],
}
}
if container.Node != nil {
runtimeContainer.Node.ID = container.Node.ID
runtimeContainer.Node.Name = container.Node.Name
runtimeContainer.Node.Address = Address{
IP: container.Node.IP,
}
}

runtimeContainer.Env = splitKeyValueSlice(container.Config.Env)
runtimeContainer.Labels = container.Config.Labels
containers = append(containers, runtimeContainer)
}
return containers, nil

}
1 change: 1 addition & 0 deletions templates/etcd.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#!/bin/bash

# Genenerated by {{ .Env.USER }}
# Docker Version {{ .Docker.Version }}

{{range $key, $value := .}}
{{ $addrLen := len $value.Addresses }}
Expand Down

0 comments on commit 5043565

Please sign in to comment.