Skip to content

Commit

Permalink
use libmachine directly
Browse files Browse the repository at this point in the history
  • Loading branch information
bamarni committed Apr 18, 2016
1 parent 547fd33 commit d36d821
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 53 deletions.
42 changes: 13 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DNS for Docker machines, allows to access them with the following domain format

It spins up a simplistic DNS server, only listening for questions about A records.

Behind the scene it will run `docker-machine ip {machine}` in order to resolve the IP address of a given machine.
Behind the scene it will use [libmachine](https://github.com/docker/machine) in order to resolve IP addresses.

## Installation

Expand All @@ -21,33 +21,31 @@ Prebuilt binaries are available in the [releases](https://github.com/bamarni/doc

### From source (requires Go)

go get github.com/miekg/dns
go get github.com/bamarni/dockness
go get github.com/miekg/dns github.com/docker/machine github.com/bamarni/dockness

## Usage

dockness [options...]

Options:
-tld Top-level domain to use (defaults to "docker")
-ttl Time to Live for DNS records (defaults to 0)
-port Port to listen on (defaults to "53")
-server-only Server only, doesn't try to create a resolver configuration file
-user Execute the "docker-machine ip" command as a different user (defaults to "SUDO_USER")
-tld Top-level domain to use (defaults to "docker")
-ttl Time to Live for DNS records (defaults to 0)
-port Port to listen on (defaults to "53")
-debug Enable debugging (defaults to false)

### Mac OSX

To develop on Mac you probably have a local VM, using VirtualBox for example.
However this machine gets assigned a dynamic IP address.

The program can be up and running in one command :
You can be up and running in a few commands, first :

> sudo dockness
2016/02/18 10:39:52 Creating configuration file at /etc/resolver/docker...
2016/02/18 10:39:52 Listening on :53...
> echo "nameserver 127.0.0.1\nport 10053" | sudo tee /etc/resolver/docker

*If you don't want to run the program as root, you can create the resolver file yourself and use a high port.
Cf. example in the [Configure as a service](#configure-dockness-as-a-service) section.*
It tells your Mac that the resolver for `.docker` TLD listens locally on port 10053. You can now run the resolver on this port :

> dockness -port 10053
2016/02/18 10:39:52 Listening on :10053...

### Linux

Expand Down Expand Up @@ -77,11 +75,7 @@ Doing so, it will be running in the background automatically when booting your c

### Mac OSX

Run this command : `echo "nameserver 127.0.0.1\nport 10053" | sudo tee /etc/resolver/docker`

It tells your Mac that the resolver for `.docker` TLD listens locally on port 10053.

You can now create the appropriate service configuration file at `~/Library/LaunchAgents/local.dockness.plist` :
You can create the appropriate service configuration file at `~/Library/LaunchAgents/local.dockness.plist` :

``` xml
<?xml version="1.0" encoding="UTF-8"?>
Expand All @@ -90,17 +84,11 @@ You can now create the appropriate service configuration file at `~/Library/Laun
<dict>
<key>Disabled</key>
<false/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin</string>
</dict>
<key>Label</key>
<string>local.dockness</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/dockness</string>
<string>-server-only</string>
<string>-port</string>
<string>10053</string>
</array>
Expand All @@ -110,10 +98,6 @@ You can now create the appropriate service configuration file at `~/Library/Laun
</plist>
```

You'll have to adapt 2 parameters :
- `/path/to/dockness`
- `/usr/local/bin`, which is the directory containing your `docker-machine` executable

Finally, the service can be enabled :

launchctl load ~/Library/LaunchAgents/local.dockness.plist
Expand Down
40 changes: 16 additions & 24 deletions dockness.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package main

import (
"flag"
"github.com/docker/machine/commands/mcndirs"
"github.com/docker/machine/libmachine"
mcnlog "github.com/docker/machine/libmachine/log"
"github.com/miekg/dns"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"os/signal"
"runtime"
"strings"
)

var api *libmachine.Client
var ttl uint
var user string

Expand All @@ -33,21 +34,19 @@ func lookup(w dns.ResponseWriter, r *dns.Msg) {
log.Printf("Couldn't parse the DNS question '%s'", q.Name)
continue
}
machine := domLevels[len(domLevels)-3]

var output []byte
var err error
if user == "" {
output, err = exec.Command("docker-machine", "ip", machine).CombinedOutput()
} else {
output, err = exec.Command("sudo", "-u", user, "docker-machine", "ip", machine).CombinedOutput()
machineName := domLevels[len(domLevels)-3]

machine, err := api.Load(machineName)
if err != nil {
log.Printf("Couldn't load machine '%s' : %s", machineName, err)
continue
}

ip, err := machine.Driver.GetIP()
if err != nil {
log.Printf("No IP found for machine '%s' (%s)", machine, output)
log.Printf("Couldn't find IP for machine '%s' : %s", machineName, err)
continue
}
ip := string(output[:len(output)-1])

rr = &dns.A{
Hdr: dns.RR_Header{
Expand All @@ -69,19 +68,12 @@ func main() {
tld := flag.String("tld", "docker", "Top-level domain to use")
flag.UintVar(&ttl, "ttl", 0, "Time to Live for DNS records")
port := flag.String("port", "53", "Port to listen on")
serverOnly := flag.Bool("server-only", false, "Server only, doesn't try to create a resolver configuration")
flag.StringVar(&user, "user", os.Getenv("SUDO_USER"), "Execute the 'docker-machine ip' command as this user")
debug := flag.Bool("debug", false, "Enable debugging")
flag.Parse()

if *serverOnly == false && runtime.GOOS == "darwin" {
confPath := "/etc/resolver/" + *tld
log.Printf("Creating configuration file at %s...", confPath)
conf := []byte("nameserver 127.0.0.1\nport " + *port + "\n")
if err := ioutil.WriteFile(confPath, conf, 0644); err != nil {
log.Fatalf("Could not create configuration file: %s", err)
}
defer os.Remove(confPath)
}
mcnlog.SetDebug(*debug)
api = libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir())
defer api.Close()

addr := ":" + *port
server := &dns.Server{
Expand Down

0 comments on commit d36d821

Please sign in to comment.