Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

weaveworks / weave / #6773

15 Jun 2016 - 14:50 coverage decreased (-0.03%) to 73.692%
#6773

Pull #2366

circleci

94ccfc629c6862b5950de3512742bcae?size=18&default=identiconbboreham
Publish weavedb container from release script
Pull Request #2366: Publish weavedb container from release script

6493 of 8811 relevant lines covered (73.69%)

120432.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.58
/proxy/proxy.go
1
package proxy
2

3
import (
4
        "bytes"
5
        "crypto/tls"
6
        "errors"
7
        "fmt"
8
        "net"
9
        "net/http"
10
        "os"
11
        "path/filepath"
12
        "regexp"
13
        "strings"
14
        "sync"
15
        "syscall"
16
        "time"
17

18
        docker "github.com/fsouza/go-dockerclient"
19
        weaveapi "github.com/weaveworks/weave/api"
20
        "github.com/weaveworks/weave/common"
21
        weavedocker "github.com/weaveworks/weave/common/docker"
22
        weavenet "github.com/weaveworks/weave/net"
23
)
24

25
const (
26
        defaultCaFile   = "ca.pem"
27
        defaultKeyFile  = "key.pem"
28
        defaultCertFile = "cert.pem"
29

30
        weaveSock     = "/var/run/weave/weave.sock"
31
        weaveSockUnix = "unix://" + weaveSock
32

33
        initialInterval = 2 * time.Second
34
        maxInterval     = 1 * time.Minute
35
)
36

37
var (
38
        containerCreateRegexp  = dockerAPIEndpoint("containers/create")
39
        containerStartRegexp   = dockerAPIEndpoint("containers/[^/]*/(re)?start")
40
        containerInspectRegexp = dockerAPIEndpoint("containers/[^/]*/json")
41
        execCreateRegexp       = dockerAPIEndpoint("containers/[^/]*/exec")
42
        execInspectRegexp      = dockerAPIEndpoint("exec/[^/]*/json")
43

44
        ErrWeaveCIDRNone = errors.New("the container was created with the '-e WEAVE_CIDR=none' option")
45
        ErrNoDefaultIPAM = errors.New("the container was created without specifying an IP address with '-e WEAVE_CIDR=...' and the proxy was started with the '--no-default-ipalloc' option")
46
)
47

48
func dockerAPIEndpoint(endpoint string) *regexp.Regexp {
375×
49
        return regexp.MustCompile("^(/v[0-9\\.]*)?/" + endpoint + "$")
375×
50
}
375×
51

52
type Config struct {
53
        HostnameFromLabel   string
54
        HostnameMatch       string
55
        HostnameReplacement string
56
        Image               string
57
        ListenAddrs         []string
58
        RewriteInspect      bool
59
        NoDefaultIPAM       bool
60
        NoRewriteHosts      bool
61
        TLSConfig           TLSConfig
62
        Version             string
63
        WithoutDNS          bool
64
        NoMulticastRoute    bool
65
        DockerBridge        string
66
        DockerHost          string
67
}
68

69
type wait struct {
70
        ident string
71
        ch    chan error
72
        done  bool
73
}
74

75
type Proxy struct {
76
        sync.Mutex
77
        Config
78
        client                 *docker.Client
79
        dockerBridgeIP         string
80
        hostnameMatchRegexp    *regexp.Regexp
81
        weaveWaitVolume        string
82
        weaveWaitNoopVolume    string
83
        weaveWaitNomcastVolume string
84
        normalisedAddrs        []string
85
        waiters                map[*http.Request]*wait
86
        attachJobs             map[string]*attachJob
87
        quit                   chan struct{}
88
}
89

90
type attachJob struct {
91
        id          string
92
        tryInterval time.Duration // retry delay on next failure
93
        timer       *time.Timer
94
}
95

96
func (proxy *Proxy) attachWithRetry(id string) {
224×
97
        proxy.Lock()
224×
98
        defer proxy.Unlock()
224×
99
        if j, ok := proxy.attachJobs[id]; ok {
224×
UNCOV
100
                j.timer.Reset(time.Duration(0))
!
101
                return
!
102
        }
!
103

104
        j := &attachJob{id: id, tryInterval: initialInterval}
224×
105
        j.timer = time.AfterFunc(time.Duration(0), func() {
449×
106
                if err := proxy.attach(id); err != nil {
229×
107
                        // The delay at the nth retry is a random value in the range
4×
108
                        // [i-i/2,i+i/2], where i = initialInterval * 1.5^(n-1).
4×
109
                        j.timer.Reset(j.tryInterval)
4×
110
                        j.tryInterval = j.tryInterval * 3 / 2
4×
111
                        if j.tryInterval > maxInterval {
4×
UNCOV
112
                                j.tryInterval = maxInterval
!
113
                        }
!
114
                        return
4×
115
                }
116
                proxy.notifyWaiters(id, nil)
221×
117
        })
118
        proxy.attachJobs[id] = j
224×
119
}
120

121
func (j attachJob) Stop() {
224×
122
        j.timer.Stop()
224×
123
}
224×
124

125
func NewProxy(c Config) (*Proxy, error) {
74×
126
        p := &Proxy{
74×
127
                Config:     c,
74×
128
                waiters:    make(map[*http.Request]*wait),
74×
129
                attachJobs: make(map[string]*attachJob),
74×
130
                quit:       make(chan struct{}),
74×
131
        }
74×
132

74×
133
        if err := p.TLSConfig.LoadCerts(); err != nil {
74×
UNCOV
134
                Log.Fatalf("Could not configure tls for proxy: %s", err)
!
135
        }
!
136

137
        // We pin the protocol version to 1.18 (which corresponds to
138
        // Docker 1.6.x; the earliest version supported by weave) in order
139
        // to insulate ourselves from breaking changes to the API, as
140
        // happened in 1.20 (Docker 1.8.0) when the presentation of
141
        // volumes changed in `inspect`.
142
        client, err := weavedocker.NewVersionedClient(c.DockerHost, "1.18")
74×
143
        if err != nil {
74×
UNCOV
144
                return nil, err
!
145
        }
!
146
        Log.Info(client.Info())
74×
147

74×
148
        p.client = client.Client
74×
149

74×
150
        if !p.WithoutDNS {
148×
151
                netDevs, err := common.GetBridgeNetDev(c.DockerBridge)
74×
152
                if err != nil {
74×
UNCOV
153
                        return nil, err
!
154
                }
!
155
                if len(netDevs) != 1 || len(netDevs[0].CIDRs) != 1 {
74×
UNCOV
156
                        return nil, fmt.Errorf("Could not obtain address of %s", c.DockerBridge)
!
157
                }
!
158
                p.dockerBridgeIP = netDevs[0].CIDRs[0].IP.String()
74×
159
        }
160

161
        p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch)
74×
162
        if err != nil {
74×
UNCOV
163
                err := fmt.Errorf("Incorrect hostname match '%s': %s", c.HostnameMatch, err.Error())
!
164
                return nil, err
!
165
        }
!
166

167
        if err = p.findWeaveWaitVolumes(); err != nil {
74×
UNCOV
168
                return nil, err
!
169
        }
!
170

171
        client.AddObserver(p)
74×
172

74×
173
        return p, nil
74×
174
}
175

176
func (proxy *Proxy) AttachExistingContainers() {
74×
177
        containers, _ := proxy.client.ListContainers(docker.ListContainersOptions{})
74×
178
        for _, c := range containers {
298×
179
                proxy.attachWithRetry(c.ID)
224×
180
        }
224×
181
}
182

183
func (proxy *Proxy) Dial() (net.Conn, error) {
916×
184
        proto := "tcp"
916×
185
        addr := proxy.Config.DockerHost
916×
186
        switch {
916×
187
        case strings.HasPrefix(addr, "unix://"):
916×
188
                proto = "unix"
916×
189
                addr = strings.TrimPrefix(addr, "unix://")
916×
UNCOV
190
        case strings.HasPrefix(addr, "tcp://"):
!
191
                addr = strings.TrimPrefix(addr, "tcp://")
!
192
        }
193
        return net.Dial(proto, addr)
916×
194
}
195

196
func (proxy *Proxy) findWeaveWaitVolumes() error {
74×
197
        var err error
74×
198
        if proxy.weaveWaitVolume, err = proxy.findVolume("/w"); err != nil {
74×
UNCOV
199
                return err
!
200
        }
!
201
        if proxy.weaveWaitNoopVolume, err = proxy.findVolume("/w-noop"); err != nil {
74×
UNCOV
202
                return err
!
203
        }
!
204
        proxy.weaveWaitNomcastVolume, err = proxy.findVolume("/w-nomcast")
74×
205
        return err
74×
206
}
207

208
func (proxy *Proxy) findVolume(v string) (string, error) {
222×
209
        container, err := proxy.client.InspectContainer("weaveproxy")
222×
210
        if err != nil {
222×
UNCOV
211
                return "", fmt.Errorf("Could not find the weavewait volume: %s", err)
!
212
        }
!
213

214
        if container.Volumes == nil {
222×
UNCOV
215
                return "", fmt.Errorf("Could not find the weavewait volume")
!
216
        }
!
217

218
        volume, ok := container.Volumes[v]
222×
219
        if !ok {
222×
UNCOV
220
                return "", fmt.Errorf("Could not find the weavewait volume")
!
221
        }
!
222

223
        return volume, nil
222×
224
}
225

226
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
917×
227
        Log.Infof("%s %s", r.Method, r.URL)
917×
228
        path := r.URL.Path
917×
229
        var i interceptor
917×
230
        switch {
917×
231
        case containerCreateRegexp.MatchString(path):
157×
232
                i = &createContainerInterceptor{proxy}
157×
233
        case containerStartRegexp.MatchString(path):
185×
234
                i = &startContainerInterceptor{proxy}
185×
235
        case containerInspectRegexp.MatchString(path):
66×
236
                i = &inspectContainerInterceptor{proxy}
66×
237
        case execCreateRegexp.MatchString(path):
21×
238
                i = &createExecInterceptor{proxy}
21×
239
        case execInspectRegexp.MatchString(path):
15×
240
                i = &inspectExecInterceptor{proxy}
15×
241
        default:
473×
242
                i = &nullInterceptor{}
473×
243
        }
244
        proxy.Intercept(i, w, r)
917×
245
}
246

247
func (proxy *Proxy) Listen() []net.Listener {
74×
248
        listeners := []net.Listener{}
74×
249
        proxy.normalisedAddrs = []string{}
74×
250
        unixAddrs := []string{}
74×
251
        for _, addr := range proxy.ListenAddrs {
148×
252
                if strings.HasPrefix(addr, "unix://") || strings.HasPrefix(addr, "/") {
76×
253
                        unixAddrs = append(unixAddrs, addr)
2×
254
                        continue
2×
255
                }
256
                listener, normalisedAddr, err := proxy.listen(addr)
72×
257
                if err != nil {
72×
UNCOV
258
                        Log.Fatalf("Cannot listen on %s: %s", addr, err)
!
259
                }
!
260
                listeners = append(listeners, listener)
72×
261
                proxy.normalisedAddrs = append(proxy.normalisedAddrs, normalisedAddr)
72×
262
        }
263

264
        if len(unixAddrs) > 0 {
76×
265
                listener, _, err := proxy.listen(weaveSockUnix)
2×
266
                if err != nil {
2×
UNCOV
267
                        Log.Fatalf("Cannot listen on %s: %s", weaveSockUnix, err)
!
268
                }
!
269
                listeners = append(listeners, listener)
2×
270

2×
271
                if err := proxy.symlink(unixAddrs); err != nil {
2×
UNCOV
272
                        Log.Fatalf("Cannot listen on unix sockets: %s", err)
!
273
                }
!
274

275
                proxy.normalisedAddrs = append(proxy.normalisedAddrs, weaveSockUnix)
2×
276
        }
277

278
        for _, addr := range proxy.normalisedAddrs {
148×
279
                Log.Infoln("proxy listening on", addr)
74×
280
        }
74×
281
        return listeners
74×
282
}
283

284
func (proxy *Proxy) Serve(listeners []net.Listener) {
74×
285
        errs := make(chan error)
74×
286
        for _, listener := range listeners {
148×
287
                go func(listener net.Listener) {
148×
288
                        errs <- (&http.Server{Handler: proxy}).Serve(listener)
74×
289
                }(listener)
74×
290
        }
291
        for range listeners {
148×
292
                err := <-errs
74×
293
                if err != nil {
74×
UNCOV
294
                        Log.Fatalf("Serve failed: %s", err)
!
295
                }
!
296
        }
297
}
298

299
func (proxy *Proxy) ListenAndServeStatus(socket string) {
74×
300
        listener, err := weavenet.ListenUnixSocket(socket)
74×
301
        if err != nil {
74×
UNCOV
302
                Log.Fatalf("ListenAndServeStatus failed: %s", err)
!
303
        }
!
304
        handler := http.HandlerFunc(proxy.StatusHTTP)
74×
305
        if err := (&http.Server{Handler: handler}).Serve(listener); err != nil {
74×
UNCOV
306
                Log.Fatalf("ListenAndServeStatus failed: %s", err)
!
307
        }
!
308
}
309

310
func (proxy *Proxy) StatusHTTP(w http.ResponseWriter, r *http.Request) {
149×
311
        for _, addr := range proxy.normalisedAddrs {
298×
312
                fmt.Fprintln(w, addr)
149×
313
        }
149×
314
}
315

316
func copyOwnerAndPermissions(from, to string) error {
2×
317
        stat, err := os.Stat(from)
2×
318
        if err != nil {
2×
UNCOV
319
                return err
!
320
        }
!
321
        if err = os.Chmod(to, stat.Mode()); err != nil {
2×
UNCOV
322
                return err
!
323
        }
!
324

325
        moreStat, ok := stat.Sys().(*syscall.Stat_t)
2×
326
        if !ok {
2×
UNCOV
327
                return nil
!
328
        }
!
329

330
        if err = os.Chown(to, int(moreStat.Uid), int(moreStat.Gid)); err != nil {
2×
UNCOV
331
                return err
!
332
        }
!
333

334
        return nil
2×
335
}
336

337
func (proxy *Proxy) listen(protoAndAddr string) (net.Listener, string, error) {
74×
338
        var (
74×
339
                listener    net.Listener
74×
340
                err         error
74×
341
                proto, addr string
74×
342
        )
74×
343

74×
344
        if protoAddrParts := strings.SplitN(protoAndAddr, "://", 2); len(protoAddrParts) == 2 {
148×
345
                proto, addr = protoAddrParts[0], protoAddrParts[1]
74×
346
        } else if strings.HasPrefix(protoAndAddr, "/") {
74×
UNCOV
347
                proto, addr = "unix", protoAndAddr
!
348
        } else {
!
349
                proto, addr = "tcp", protoAndAddr
!
350
        }
!
351

352
        switch proto {
74×
353
        case "tcp":
72×
354
                listener, err = net.Listen(proto, addr)
72×
355
                if err != nil {
72×
UNCOV
356
                        return nil, "", err
!
357
                }
!
358
                if proxy.TLSConfig.IsEnabled() {
73×
359
                        listener = tls.NewListener(listener, proxy.TLSConfig.Config)
1×
360
                }
1×
361

362
        case "unix":
2×
363
                // remove socket from last invocation
2×
364
                if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
2×
UNCOV
365
                        return nil, "", err
!
366
                }
!
367
                listener, err = net.Listen(proto, addr)
2×
368
                if err != nil {
2×
UNCOV
369
                        return nil, "", err
!
370
                }
!
371
                if strings.HasPrefix(proxy.Config.DockerHost, "unix://") {
4×
372
                        if err = copyOwnerAndPermissions(strings.TrimPrefix(proxy.Config.DockerHost, "unix://"), addr); err != nil {
2×
UNCOV
373
                                return nil, "", err
!
374
                        }
!
375
                }
376

UNCOV
377
        default:
!
378
                Log.Fatalf("Invalid protocol format: %q", proto)
!
379
        }
380

381
        return listener, fmt.Sprintf("%s://%s", proto, addr), nil
74×
382
}
383

384
// weavedocker.ContainerObserver interface
385
func (proxy *Proxy) ContainerStarted(ident string) {
841×
386
        err := proxy.attach(ident)
841×
387
        if err != nil {
843×
388
                var e error
2×
389
                // attach failed: if we have a request waiting on the start, kill the container,
2×
390
                // otherwise assume it is a Docker-initated restart and kill the process inside.
2×
391
                if proxy.waitChan(ident) != nil {
4×
392
                        e = proxy.client.KillContainer(docker.KillContainerOptions{ID: ident})
2×
393
                } else {
2×
UNCOV
394
                        var c *docker.Container
!
395
                        if c, e = proxy.client.InspectContainer(ident); e == nil {
!
396
                                var process *os.Process
!
397
                                if process, e = os.FindProcess(c.State.Pid); e == nil {
!
398
                                        e = process.Kill()
!
399
                                }
!
400
                        }
401
                }
402
                if e != nil {
2×
UNCOV
403
                        Log.Warningf("Error killing %s: %s", ident, e)
!
404
                }
!
405
        }
406
        proxy.notifyWaiters(ident, err)
841×
407
}
408

409
func containerShouldAttach(container *docker.Container) bool {
1,186×
410
        return len(container.Config.Entrypoint) > 0 && container.Config.Entrypoint[0] == weaveWaitEntrypoint[0]
1,186×
411
}
1,186×
412

413
func containerIsWeaveRouter(container *docker.Container) bool {
1,066×
414
        return container.Name == weaveContainerName &&
1,066×
415
                len(container.Config.Entrypoint) > 0 && container.Config.Entrypoint[0] == weaveEntrypoint
1,066×
416
}
1,066×
417

418
func (proxy *Proxy) createWait(r *http.Request, ident string) {
185×
419
        proxy.Lock()
185×
420
        proxy.waiters[r] = &wait{ident: ident, ch: make(chan error, 1)}
185×
421
        proxy.Unlock()
185×
422
}
185×
423

424
func (proxy *Proxy) removeWait(r *http.Request) {
185×
425
        proxy.Lock()
185×
426
        delete(proxy.waiters, r)
185×
427
        proxy.Unlock()
185×
428
}
185×
429

430
func (proxy *Proxy) notifyWaiters(ident string, err error) {
1,062×
431
        proxy.Lock()
1,062×
432
        if j, ok := proxy.attachJobs[ident]; ok {
1,283×
433
                j.Stop()
221×
434
                delete(proxy.attachJobs, ident)
221×
435
        }
221×
436
        for _, wait := range proxy.waiters {
1,324×
437
                if ident == wait.ident && !wait.done {
446×
438
                        wait.ch <- err
184×
439
                        close(wait.ch)
184×
440
                        wait.done = true
184×
441
                }
184×
442
        }
443
        proxy.Unlock()
1,062×
444
}
445

446
func (proxy *Proxy) waitForStart(r *http.Request) error {
184×
447
        var ch chan error
184×
448
        proxy.Lock()
184×
449
        wait, found := proxy.waiters[r]
184×
450
        if found {
368×
451
                ch = wait.ch
184×
452
        }
184×
453
        proxy.Unlock()
184×
454
        if ch != nil {
368×
455
                Log.Debugf("Wait for start of container %s", wait.ident)
184×
456
                return <-ch
184×
457
        }
184×
UNCOV
458
        return nil
!
459
}
460

461
func (proxy *Proxy) waitChan(ident string) chan error {
3×
462
        proxy.Lock()
3×
463
        defer proxy.Unlock()
3×
464
        for _, wait := range proxy.waiters {
5×
465
                if ident == wait.ident && !wait.done {
4×
466
                        return wait.ch
2×
467
                }
2×
468
        }
469
        return nil
1×
470
}
471

472
// If some other operation is waiting for a container to start, join in the wait
473
func (proxy *Proxy) waitForStartByIdent(ident string) error {
1×
474
        if ch := proxy.waitChan(ident); ch != nil {
1×
UNCOV
475
                Log.Debugf("Wait for start of container %s", ident)
!
476
                return <-ch
!
477
        }
!
478
        return nil
1×
479
}
480

481
func (proxy *Proxy) ContainerDied(ident string)      {}
817×
482
func (proxy *Proxy) ContainerDestroyed(ident string) {}
633×
483

484
// Check if this container needs to be attached, if so then attach it,
485
// and return nil on success or not needed.
486
func (proxy *Proxy) attach(containerID string) error {
1,066×
487
        container, err := proxy.client.InspectContainer(containerID)
1,066×
488
        if err != nil {
1,066×
UNCOV
489
                if _, ok := err.(*docker.NoSuchContainer); !ok {
!
490
                        Log.Warningf("unable to attach existing container %s since inspecting it failed: %v", containerID, err)
!
491
                }
!
492
                return nil
!
493
        }
494
        if containerIsWeaveRouter(container) {
1,131×
495
                Log.Infof("Attaching weave router container: %s", container.ID)
65×
496
                return callWeaveAttach(container, []string{"attach-router"})
65×
497
        }
65×
498
        if !containerShouldAttach(container) || !container.State.Running {
1,913×
499
                return nil
912×
500
        }
912×
501

502
        cidrs, err := proxy.weaveCIDRs(container.HostConfig.NetworkMode, container.Config.Env)
89×
503
        if err != nil {
94×
504
                Log.Infof("Leaving container %s alone because %s", containerID, err)
5×
505
                return nil
5×
506
        }
5×
507
        Log.Infof("Attaching container %s with WEAVE_CIDR \"%s\" to weave network", container.ID, strings.Join(cidrs, " "))
84×
508
        args := []string{"attach"}
84×
509
        args = append(args, cidrs...)
84×
510
        if !proxy.NoRewriteHosts {
167×
511
                args = append(args, "--rewrite-hosts")
83×
512

83×
513
                if container.HostConfig != nil {
166×
514
                        for _, eh := range container.HostConfig.ExtraHosts {
83×
UNCOV
515
                                args = append(args, fmt.Sprintf("--add-host=%s", eh))
!
UNCOV
516
                        }
!
517
                }
518
        }
519
        if proxy.NoMulticastRoute {
84×
UNCOV
520
                args = append(args, "--no-multicast-route")
!
UNCOV
521
        }
!
522
        args = append(args, container.ID)
84×
523
        return callWeaveAttach(container, args)
84×
524
}
525

526
func callWeaveAttach(container *docker.Container, args []string) error {
149×
527
        if _, stderr, err := callWeave(args...); err != nil {
155×
528
                Log.Warningf("Attaching container %s to weave network failed: %s", container.ID, string(stderr))
6×
529
                return errors.New(string(stderr))
6×
530
        } else if len(stderr) > 0 {
159×
531
                Log.Warningf("Attaching container %s to weave network: %s", container.ID, string(stderr))
10×
532
        }
10×
533
        return nil
143×
534
}
535

536
func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, error) {
254×
537
        if networkMode == "host" || strings.HasPrefix(networkMode, "container:") ||
254×
538
                // Anything else, other than blank/none/default/bridge, is some sort of network plugin
254×
539
                (networkMode != "" && networkMode != "none" && networkMode != "default" && networkMode != "bridge") {
274×
540
                return nil, fmt.Errorf("the container has '--net=%s'", networkMode)
20×
541
        }
20×
542
        for _, e := range env {
312×
543
                if strings.HasPrefix(e, "WEAVE_CIDR=") {
145×
544
                        if e[11:] == "none" {
69×
545
                                return nil, ErrWeaveCIDRNone
2×
546
                        }
2×
547
                        return strings.Fields(e[11:]), nil
65×
548
                }
549
        }
550
        if proxy.NoDefaultIPAM {
253×
551
                return nil, ErrNoDefaultIPAM
86×
552
        }
86×
553
        return nil, nil
81×
554
}
555

556
func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain string) error {
43×
557
        dns, err := hostConfig.StringArray("Dns")
43×
558
        if err != nil {
43×
UNCOV
559
                return err
!
UNCOV
560
        }
!
561
        hostConfig["Dns"] = append(dns, proxy.dockerBridgeIP)
43×
562

43×
563
        dnsSearch, err := hostConfig.StringArray("DnsSearch")
43×
564
        if err != nil {
43×
UNCOV
565
                return err
!
UNCOV
566
        }
!
567
        if len(dnsSearch) == 0 {
85×
568
                if hostname == "" {
46×
569
                        hostConfig["DnsSearch"] = []string{dnsDomain}
4×
570
                } else {
42×
571
                        hostConfig["DnsSearch"] = []string{"."}
38×
572
                }
38×
573
        }
574

575
        return nil
43×
576
}
577

578
func (proxy *Proxy) getDNSDomain() string {
55×
579
        if proxy.WithoutDNS {
55×
UNCOV
580
                return ""
!
581
        }
!
582
        weave := weaveapi.NewClient(os.Getenv("WEAVE_HTTP_ADDR"), Log)
55×
583
        domain, _ := weave.DNSDomain()
55×
584
        return domain
55×
585
}
586

587
func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
1×
588
        containerID, err := container.String("Id")
1×
589
        if err != nil {
1×
UNCOV
590
                return err
!
UNCOV
591
        }
!
592

593
        state, err := container.Object("State")
1×
594
        if err != nil {
1×
UNCOV
595
                return err
!
UNCOV
596
        }
!
597

598
        pid, err := state.Int("Pid")
1×
599
        if err != nil {
1×
UNCOV
600
                return err
!
UNCOV
601
        }
!
602

603
        if err := proxy.waitForStartByIdent(containerID); err != nil {
1×
UNCOV
604
                return err
!
UNCOV
605
        }
!
606
        netDevs, err := common.GetWeaveNetDevs(pid)
1×
607
        if err != nil || len(netDevs) == 0 || len(netDevs[0].CIDRs) == 0 {
1×
UNCOV
608
                return err
!
UNCOV
609
        }
!
610

611
        networkSettings, err := container.Object("NetworkSettings")
1×
612
        if err != nil {
1×
613
                return err
!
UNCOV
614
        }
!
615
        networkSettings["MacAddress"] = netDevs[0].MAC.String()
1×
616
        networkSettings["IPAddress"] = netDevs[0].CIDRs[0].IP.String()
1×
617
        networkSettings["IPPrefixLen"], _ = netDevs[0].CIDRs[0].Mask.Size()
1×
618
        return nil
1×
619
}
620

621
func (proxy *Proxy) symlink(unixAddrs []string) (err error) {
2×
622
        var container *docker.Container
2×
623
        binds := []string{"/var/run/weave:/var/run/weave"}
2×
624
        froms := []string{}
2×
625
        for _, addr := range unixAddrs {
4×
626
                from := strings.TrimPrefix(addr, "unix://")
2×
627
                if from == weaveSock {
4×
628
                        continue
2×
629
                }
630
                dir := filepath.Dir(from)
!
631
                binds = append(binds, dir+":"+filepath.Join("/host", dir))
!
UNCOV
632
                froms = append(froms, filepath.Join("/host", from))
!
UNCOV
633
                proxy.normalisedAddrs = append(proxy.normalisedAddrs, addr)
!
634
        }
635
        if len(froms) == 0 {
4×
636
                return
2×
637
        }
2×
638

UNCOV
639
        env := []string{
!
UNCOV
640
                "PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
!
UNCOV
641
        }
!
UNCOV
642

!
UNCOV
643
        if val := os.Getenv("WEAVE_DEBUG"); val != "" {
!
UNCOV
644
                env = append(env, fmt.Sprintf("%s=%s", "WEAVE_DEBUG", val))
!
UNCOV
645
        }
!
646

UNCOV
647
        container, err = proxy.client.CreateContainer(docker.CreateContainerOptions{
!
UNCOV
648
                Config: &docker.Config{
!
UNCOV
649
                        Image:      proxy.Image,
!
UNCOV
650
                        Entrypoint: []string{"/home/weave/symlink", weaveSock},
!
UNCOV
651
                        Cmd:        froms,
!
652
                        Env:        env,
!
653
                },
!
654
                HostConfig: &docker.HostConfig{Binds: binds},
!
655
        })
!
UNCOV
656
        if err != nil {
!
UNCOV
657
                return
!
UNCOV
658
        }
!
659

UNCOV
660
        defer func() {
!
661
                err2 := proxy.client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID})
!
662
                if err == nil {
!
663
                        err = err2
!
664
                }
!
665
        }()
666

667
        err = proxy.client.StartContainer(container.ID, nil)
!
UNCOV
668
        if err != nil {
!
669
                return
!
670
        }
!
671

672
        var buf bytes.Buffer
!
673
        err = proxy.client.AttachToContainer(docker.AttachToContainerOptions{
!
674
                Container:   container.ID,
!
675
                ErrorStream: &buf,
!
676
                Logs:        true,
!
677
                Stderr:      true,
!
678
        })
!
679
        if err != nil {
!
680
                return
!
UNCOV
681
        }
!
682

683
        var rc int
!
684
        rc, err = proxy.client.WaitContainer(container.ID)
!
685
        if err != nil {
!
686
                return
!
UNCOV
687
        }
!
UNCOV
688
        if rc != 0 {
!
689
                err = errors.New(buf.String())
!
690
        }
!
691
        return
!
692
}
693

694
func (proxy *Proxy) Stop() {
74×
695
        close(proxy.quit)
74×
696
        proxy.Lock()
74×
697
        defer proxy.Unlock()
74×
698
        for _, j := range proxy.attachJobs {
77×
699
                j.Stop()
3×
700
        }
3×
701
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc