Skip to content

Commit 27d6eb2

Browse files
committed
Add CSI NodeStage
1 parent dd25e3f commit 27d6eb2

File tree

897 files changed

+437579
-43
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

897 files changed

+437579
-43
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ _bin/
2222
/bin
2323
*.iml
2424
cover.out
25+
cover.out.tmp
2526
coverprofile*.out
2627
/amazon-ecs-init*
2728
/BUILDROOT/

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ GOFILES:=$(shell go list -f '{{$$p := .}}{{range $$f := .GoFiles}}{{$$p.Dir}}/{{
307307
.PHONY: gocyclo
308308
gocyclo:
309309
# Run gocyclo over all .go files
310-
gocyclo -over 17 ${GOFILES}
310+
gocyclo -over 40 ${GOFILES}
311311

312312
# same as gofiles above, but without the `-f`
313313
.PHONY: govet
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Build csi-driver from the minimal eks base to add required mount utils
2+
# TODO update Dockerfile with arch to build arm and windows
3+
4+
FROM public.ecr.aws/eks-distro-build-tooling/eks-distro-minimal-base-csi-ebs:latest.2 AS linux-amazon
5+
COPY csi-driver /bin/aws-ebs-csi-driver
6+
ENTRYPOINT ["/bin/aws-ebs-csi-driver"]
7+
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package driver
15+
16+
// constants of keys in VolumeContext
17+
const (
18+
// VolumeAttributePartition represents key for partition config in VolumeContext
19+
// this represents the partition number on a device used to mount
20+
VolumeAttributePartition = "partition"
21+
)
22+
23+
// constants for fstypes
24+
const (
25+
// FSTypeExt2 represents the ext2 filesystem type
26+
FSTypeExt2 = "ext2"
27+
// FSTypeExt3 represents the ext3 filesystem type
28+
FSTypeExt3 = "ext3"
29+
// FSTypeExt4 represents the ext4 filesystem type
30+
FSTypeExt4 = "ext4"
31+
// FSTypeXfs represents the xfs filesystem type
32+
FSTypeXfs = "xfs"
33+
// FSTypeNtfs represents the ntfs filesystem type
34+
FSTypeNtfs = "ntfs"
35+
)
36+
37+
// constants of disk partition suffix
38+
const (
39+
diskPartitionSuffix = ""
40+
nvmeDiskPartitionSuffix = "p"
41+
)
42+
43+
// constants of keys in volume parameters
44+
const (
45+
// BlockSizeKey configures the block size when formatting a volume
46+
BlockSizeKey = "blocksize"
47+
48+
// INodeSizeKey configures the inode size when formatting a volume
49+
INodeSizeKey = "inodesize"
50+
51+
// BytesPerINodeKey configures the `bytes-per-inode` when formatting a volume
52+
BytesPerINodeKey = "bytesperinode"
53+
54+
// NumberOfINodesKey configures the `number-of-inodes` when formatting a volume
55+
NumberOfINodesKey = "numberofinodes"
56+
)
57+
58+
type fileSystemConfig struct {
59+
NotSupportedParams map[string]struct{}
60+
}
61+
62+
// constants of keys in PublishContext
63+
const (
64+
// devicePathKey represents key for device path in PublishContext
65+
// devicePath is the device path where the volume is attached to
66+
DevicePathKey = "devicePath"
67+
)
68+
69+
var (
70+
FileSystemConfigs = map[string]fileSystemConfig{
71+
FSTypeExt2: {
72+
NotSupportedParams: map[string]struct{}{},
73+
},
74+
FSTypeExt3: {
75+
NotSupportedParams: map[string]struct{}{},
76+
},
77+
FSTypeExt4: {
78+
NotSupportedParams: map[string]struct{}{},
79+
},
80+
FSTypeXfs: {
81+
NotSupportedParams: map[string]struct{}{
82+
BytesPerINodeKey: {},
83+
NumberOfINodesKey: {},
84+
},
85+
},
86+
FSTypeNtfs: {
87+
NotSupportedParams: map[string]struct{}{
88+
BlockSizeKey: {},
89+
INodeSizeKey: {},
90+
BytesPerINodeKey: {},
91+
NumberOfINodesKey: {},
92+
},
93+
},
94+
}
95+
)
96+
97+
func (fsConfig fileSystemConfig) isParameterSupported(paramName string) bool {
98+
_, notSupported := fsConfig.NotSupportedParams[paramName]
99+
return !notSupported
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package driver
15+
16+
import (
17+
"strconv"
18+
19+
csi "github.com/container-storage-interface/spec/lib/go/csi"
20+
"k8s.io/klog/v2"
21+
)
22+
23+
var (
24+
// volumeCaps represents how the volume could be accessed.
25+
// It is SINGLE_NODE_WRITER since EBS volume could only be
26+
// attached to a single node at any given time.
27+
volumeCaps = []csi.VolumeCapability_AccessMode{
28+
{
29+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
30+
},
31+
}
32+
)
33+
34+
func isValidVolumeCapabilities(volCaps []*csi.VolumeCapability) bool {
35+
hasSupport := func(cap *csi.VolumeCapability) bool {
36+
for _, c := range volumeCaps {
37+
if c.GetMode() == cap.AccessMode.GetMode() {
38+
return true
39+
}
40+
}
41+
return false
42+
}
43+
44+
foundAll := true
45+
for _, c := range volCaps {
46+
if !hasSupport(c) {
47+
foundAll = false
48+
}
49+
}
50+
return foundAll
51+
}
52+
53+
func isValidVolumeContext(volContext map[string]string) bool {
54+
//There could be multiple volume attributes in the volumeContext map
55+
//Validate here case by case
56+
if partition, ok := volContext[VolumeAttributePartition]; ok {
57+
partitionInt, err := strconv.ParseInt(partition, 10, 64)
58+
if err != nil {
59+
klog.ErrorS(err, "failed to parse partition as int", "partition", partition)
60+
return false
61+
}
62+
if partitionInt < 0 {
63+
klog.ErrorS(err, "invalid partition config", "partition", partition)
64+
return false
65+
}
66+
}
67+
return true
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package internal
15+
16+
import (
17+
"sync"
18+
19+
"k8s.io/klog/v2"
20+
)
21+
22+
// Idempotent is the interface required to manage in flight requests.
23+
type Idempotent interface {
24+
// The CSI data types are generated using a protobuf.
25+
// The generated structures are guaranteed to implement the Stringer interface.
26+
// Example: https://github.com/container-storage-interface/spec/blob/master/lib/go/csi/csi.pb.go#L3508
27+
// We can use the generated string as the key of our internal inflight database of requests.
28+
String() string
29+
}
30+
31+
const (
32+
VolumeOperationAlreadyExistsErrorMsg = "An operation with the given Volume %s already exists"
33+
)
34+
35+
// InFlight is a struct used to manage in flight requests per volumeId.
36+
type InFlight struct {
37+
mux *sync.Mutex
38+
inFlight map[string]bool
39+
}
40+
41+
// NewInFlight instanciates a InFlight structures.
42+
func NewInFlight() *InFlight {
43+
return &InFlight{
44+
mux: &sync.Mutex{},
45+
inFlight: make(map[string]bool),
46+
}
47+
}
48+
49+
// Insert inserts the entry to the current list of inflight request key is volumeId for node and req hash for controller .
50+
// Returns false when the key already exists.
51+
func (db *InFlight) Insert(key string) bool {
52+
db.mux.Lock()
53+
defer db.mux.Unlock()
54+
55+
_, ok := db.inFlight[key]
56+
if ok {
57+
return false
58+
}
59+
60+
db.inFlight[key] = true
61+
return true
62+
}
63+
64+
// Delete removes the entry from the inFlight entries map.
65+
// It doesn't return anything, and will do nothing if the specified key doesn't exist.
66+
func (db *InFlight) Delete(key string) {
67+
db.mux.Lock()
68+
defer db.mux.Unlock()
69+
70+
delete(db.inFlight, key)
71+
klog.V(4).InfoS("Node Service: volume operation finished", "key", key)
72+
}

0 commit comments

Comments
 (0)