This repository has been archived by the owner on Oct 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
git.go
103 lines (87 loc) · 2.34 KB
/
git.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package cali
import (
"crypto/md5"
"fmt"
"os"
log "github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
)
// GitCheckoutConfig is input for Git.Checkout
type GitCheckoutConfig struct {
Repo, Branch, RelPath, Image string
}
const gitImage = "indiehosters/git:latest"
// Git returns a new instance
func (c *DockerClient) Git() *Git {
return &Git{c: c, Image: gitImage}
}
// Git is used to interact with containerised git
type Git struct {
c *DockerClient
Image string
}
// GitCheckout will create and start a container, checkout repo and leave container stopped
// so volume can be imported
func (g *Git) Checkout(cfg *GitCheckoutConfig) (string, error) {
name := fmt.Sprintf("data_%x", md5.Sum([]byte(cfg.Repo+cfg.Branch)))
if g.c.ContainerExists(name) {
log.Infof("Existing data container found: %s", name)
if _, err := g.Pull(name); err != nil {
log.Warnf("Git pull error: %s", err)
return name, err
}
return name, nil
} else {
log.WithFields(log.Fields{
"git_url": cfg.Repo,
"image": g.Image,
}).Info("Creating data containers")
co := container.Config{
Cmd: []string{"clone", cfg.Repo, "-b", cfg.Branch, "--depth", "1", "."},
Image: gitImage,
Tty: true,
AttachStdout: true,
AttachStderr: true,
WorkingDir: "/tmp/workspace",
Entrypoint: []string{"git"},
}
hc := container.HostConfig{
Binds: []string{
"/tmp/workspace",
fmt.Sprintf("%s/.ssh:/root/.ssh", os.Getenv("HOME")),
},
}
nc := network.NetworkingConfig{}
g.c.SetConf(&co)
g.c.SetHostConf(&hc)
g.c.SetNetConf(&nc)
id, err := g.c.StartContainer(false, name)
if err != nil {
return "", fmt.Errorf("Failed to create data container for %s: %s", cfg.Repo, err)
}
return id, nil
}
}
func (g *Git) Pull(name string) (string, error) {
co := container.Config{
Cmd: []string{"pull"},
Image: g.Image,
Tty: true,
AttachStdout: true,
AttachStderr: true,
WorkingDir: "/tmp/workspace",
Entrypoint: []string{"git"},
}
hc := container.HostConfig{
VolumesFrom: []string{name},
Binds: []string{
fmt.Sprintf("%s/.ssh:/root/.ssh", os.Getenv("HOME")),
},
}
nc := network.NetworkingConfig{}
g.c.SetConf(&co)
g.c.SetHostConf(&hc)
g.c.SetNetConf(&nc)
return g.c.StartContainer(true, "")
}