Skip to content

Commit e48a722

Browse files
committed
per-volume ephemeral mode
This removes the limitation that the driver can only be deployed for one mode or the other. Instead the driver uses the new csi.storage.k8s.io/ephemeral field (kubernetes/kubernetes#79624) in the volume context to determine how it should behave in NodePublishVolume. Supporting both modes in the same deployment makes it possible to test ephemeral mode without having to change how the Prow jobs deploy the driver, which is once as part of the cluster setup. The --ephemeral parameter is still supported and can be used to force the driver into ephemeral mode, which is useful when deploying on Kubernetes 1.15 where csi.storage.k8s.io/ephemeral is not supported.
1 parent 46a3521 commit e48a722

File tree

5 files changed

+15
-8
lines changed

5 files changed

+15
-8
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ Follow the following example to create a volume from a volume snapshot:
346346
As of version 1.15 of Kubernetes, the CSI Hostpath driver (starting with version 1.0.1) now includes support for inline ephemeral volume. This means that a volume can be specified directly inside a pod spec without the need to use a persistent volume object.
347347
Find out how to enable or create a CSI inline driver [here](https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html)
348348
349-
To test this feature, redeploy the CSI Hostpath plugin YAML by updating the `hostpath` container to use the inline ephemeral mode by setting the `ephemeral` flag, of the driver binary, to true as shown in the following setup:
349+
To test this feature on Kubernetes 1.15, redeploy the CSI Hostpath plugin YAML by updating the `hostpath` container to use the inline ephemeral mode by setting the `ephemeral` flag, of the driver binary, to true as shown in the following setup:
350350
351351
```yaml
352352
kind: DaemonSet
@@ -369,6 +369,9 @@ spec:
369369
370370
```
371371
Notice the addition of the `ephemeral=true` flag used in the `args:` block in the previous snippet.
372+
This is an intermediate solution for Kubernetes 1.15. Kubernetes 1.16 will provide [additional
373+
information to the driver](https://github.com/kubernetes/kubernetes/pull/79983) which makes it
374+
possible to use the normal deployment for both inline ephemeral volumes and persistent volumes.
372375

373376
Once the driver plugin has been deployed, it can be tested by deploying a simple pod which has an inline volume specified in the spec:
374377

cmd/hostpathplugin/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var (
3333
endpoint = flag.String("endpoint", "unix://tmp/csi.sock", "CSI endpoint")
3434
driverName = flag.String("drivername", "hostpath.csi.k8s.io", "name of the driver")
3535
nodeID = flag.String("nodeid", "", "node id")
36-
ephemeral = flag.Bool("ephemeral", false, "deploy in ephemeral mode")
36+
ephemeral = flag.Bool("ephemeral", false, "publish volumes in ephemeral mode even if kubelet did not ask for it (only needed for Kubernetes 1.15)")
3737
showVersion = flag.Bool("version", false, "Show version.")
3838
// Set by the build process
3939
version = ""

pkg/hostpath/controllerserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
167167
}
168168
}
169169

170-
vol, err := createHostpathVolume(volumeID, req.GetName(), capacity, requestedAccessType)
170+
vol, err := createHostpathVolume(volumeID, req.GetName(), capacity, requestedAccessType, false /* ephemeral */)
171171
if err != nil {
172172
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create volume: %s", err))
173173
}

pkg/hostpath/hostpath.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type hostPathVolume struct {
5353
VolSize int64 `json:"volSize"`
5454
VolPath string `json:"volPath"`
5555
VolAccessType accessType `json:"volAccessType"`
56+
Ephemeral bool `json:"ephemeral"`
5657
}
5758

5859
type hostPathSnapshot struct {
@@ -148,7 +149,7 @@ func getVolumePath(volID string) string {
148149

149150
// createVolume create the directory for the hostpath volume.
150151
// It returns the volume path or err if one occurs.
151-
func createHostpathVolume(volID, name string, cap int64, volAccessType accessType) (*hostPathVolume, error) {
152+
func createHostpathVolume(volID, name string, cap int64, volAccessType accessType, ephemeral bool) (*hostPathVolume, error) {
152153
path := getVolumePath(volID)
153154
if volAccessType == mountAccess {
154155
err := os.MkdirAll(path, 0777)
@@ -163,6 +164,7 @@ func createHostpathVolume(volID, name string, cap int64, volAccessType accessTyp
163164
VolSize: cap,
164165
VolPath: path,
165166
VolAccessType: volAccessType,
167+
Ephemeral: ephemeral,
166168
}
167169
hostPathVolumes[volID] = hostpathVol
168170
return &hostpathVol, nil

pkg/hostpath/nodeserver.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,19 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
5757
}
5858

5959
targetPath := req.GetTargetPath()
60+
ephemeralVolume := req.GetVolumeContext()["csi.storage.k8s.io/ephemeral"] == "true" ||
61+
req.GetVolumeContext()["csi.storage.k8s.io/ephemeral"] == "" && ns.ephemeral // Kubernetes 1.15 doesn't have csi.storage.k8s.io/ephemeral.
6062

6163
if req.GetVolumeCapability().GetBlock() != nil &&
6264
req.GetVolumeCapability().GetMount() != nil {
6365
return nil, status.Error(codes.InvalidArgument, "cannot have both block and mount access type")
6466
}
6567

6668
// if ephemeral is specified, create volume here to avoid errors
67-
if ns.ephemeral {
69+
if ephemeralVolume {
6870
volID := req.GetVolumeId()
6971
volName := fmt.Sprintf("ephemeral-%s", volID)
70-
vol, err := createHostpathVolume(req.GetVolumeId(), volName, maxStorageCapacity, mountAccess)
72+
vol, err := createHostpathVolume(req.GetVolumeId(), volName, maxStorageCapacity, mountAccess, ephemeralVolume)
7173
if err != nil && !os.IsExist(err) {
7274
glog.Error("ephemeral mode failed to create volume: ", err)
7375
return nil, status.Error(codes.Internal, err.Error())
@@ -170,7 +172,7 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
170172
if err := mounter.Mount(path, targetPath, "", options); err != nil {
171173
var errList strings.Builder
172174
errList.WriteString(err.Error())
173-
if ns.ephemeral {
175+
if vol.Ephemeral {
174176
if rmErr := os.RemoveAll(path); rmErr != nil && !os.IsNotExist(rmErr) {
175177
errList.WriteString(fmt.Sprintf(" :%s", rmErr.Error()))
176178
}
@@ -218,7 +220,7 @@ func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
218220
glog.V(4).Infof("hostpath: volume %s/%s has been unmounted.", targetPath, volumeID)
219221
}
220222

221-
if ns.ephemeral {
223+
if vol.Ephemeral {
222224
glog.V(4).Infof("deleting volume %s", volumeID)
223225
if err := deleteHostpathVolume(volumeID); err != nil && !os.IsNotExist(err) {
224226
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to delete volume: %s", err))

0 commit comments

Comments
 (0)