Skip to content

Commit

Permalink
Merge pull request #67 from pohly/inline-and-persistent-volumes
Browse files Browse the repository at this point in the history
Inline and persistent volumes
  • Loading branch information
k8s-ci-robot authored Jul 16, 2019
2 parents 46a3521 + 37803e6 commit d789c11
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 8 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ Follow the following example to create a volume from a volume snapshot:
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.
Find out how to enable or create a CSI inline driver [here](https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html)
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:
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:
```yaml
kind: DaemonSet
Expand All @@ -369,6 +369,9 @@ spec:
```
Notice the addition of the `ephemeral=true` flag used in the `args:` block in the previous snippet.
This is an intermediate solution for Kubernetes 1.15. Kubernetes 1.16 will provide [additional
information to the driver](https://github.com/kubernetes/kubernetes/pull/79983) which makes it
possible to use the normal deployment for both inline ephemeral volumes and persistent volumes.

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:

Expand Down
6 changes: 5 additions & 1 deletion cmd/hostpathplugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (
endpoint = flag.String("endpoint", "unix://tmp/csi.sock", "CSI endpoint")
driverName = flag.String("drivername", "hostpath.csi.k8s.io", "name of the driver")
nodeID = flag.String("nodeid", "", "node id")
ephemeral = flag.Bool("ephemeral", false, "deploy in ephemeral mode")
ephemeral = flag.Bool("ephemeral", false, "publish volumes in ephemeral mode even if kubelet did not ask for it (only needed for Kubernetes 1.15)")
showVersion = flag.Bool("version", false, "Show version.")
// Set by the build process
version = ""
Expand All @@ -48,6 +48,10 @@ func main() {
return
}

if *ephemeral {
fmt.Fprintln(os.Stderr, "Deprecation warning: The ephemeral flag is deprecated and should only be used when deploying on Kubernetes 1.15. It will be removed in the future.")
}

handle()
os.Exit(0)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/hostpath/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
}
}

vol, err := createHostpathVolume(volumeID, req.GetName(), capacity, requestedAccessType)
vol, err := createHostpathVolume(volumeID, req.GetName(), capacity, requestedAccessType, false /* ephemeral */)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create volume: %s", err))
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/hostpath/hostpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type hostPathVolume struct {
VolSize int64 `json:"volSize"`
VolPath string `json:"volPath"`
VolAccessType accessType `json:"volAccessType"`
Ephemeral bool `json:"ephemeral"`
}

type hostPathSnapshot struct {
Expand Down Expand Up @@ -148,7 +149,7 @@ func getVolumePath(volID string) string {

// createVolume create the directory for the hostpath volume.
// It returns the volume path or err if one occurs.
func createHostpathVolume(volID, name string, cap int64, volAccessType accessType) (*hostPathVolume, error) {
func createHostpathVolume(volID, name string, cap int64, volAccessType accessType, ephemeral bool) (*hostPathVolume, error) {
path := getVolumePath(volID)
if volAccessType == mountAccess {
err := os.MkdirAll(path, 0777)
Expand All @@ -163,6 +164,7 @@ func createHostpathVolume(volID, name string, cap int64, volAccessType accessTyp
VolSize: cap,
VolPath: path,
VolAccessType: volAccessType,
Ephemeral: ephemeral,
}
hostPathVolumes[volID] = hostpathVol
return &hostpathVol, nil
Expand Down
10 changes: 6 additions & 4 deletions pkg/hostpath/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,19 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
}

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

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

// if ephemeral is specified, create volume here to avoid errors
if ns.ephemeral {
if ephemeralVolume {
volID := req.GetVolumeId()
volName := fmt.Sprintf("ephemeral-%s", volID)
vol, err := createHostpathVolume(req.GetVolumeId(), volName, maxStorageCapacity, mountAccess)
vol, err := createHostpathVolume(req.GetVolumeId(), volName, maxStorageCapacity, mountAccess, ephemeralVolume)
if err != nil && !os.IsExist(err) {
glog.Error("ephemeral mode failed to create volume: ", err)
return nil, status.Error(codes.Internal, err.Error())
Expand Down Expand Up @@ -170,7 +172,7 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
if err := mounter.Mount(path, targetPath, "", options); err != nil {
var errList strings.Builder
errList.WriteString(err.Error())
if ns.ephemeral {
if vol.Ephemeral {
if rmErr := os.RemoveAll(path); rmErr != nil && !os.IsNotExist(rmErr) {
errList.WriteString(fmt.Sprintf(" :%s", rmErr.Error()))
}
Expand Down Expand Up @@ -218,7 +220,7 @@ func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
glog.V(4).Infof("hostpath: volume %s/%s has been unmounted.", targetPath, volumeID)
}

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

0 comments on commit d789c11

Please sign in to comment.