@@ -4,34 +4,29 @@ import (
4
4
"errors"
5
5
"fmt"
6
6
"net"
7
- "net/url"
8
7
"os"
9
8
"path/filepath"
10
9
"time"
11
10
12
- dockerclient "github.com/fsouza/go-dockerclient"
13
11
"github.com/golang/glog"
14
12
15
13
kapiv1 "k8s.io/api/core/v1"
16
14
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17
15
kclientsetexternal "k8s.io/client-go/kubernetes"
18
- "k8s.io/kubernetes/pkg/kubelet/dockershim"
19
- dockertools "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker"
20
- "k8s.io/kubernetes/pkg/util/mount"
16
+ "k8s.io/kubernetes/cmd/kubelet/app"
21
17
"k8s.io/kubernetes/pkg/volume"
22
18
23
19
configapi "github.com/openshift/origin/pkg/cmd/server/api"
24
20
cmdutil "github.com/openshift/origin/pkg/cmd/util"
25
- dockerutil "github.com/openshift/origin/pkg/cmd/util/docker"
26
21
"github.com/openshift/origin/pkg/volume/emptydir"
27
22
)
28
23
29
- const minimumDockerAPIVersionWithPullByID = "1.22"
30
-
24
+ // TODO this is a best effort check at the moment that should either move to kubelet or be removed entirely
31
25
// EnsureKubeletAccess performs a number of test operations that the Kubelet requires to properly function.
32
26
// All errors here are fatal.
33
- func (c * NodeConfig ) EnsureKubeletAccess () {
34
- if c .Containerized {
27
+ func EnsureKubeletAccess () {
28
+ containerized := cmdutil .Env ("OPENSHIFT_CONTAINERIZED" , "" ) == "true"
29
+ if containerized {
35
30
if _ , err := os .Stat ("/rootfs" ); os .IsPermission (err ) || os .IsNotExist (err ) {
36
31
glog .Fatal ("error: Running in containerized mode, but cannot find the /rootfs directory - be sure to mount the host filesystem at /rootfs (read-only) in the container." )
37
32
}
@@ -71,156 +66,83 @@ func sameFileStat(requireMode bool, src, dst string) bool {
71
66
return true
72
67
}
73
68
74
- // EnsureDocker attempts to connect to the Docker daemon defined by the helper,
75
- // and if it is unable to it will print a warning.
76
- func (c * NodeConfig ) EnsureDocker (docker * dockerutil.Helper ) {
77
- if c .KubeletServer .ContainerRuntime != "docker" {
78
- return
79
- }
80
- if _ , err := os .Stat ("/var/lib/docker" ); os .IsPermission (err ) {
81
- glog .Fatal ("Unable to view the /var/lib/docker directory - are you running as root?" )
82
- }
83
-
84
- var endpoint string
85
- if len (os .Getenv ("DOCKER_HOST" )) > 0 {
86
- endpoint = os .Getenv ("DOCKER_HOST" )
87
- } else {
88
- endpoint = "unix:///var/run/docker.sock"
89
- }
90
-
91
- dockerClientConfig := & dockershim.ClientConfig {
92
- DockerEndpoint : endpoint ,
93
- RuntimeRequestTimeout : c .KubeletServer .RuntimeRequestTimeout .Duration ,
94
- ImagePullProgressDeadline : c .KubeletServer .ImagePullProgressDeadline .Duration ,
95
- }
96
- client := dockertools .ConnectToDockerOrDie (endpoint , c .KubeletServer .RuntimeRequestTimeout .Duration , c .KubeletServer .ImagePullProgressDeadline .Duration , false , false )
97
- dockerClient := & dockerutil.KubeDocker {Interface : client }
98
-
99
- if url , err := url .Parse (endpoint ); err == nil && url .Scheme == "unix" && len (url .Path ) > 0 {
100
- s , err := os .Stat (url .Path )
101
- switch {
102
- case os .IsNotExist (err ):
103
- glog .Fatalf ("No Docker socket found at %s. Have you started the Docker daemon?" , url .Path )
104
- return
105
- case os .IsPermission (err ):
106
- glog .Fatalf ("You do not have permission to connect to the Docker daemon (via %s). This process requires running as the root user." , url .Path )
107
- return
108
- case err == nil && s .IsDir ():
109
- glog .Fatalf ("The Docker socket at %s is a directory instead of a unix socket - check that you have configured your connection to the Docker daemon properly." , url .Path )
110
- return
111
- }
112
- }
113
- _ , isFakeDocker := client .(* dockertools.FakeDockerClient )
114
- if isFakeDocker {
115
- // If using the fake docker client, ensure that the CgroupDriver for the kubelet matches
116
- // the default cgroup driver, and use a fake mounter
117
- c .KubeletServer .CgroupDriver = "cgroupfs"
118
- c .KubeletDeps .Mounter = & mount.FakeMounter {}
119
- }
120
-
121
- if ! isFakeDocker {
122
- if err := dockerClient .Ping (); err != nil {
123
- glog .Fatalf ("Docker could not be reached at %s. Docker must be installed and running to start containers.\n %v" , endpoint , err )
124
- return
125
- }
126
- }
127
-
128
- glog .Infof ("Connecting to Docker at %s" , endpoint )
129
-
130
- version , err := dockerClient .Version ()
131
- if err != nil {
132
- glog .Fatalf ("Unable to check for Docker server version.\n %v" , err )
133
- return
134
- }
135
-
136
- serverVersion , err := dockerclient .NewAPIVersion (version .APIVersion )
137
- if err != nil {
138
- glog .Fatalf ("Unable to determine Docker server version from %q.\n %v" , version .APIVersion , err )
139
- return
140
- }
141
-
142
- minimumPullByIDVersion , err := dockerclient .NewAPIVersion (minimumDockerAPIVersionWithPullByID )
143
- if err != nil {
144
- glog .Fatalf ("Unable to check for Docker server version.\n %v" , err )
145
- return
146
- }
147
-
148
- if serverVersion .LessThan (minimumPullByIDVersion ) {
149
- glog .Fatalf ("Docker 1.6 or later (server API version %s or later) required." , minimumDockerAPIVersionWithPullByID )
150
- return
151
- }
152
-
153
- c .DockerClientConfig = dockerClientConfig
154
- }
155
-
69
+ // TODO we need to stop doing this or get it upstream
156
70
// EnsureVolumeDir attempts to convert the provided volume directory argument to
157
71
// an absolute path and create the directory if it does not exist. Will exit if
158
72
// an error is encountered.
159
- func ( c * NodeConfig ) EnsureVolumeDir () {
160
- if volumeDir , err := c . initializeVolumeDir (c . VolumeDir ); err != nil {
73
+ func EnsureVolumeDir (volumeDirName string ) {
74
+ if err := initializeVolumeDir (volumeDirName ); err != nil {
161
75
glog .Fatal (err )
162
- } else {
163
- c .VolumeDir = volumeDir
164
76
}
165
77
}
166
78
167
- func (c * NodeConfig ) initializeVolumeDir (path string ) (string , error ) {
168
- rootDirectory , err := filepath .Abs (path )
169
- if err != nil {
170
- return "" , fmt .Errorf ("Error converting volume directory to an absolute path: %v" , err )
79
+ func initializeVolumeDir (rootDirectory string ) error {
80
+ if ! filepath .IsAbs (rootDirectory ) {
81
+ return fmt .Errorf ("%q is not an absolute path" , rootDirectory )
171
82
}
172
83
173
84
if _ , err := os .Stat (rootDirectory ); os .IsNotExist (err ) {
174
85
if err := os .MkdirAll (rootDirectory , 0750 ); err != nil {
175
- return "" , fmt .Errorf ("Couldn't create kubelet volume root directory '%s': %s" , rootDirectory , err )
86
+ return fmt .Errorf ("Couldn't create kubelet volume root directory '%s': %s" , rootDirectory , err )
176
87
}
177
88
}
178
- return rootDirectory , nil
89
+ return nil
179
90
}
180
91
181
- // EnsureLocalQuota checks if the node config specifies a local storage
92
+ // TODO this needs to move into the forked kubelet with a `--openshift-config` flag
93
+ // PatchUpstreamVolumePluginsForLocalQuota checks if the node config specifies a local storage
182
94
// perFSGroup quota, and if so will test that the volumeDirectory is on a
183
95
// filesystem suitable for quota enforcement. If checks pass the k8s emptyDir
184
96
// volume plugin will be replaced with a wrapper version which adds quota
185
97
// functionality.
186
- func (c * NodeConfig ) EnsureLocalQuota (nodeConfig configapi.NodeConfig ) {
187
- if nodeConfig .VolumeConfig .LocalQuota .PerFSGroup == nil {
188
- return
189
- }
190
- glog .V (4 ).Info ("Replacing empty-dir volume plugin with quota wrapper" )
191
- wrappedEmptyDirPlugin := false
98
+ func PatchUpstreamVolumePluginsForLocalQuota (nodeConfig configapi.NodeConfig ) func () []volume.VolumePlugin {
99
+ // This looks a little weird written this way but it allows straight lifting from here to kube at a future time
100
+ // and will allow us to wrap the exec.
192
101
193
- quotaApplicator , err := emptydir .NewQuotaApplicator (nodeConfig .VolumeDirectory )
194
- if err != nil {
195
- glog .Fatalf ("Could not set up local quota, %s" , err )
196
- }
102
+ existingProbeVolumePlugins := app .ProbeVolumePlugins
103
+ return func () []volume.VolumePlugin {
104
+ if nodeConfig .VolumeConfig .LocalQuota .PerFSGroup == nil {
105
+ return existingProbeVolumePlugins ()
106
+ }
107
+
108
+ glog .V (4 ).Info ("Replacing empty-dir volume plugin with quota wrapper" )
109
+ wrappedEmptyDirPlugin := false
197
110
198
- // Create a volume spec with emptyDir we can use to search for the
199
- // emptyDir plugin with CanSupport:
200
- emptyDirSpec := & volume.Spec {
201
- Volume : & kapiv1.Volume {
202
- VolumeSource : kapiv1.VolumeSource {
203
- EmptyDir : & kapiv1.EmptyDirVolumeSource {},
111
+ quotaApplicator , err := emptydir .NewQuotaApplicator (nodeConfig .VolumeDirectory )
112
+ if err != nil {
113
+ glog .Fatalf ("Could not set up local quota, %s" , err )
114
+ }
115
+
116
+ // Create a volume spec with emptyDir we can use to search for the
117
+ // emptyDir plugin with CanSupport:
118
+ emptyDirSpec := & volume.Spec {
119
+ Volume : & kapiv1.Volume {
120
+ VolumeSource : kapiv1.VolumeSource {
121
+ EmptyDir : & kapiv1.EmptyDirVolumeSource {},
122
+ },
204
123
},
205
- },
206
- }
124
+ }
207
125
208
- for idx , plugin := range c .KubeletDeps .VolumePlugins {
209
- // Can't really do type checking or use a constant here as they are not exported:
210
- if plugin .CanSupport (emptyDirSpec ) {
211
- wrapper := emptydir.EmptyDirQuotaPlugin {
212
- VolumePlugin : plugin ,
213
- Quota : * nodeConfig .VolumeConfig .LocalQuota .PerFSGroup ,
214
- QuotaApplicator : quotaApplicator ,
126
+ ret := existingProbeVolumePlugins ()
127
+ for idx , plugin := range ret {
128
+ // Can't really do type checking or use a constant here as they are not exported:
129
+ if plugin .CanSupport (emptyDirSpec ) {
130
+ wrapper := emptydir.EmptyDirQuotaPlugin {
131
+ VolumePlugin : plugin ,
132
+ Quota : * nodeConfig .VolumeConfig .LocalQuota .PerFSGroup ,
133
+ QuotaApplicator : quotaApplicator ,
134
+ }
135
+ ret [idx ] = & wrapper
136
+ wrappedEmptyDirPlugin = true
215
137
}
216
- c .KubeletDeps .VolumePlugins [idx ] = & wrapper
217
- wrappedEmptyDirPlugin = true
218
138
}
219
- }
220
- // Because we can't look for the k8s emptyDir plugin by any means that would
221
- // survive a refactor, error out if we couldn't find it:
222
- if ! wrappedEmptyDirPlugin {
223
- glog .Fatal (errors .New ("No plugin handling EmptyDir was found, unable to apply local quotas" ))
139
+ // Because we can't look for the k8s emptyDir plugin by any means that would
140
+ // survive a refactor, error out if we couldn't find it:
141
+ if ! wrappedEmptyDirPlugin {
142
+ glog .Fatal (errors .New ("No plugin handling EmptyDir was found, unable to apply local quotas" ))
143
+ }
144
+
145
+ return ret
224
146
}
225
147
}
226
148
0 commit comments