forked from docker/machine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
provisioner.go
132 lines (100 loc) · 3.69 KB
/
provisioner.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package provision
import (
"fmt"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/provision/pkgaction"
"github.com/docker/machine/libmachine/provision/serviceaction"
"github.com/docker/machine/libmachine/swarm"
)
var (
provisioners = make(map[string]*RegisteredProvisioner)
detector Detector = &StandardDetector{}
)
const (
LastReleaseBeforeCEVersioning = "1.13.1"
)
type SSHCommander interface {
// Short-hand for accessing an SSH command from the driver.
SSHCommand(args string) (string, error)
}
type Detector interface {
DetectProvisioner(d drivers.Driver) (Provisioner, error)
}
type StandardDetector struct{}
func SetDetector(newDetector Detector) {
detector = newDetector
}
// Provisioner defines distribution specific actions
type Provisioner interface {
fmt.Stringer
SSHCommander
// Create the files for the daemon to consume configuration settings (return struct of content and path)
GenerateDockerOptions(dockerPort int) (*DockerOptions, error)
// Get the directory where the settings files for docker are to be found
GetDockerOptionsDir() string
// Return the auth options used to configure remote connection for the daemon.
GetAuthOptions() auth.Options
// Get the swarm options associated with this host.
GetSwarmOptions() swarm.Options
// Run a package action e.g. install
Package(name string, action pkgaction.PackageAction) error
// Get Hostname
Hostname() (string, error)
// Set hostname
SetHostname(hostname string) error
// Figure out if this is the right provisioner to use based on /etc/os-release info
CompatibleWithHost() bool
// Do the actual provisioning piece:
// 1. Set the hostname on the instance.
// 2. Install Docker if it is not present.
// 3. Configure the daemon to accept connections over TLS.
// 4. Copy the needed certificates to the server and local config dir.
// 5. Configure / activate swarm if applicable.
Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error
// Perform action on a named service e.g. stop
Service(name string, action serviceaction.ServiceAction) error
// Get the driver which is contained in the provisioner.
GetDriver() drivers.Driver
// Set the OS Release info depending on how it's represented
// internally
SetOsReleaseInfo(info *OsRelease)
// Get the OS Release info for the current provisioner
GetOsReleaseInfo() (*OsRelease, error)
}
// RegisteredProvisioner creates a new provisioner
type RegisteredProvisioner struct {
New func(d drivers.Driver) Provisioner
}
func Register(name string, p *RegisteredProvisioner) {
provisioners[name] = p
}
func DetectProvisioner(d drivers.Driver) (Provisioner, error) {
return detector.DetectProvisioner(d)
}
func (detector StandardDetector) DetectProvisioner(d drivers.Driver) (Provisioner, error) {
log.Info("Waiting for SSH to be available...")
if err := drivers.WaitForSSH(d); err != nil {
return nil, err
}
log.Info("Detecting the provisioner...")
osReleaseOut, err := drivers.RunSSHCommandFromDriver(d, "cat /etc/os-release")
if err != nil {
return nil, fmt.Errorf("Error getting SSH command: %s", err)
}
osReleaseInfo, err := NewOsRelease([]byte(osReleaseOut))
if err != nil {
return nil, fmt.Errorf("Error parsing /etc/os-release file: %s", err)
}
for _, p := range provisioners {
provisioner := p.New(d)
provisioner.SetOsReleaseInfo(osReleaseInfo)
if provisioner.CompatibleWithHost() {
log.Debugf("found compatible host: %s", osReleaseInfo.ID)
return provisioner, nil
}
}
return nil, ErrDetectionFailed
}