... | ... |
@@ -7,6 +7,7 @@ import ( |
7 | 7 |
"io" |
8 | 8 |
"net" |
9 | 9 |
"net/url" |
10 |
+ "regexp" |
|
10 | 11 |
"strconv" |
11 | 12 |
"time" |
12 | 13 |
|
... | ... |
@@ -76,26 +77,36 @@ func (h *Helper) HasInsecureRegistryArg() (bool, error) { |
76 | 76 |
return hasCIDR(openShiftInsecureCIDR, registryConfig.InsecureRegistryCIDRs), nil |
77 | 77 |
} |
78 | 78 |
|
79 |
-// Version returns the Docker version |
|
80 |
-func (h *Helper) Version() (*semver.Version, error) { |
|
79 |
+var ( |
|
80 |
+ fedoraPackage = regexp.MustCompile("\\.fc[0-9_]*\\.") |
|
81 |
+ rhelPackage = regexp.MustCompile("\\.el[0-9_]*\\.") |
|
82 |
+) |
|
83 |
+ |
|
84 |
+// Version returns the Docker version and whether it is a Red Hat distro version |
|
85 |
+func (h *Helper) Version() (*semver.Version, bool, error) { |
|
81 | 86 |
glog.V(5).Infof("Retrieving Docker version") |
82 | 87 |
env, err := h.client.Version() |
83 | 88 |
if err != nil { |
84 | 89 |
glog.V(2).Infof("Error retrieving version: %v", err) |
85 |
- return nil, err |
|
90 |
+ return nil, false, err |
|
86 | 91 |
} |
87 | 92 |
glog.V(5).Infof("Docker version results: %#v", env) |
88 | 93 |
versionStr := env.Get("Version") |
89 | 94 |
if len(versionStr) == 0 { |
90 |
- return nil, errors.New("did not get a version") |
|
95 |
+ return nil, false, errors.New("did not get a version") |
|
91 | 96 |
} |
92 | 97 |
glog.V(5).Infof("Version: %s", versionStr) |
93 | 98 |
dockerVersion, err := semver.Parse(versionStr) |
94 | 99 |
if err != nil { |
95 | 100 |
glog.V(2).Infof("Error parsing Docker version %q", versionStr) |
96 |
- return nil, err |
|
101 |
+ return nil, false, err |
|
102 |
+ } |
|
103 |
+ isRedHat := false |
|
104 |
+ packageVersion := env.Get("PkgVersion") |
|
105 |
+ if len(packageVersion) > 0 { |
|
106 |
+ isRedHat = fedoraPackage.MatchString(packageVersion) || rhelPackage.MatchString(packageVersion) |
|
97 | 107 |
} |
98 |
- return &dockerVersion, nil |
|
108 |
+ return &dockerVersion, isRedHat, nil |
|
99 | 109 |
} |
100 | 110 |
|
101 | 111 |
// CheckAndPull checks whether a Docker image exists. If not, it pulls it. |
... | ... |
@@ -7,7 +7,6 @@ import ( |
7 | 7 |
"os" |
8 | 8 |
"path" |
9 | 9 |
"path/filepath" |
10 |
- "runtime" |
|
11 | 10 |
"strings" |
12 | 11 |
|
13 | 12 |
docker "github.com/fsouza/go-dockerclient" |
... | ... |
@@ -55,12 +54,6 @@ func NewHostHelper(client *docker.Client, image, volumesDir, configDir, dataDir |
55 | 55 |
|
56 | 56 |
// CanUseNsenterMounter returns true if the Docker host machine can execute findmnt through nsenter |
57 | 57 |
func (h *HostHelper) CanUseNsenterMounter() (bool, error) { |
58 |
- // For now, use a shared mount on Windows/Mac |
|
59 |
- // Eventually it also needs to be used on Linux, but nsenter |
|
60 |
- // is still needed for Docker 1.9 |
|
61 |
- if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { |
|
62 |
- return false, nil |
|
63 |
- } |
|
64 | 58 |
rc, err := h.runner(). |
65 | 59 |
Image(h.image). |
66 | 60 |
DiscardContainer(). |
... | ... |
@@ -62,18 +62,19 @@ type Helper struct { |
62 | 62 |
|
63 | 63 |
// StartOptions represent the parameters sent to the start command |
64 | 64 |
type StartOptions struct { |
65 |
- ServerIP string |
|
66 |
- DNSPort int |
|
67 |
- UseSharedVolume bool |
|
68 |
- Images string |
|
69 |
- HostVolumesDir string |
|
70 |
- HostConfigDir string |
|
71 |
- HostDataDir string |
|
72 |
- UseExistingConfig bool |
|
73 |
- Environment []string |
|
74 |
- LogLevel int |
|
75 |
- MetricsHost string |
|
76 |
- PortForwarding bool |
|
65 |
+ ServerIP string |
|
66 |
+ DNSPort int |
|
67 |
+ UseSharedVolume bool |
|
68 |
+ SetPropagationMode bool |
|
69 |
+ Images string |
|
70 |
+ HostVolumesDir string |
|
71 |
+ HostConfigDir string |
|
72 |
+ HostDataDir string |
|
73 |
+ UseExistingConfig bool |
|
74 |
+ Environment []string |
|
75 |
+ LogLevel int |
|
76 |
+ MetricsHost string |
|
77 |
+ PortForwarding bool |
|
77 | 78 |
} |
78 | 79 |
|
79 | 80 |
// NewHelper creates a new OpenShift helper |
... | ... |
@@ -218,7 +219,11 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { |
218 | 218 |
env = append(env, "OPENSHIFT_CONTAINERIZED=false") |
219 | 219 |
} else { |
220 | 220 |
binds = append(binds, "/:/rootfs:ro") |
221 |
- binds = append(binds, fmt.Sprintf("%[1]s:%[1]s", opt.HostVolumesDir)) |
|
221 |
+ propagationMode := "" |
|
222 |
+ if opt.SetPropagationMode { |
|
223 |
+ propagationMode = ":rslave" |
|
224 |
+ } |
|
225 |
+ binds = append(binds, fmt.Sprintf("%[1]s:%[1]s%[2]s", opt.HostVolumesDir, propagationMode)) |
|
222 | 226 |
} |
223 | 227 |
env = append(env, opt.Environment...) |
224 | 228 |
binds = append(binds, fmt.Sprintf("%s:/var/lib/origin/openshift.local.config:z", opt.HostConfigDir)) |
... | ... |
@@ -100,6 +100,8 @@ var ( |
100 | 100 |
"jenkins pipeline persistent": "examples/jenkins/jenkins-persistent-template.json", |
101 | 101 |
"sample pipeline": "examples/jenkins/pipeline/samplepipeline.json", |
102 | 102 |
} |
103 |
+ dockerVersion19 = semver.MustParse("1.9.0") |
|
104 |
+ dockerVersion110 = semver.MustParse("1.10.0") |
|
103 | 105 |
) |
104 | 106 |
|
105 | 107 |
// NewCmdUp creates a command that starts openshift on Docker with reasonable defaults |
... | ... |
@@ -158,16 +160,17 @@ type ClientStartConfig struct { |
158 | 158 |
ShouldInstallMetrics bool |
159 | 159 |
PortForwarding bool |
160 | 160 |
|
161 |
- UseNsenterMount bool |
|
162 |
- Out io.Writer |
|
163 |
- TaskPrinter *TaskPrinter |
|
164 |
- Tasks []task |
|
165 |
- HostName string |
|
166 |
- ServerIP string |
|
167 |
- CACert string |
|
168 |
- PublicHostname string |
|
169 |
- RoutingSuffix string |
|
170 |
- DNSPort int |
|
161 |
+ UseNsenterMount bool |
|
162 |
+ SetPropagationMode bool |
|
163 |
+ Out io.Writer |
|
164 |
+ TaskPrinter *TaskPrinter |
|
165 |
+ Tasks []task |
|
166 |
+ HostName string |
|
167 |
+ ServerIP string |
|
168 |
+ CACert string |
|
169 |
+ PublicHostname string |
|
170 |
+ RoutingSuffix string |
|
171 |
+ DNSPort int |
|
171 | 172 |
|
172 | 173 |
LocalConfigDir string |
173 | 174 |
HostVolumesDir string |
... | ... |
@@ -216,6 +219,9 @@ func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) |
216 | 216 |
// running. Otherwise, use environment variables. |
217 | 217 |
c.addTask("Checking Docker client", c.GetDockerClient) |
218 | 218 |
|
219 |
+ // Check that we have the minimum Docker version available to run OpenShift |
|
220 |
+ c.addTask("Checking Docker version", c.CheckDockerVersion) |
|
221 |
+ |
|
219 | 222 |
// Check for an OpenShift container. If one exists and is running, exit. |
220 | 223 |
// If one exists but not running, delete it. |
221 | 224 |
c.addTask("Checking for existing OpenShift container", c.CheckExistingOpenShiftContainer) |
... | ... |
@@ -237,9 +243,6 @@ func (c *ClientStartConfig) Complete(f *osclientcmd.Factory, cmd *cobra.Command) |
237 | 237 |
// If not, use a shared volume to mount volumes on OpenShift |
238 | 238 |
c.addTask("Checking type of volume mount", c.CheckNsenterMounter) |
239 | 239 |
|
240 |
- // Check that we have the minimum Docker version available to run OpenShift |
|
241 |
- c.addTask("Checking Docker version", c.CheckDockerVersion) |
|
242 |
- |
|
243 | 240 |
// Ensure that host directories exist. |
244 | 241 |
// If not using the nsenter mounter, create a volume share on the host machine to |
245 | 242 |
// mount OpenShift volumes. |
... | ... |
@@ -479,20 +482,19 @@ func (c *ClientStartConfig) CheckNsenterMounter(out io.Writer) error { |
479 | 479 |
// CheckDockerVersion checks that the appropriate Docker version is installed based on whether we are using the nsenter mounter |
480 | 480 |
// or shared volumes for OpenShift |
481 | 481 |
func (c *ClientStartConfig) CheckDockerVersion(io.Writer) error { |
482 |
- var minDockerVersion semver.Version |
|
483 |
- if c.UseNsenterMount { |
|
484 |
- minDockerVersion = semver.MustParse("1.8.1") |
|
485 |
- } else { |
|
486 |
- minDockerVersion = semver.MustParse("1.10.0") |
|
487 |
- } |
|
488 |
- ver, err := c.DockerHelper().Version() |
|
482 |
+ ver, rh, err := c.DockerHelper().Version() |
|
489 | 483 |
if err != nil { |
490 | 484 |
return err |
491 | 485 |
} |
492 |
- glog.V(5).Infof("Checking that docker version is at least %v", minDockerVersion) |
|
493 |
- if ver.LT(minDockerVersion) { |
|
494 |
- return fmt.Errorf("Docker version is %v, it needs to be %v", ver, minDockerVersion) |
|
486 |
+ needVersion := dockerVersion19 |
|
487 |
+ if !rh { |
|
488 |
+ needVersion = dockerVersion110 |
|
489 |
+ } |
|
490 |
+ glog.V(5).Infof("Checking that docker version is at least %v", needVersion) |
|
491 |
+ if ver.LT(needVersion) { |
|
492 |
+ return fmt.Errorf("Docker version is %v, it needs to be %v", ver, needVersion) |
|
495 | 493 |
} |
494 |
+ c.SetPropagationMode = ver.GTE(dockerVersion110) |
|
496 | 495 |
return nil |
497 | 496 |
} |
498 | 497 |
|
... | ... |
@@ -546,17 +548,18 @@ func (c *ClientStartConfig) DetermineServerIP(out io.Writer) error { |
546 | 546 |
func (c *ClientStartConfig) StartOpenShift(out io.Writer) error { |
547 | 547 |
var err error |
548 | 548 |
opt := &openshift.StartOptions{ |
549 |
- ServerIP: c.ServerIP, |
|
550 |
- UseSharedVolume: !c.UseNsenterMount, |
|
551 |
- Images: c.imageFormat(), |
|
552 |
- HostVolumesDir: c.HostVolumesDir, |
|
553 |
- HostConfigDir: c.HostConfigDir, |
|
554 |
- HostDataDir: c.HostDataDir, |
|
555 |
- UseExistingConfig: c.UseExistingConfig, |
|
556 |
- Environment: c.Environment, |
|
557 |
- LogLevel: c.ServerLogLevel, |
|
558 |
- DNSPort: c.DNSPort, |
|
559 |
- PortForwarding: c.PortForwarding, |
|
549 |
+ ServerIP: c.ServerIP, |
|
550 |
+ UseSharedVolume: !c.UseNsenterMount, |
|
551 |
+ SetPropagationMode: c.SetPropagationMode, |
|
552 |
+ Images: c.imageFormat(), |
|
553 |
+ HostVolumesDir: c.HostVolumesDir, |
|
554 |
+ HostConfigDir: c.HostConfigDir, |
|
555 |
+ HostDataDir: c.HostDataDir, |
|
556 |
+ UseExistingConfig: c.UseExistingConfig, |
|
557 |
+ Environment: c.Environment, |
|
558 |
+ LogLevel: c.ServerLogLevel, |
|
559 |
+ DNSPort: c.DNSPort, |
|
560 |
+ PortForwarding: c.PortForwarding, |
|
560 | 561 |
} |
561 | 562 |
if c.ShouldInstallMetrics { |
562 | 563 |
opt.MetricsHost = openshift.MetricsHost(c.RoutingSuffix, c.ServerIP) |