github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/select/blockdevice/select.go (about) 1 /* 2 Copyright 2019 The OpenEBS Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package blockdevice 18 19 import ( 20 "fmt" 21 apis "github.com/openebs/node-disk-manager/api/v1alpha1" 22 ) 23 24 // Filter selects a single block device from a list of block devices 25 func (c *Config) Filter(bdList *apis.BlockDeviceList) (*apis.BlockDevice, error) { 26 if len(bdList.Items) == 0 { 27 return nil, fmt.Errorf("no blockdevices found") 28 } 29 30 candidateDevices, err := c.getCandidateDevices(bdList) 31 if err != nil { 32 return nil, err 33 } 34 selectedDevice, err := c.getSelectedDevice(candidateDevices) 35 if err != nil { 36 return nil, err 37 } 38 return selectedDevice, nil 39 } 40 41 // getCandidateDevices selects a list of blockdevices from a given block device 42 // list based on criteria specified in the claim spec 43 func (c *Config) getCandidateDevices(bdList *apis.BlockDeviceList) (*apis.BlockDeviceList, error) { 44 45 // filterKeys to be used for filtering, by default active and unclaimed filter is present 46 filterKeys := []string{FilterActive, 47 FilterUnclaimed, 48 // do not consider any devices with legacy annotation for claiming 49 FilterOutLegacyAnnotation, 50 // remove block devices which do not have the blockdevice tag 51 // if selector is present on the BDC, select only those devices 52 // this applies to both manual and auto claiming. 53 FilterBlockDeviceTag, 54 } 55 56 if c.ManualSelection { 57 filterKeys = append(filterKeys, 58 FilterBlockDeviceName, 59 ) 60 } else { 61 filterKeys = append(filterKeys, 62 // Sparse BDs can be claimed only by manual selection. Therefore, all 63 // sparse BDs will be filtered out in auto mode 64 FilterOutSparseBlockDevices, 65 FilterDeviceType, 66 FilterVolumeMode, 67 FilterNodeName, 68 ) 69 } 70 71 candidateBD := c.ApplyFilters(bdList, filterKeys...) 72 73 if len(candidateBD.Items) == 0 { 74 return nil, fmt.Errorf("no devices found matching the criteria") 75 } 76 77 return candidateBD, nil 78 } 79 80 // getSelectedDevice selects a single a block device based on the resource requirements 81 // requested by the claim 82 func (c *Config) getSelectedDevice(bdList *apis.BlockDeviceList) (*apis.BlockDevice, error) { 83 if c.ManualSelection { 84 return &bdList.Items[0], nil 85 } 86 87 // filterKeys for filtering based on resource requirements 88 filterKeys := []string{FilterResourceStorage} 89 90 selectedDevices := c.ApplyFilters(bdList, filterKeys...) 91 92 if len(selectedDevices.Items) == 0 { 93 return nil, fmt.Errorf("could not find a device with matching resource requirements") 94 } 95 96 // will use the first available block device 97 return &selectedDevices.Items[0], nil 98 }