Repository: dell/csi-baremetal
Pull request #854 (2022-05-18 09:10:30)

[ISSUE-825] Revert changes (#826)
## Purpose
### Reverts #825 
This reverts commit 1bd6ce8f5558266b01bef33605fc79c790131d86.
Changes caused regression - stress test with loopback manager failed:
```
[DEBU] [Executor] [sgdisk -n 1:0:0 -c 1:CSI -u 1:1dc34670-667a-4f6a-a35e-eb1b90110392 /dev/loop92] [1.100000372s] [1100000372] stdout: Setting name!

[DEBU] [PartitionOperations] [SearchPartName] [1dc34670-667a-4f6a-a35e-eb1b90110392] Search partition number for device /dev/loop92 and uuid 1dc34670-667a-4f6a-a35e-eb1b90110392

[ERRO] [Executor] [blockdev --rereadpt -v /dev/loop92] [23.387079ms] [23387079] [pkg/base/command/cmdexec.go:186] [runCmdFromCmdObj] stdout: , stderr: blockdev: ioctl error on BLKRRPART: Invalid argument

....
[ERRO] [Executor] [blockdev --rereadpt -v /dev/loop92] [18.975902ms] [18975902] [pkg/base/command/cmdexec.go:186] [runCmdFromCmdObj] stdout: , stderr: blockdev: ioctl error on BLKRRPART: Invalid argument

[ERRO] [PartitionOperations] [SearchPartName] [1dc34670-667a-4f6a-a35e-eb1b90110392] [pkg/node/provisioners/utilwrappers/partition_operations.go:179] [SearchPartName] Unable to sync partition table for device /dev/loop92: exit status 1
```

## PR checklist
- [x] Add link to the issue
- [x] Choose Project
- [x] Choose PR label
- [ ] New unit tests added
- [ ] Modified code has meaningful comments
- [ ] All TODOs are linked with the issues
- [ ] All comments are resolved

## Testing
n/a

codecov[bot]: # [Codecov](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell) Report
> Merging [#854](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell) (fbafdfc) into [master](https://codecov.io/gh/dell/csi-baremetal/commit/4f85fe671ea20e6a23bfe278211d8bd0d1780474?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell) (4f85fe6) will **decrease** coverage by `0.03%`.
> The diff coverage is `84.37%`.

```diff
@@            Coverage Diff             @@
##           master     #854      +/-   ##
==========================================
- Coverage   71.29%   71.26%   -0.04%     
==========================================
  Files          61       61              
  Lines        7612     7586      -26     
==========================================
- Hits         5427     5406      -21     
+ Misses       1938     1934       -4     
+ Partials      247      246       -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `71.26% <84.37%> (-0.04%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell) | Coverage Δ | |
|---|---|---|
| [pkg/crcontrollers/node/common/annotation.go](https://codecov.io/gh/dell/csi-baremetal/pull/854/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell#diff-cGtnL2NyY29udHJvbGxlcnMvbm9kZS9jb21tb24vYW5ub3RhdGlvbi5nbw==) | `92.50% <ø> (-1.62%)` | :arrow_down: |
| [.../provisioners/utilwrappers/partition\_operations.go](https://codecov.io/gh/dell/csi-baremetal/pull/854/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell#diff-cGtnL25vZGUvcHJvdmlzaW9uZXJzL3V0aWx3cmFwcGVycy9wYXJ0aXRpb25fb3BlcmF0aW9ucy5nbw==) | `84.84% <58.33%> (+4.45%)` | :arrow_up: |
| [...ase/linuxutils/partitionhelper/partition\_helper.go](https://codecov.io/gh/dell/csi-baremetal/pull/854/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell#diff-cGtnL2Jhc2UvbGludXh1dGlscy9wYXJ0aXRpb25oZWxwZXIvcGFydGl0aW9uX2hlbHBlci5nbw==) | `98.42% <100.00%> (-0.10%)` | :arrow_down: |
| [pkg/node/provisioners/drive\_provisioner.go](https://codecov.io/gh/dell/csi-baremetal/pull/854/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell#diff-cGtnL25vZGUvcHJvdmlzaW9uZXJzL2RyaXZlX3Byb3Zpc2lvbmVyLmdv) | `93.61% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell). Last update [4f85fe6...fbafdfc](https://codecov.io/gh/dell/csi-baremetal/pull/854?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dell).


Patch:
diff --git a/cmd/drivemgr/loopbackmgr/main.go b/cmd/drivemgr/loopbackmgr/main.go
index cdf3eef..704ec61 100644
--- a/cmd/drivemgr/loopbackmgr/main.go
+++ b/cmd/drivemgr/loopbackmgr/main.go
@@ -66,11 +66,9 @@ func main() {
 		logger.Fatalf("fail to create kubernetes client, error: %v", err)
 	}
 
-	// we need to obtain node ID first before proceeding with the initialization
-	nodeID, err := annotations.ObtainNodeIDWithRetries(k8SClient, featureConf, nodeName, *nodeIDAnnotation,
-		logger, annotations.NumberOfRetries, annotations.DelayBetweenRetries)
+	nodeID, err := annotations.GetNodeIDByName(k8SClient, nodeName, *nodeIDAnnotation, "", featureConf)
 	if err != nil {
-		logger.Fatalf("Unable to obtain node ID: %v", err)
+		logger.Fatalf("fail to get nodeID, error: %v", err)
 	}
 
 	// Server is insecure for now because credentials are nil
diff --git a/cmd/node/main.go b/cmd/node/main.go
index 7323f25..6c7f333 100644
--- a/cmd/node/main.go
+++ b/cmd/node/main.go
@@ -118,8 +118,7 @@ func main() {
 		logger.Fatalf("fail to create kubernetes client, error: %v", err)
 	}
 	// we need to obtain node ID first before proceeding with the initialization
-	nodeID, err := annotations.ObtainNodeIDWithRetries(k8SClient, featureConf, *nodeName, *nodeIDAnnotation,
-		logger, annotations.NumberOfRetries, annotations.DelayBetweenRetries)
+	nodeID, err := obtainNodeIDWithRetries(k8SClient, featureConf, logger)
 	if err != nil {
 		logger.Fatalf("Unable to obtain node ID: %v", err)
 	}
@@ -212,6 +211,22 @@ func main() {
 	logger.Info("Got SIGTERM signal")
 }
 
+func obtainNodeIDWithRetries(client k8sClient.Client, featureConf featureconfig.FeatureChecker,
+	logger *logrus.Logger) (nodeID string, err error) {
+	// try to obtain node ID
+	for i := 0; i < numberOfRetries; i++ {
+		logger.Info("Obtaining node ID...")
+		if nodeID, err = annotations.GetNodeIDByName(client, *nodeName, *nodeIDAnnotation, "", featureConf); err == nil {
+			logger.Infof("Node ID is %s", nodeID)
+			return nodeID, nil
+		}
+		logger.Warningf("Unable to get node ID due to %v, sleep and retry...", err)
+		time.Sleep(delayBeforeRetry * time.Second)
+	}
+	// return empty node ID and error
+	return "", fmt.Errorf("number of retries %d exceeded", numberOfRetries)
+}
+
 func waitForVolumeManagerReadiness(c *node.CSINodeService, logger *logrus.Logger) {
 	// check here for volume manager readiness
 	// input parameters are ignored by Check() function - pass empty context and health check request
diff --git a/devkit/start_ide.sh b/devkit/start_ide.sh
index f4f85c6..e2b01df 100755
--- a/devkit/start_ide.sh
+++ b/devkit/start_ide.sh
@@ -16,7 +16,7 @@ if [[ ! -x $START_SCRIPT ]]; then
     exit 1
 fi
 
-$START_SCRIPT &>/dev/null &
+$START_SCRIPT #&>/dev/null &
 
 # sleep for a while to give a process a chance to start
 # if something is wrong, process will start and exit but we want it to start and work
diff --git a/pkg/base/linuxutils/partitionhelper/partition_helper.go b/pkg/base/linuxutils/partitionhelper/partition_helper.go
index fd9224e..7da683c 100644
--- a/pkg/base/linuxutils/partitionhelper/partition_helper.go
+++ b/pkg/base/linuxutils/partitionhelper/partition_helper.go
@@ -22,7 +22,6 @@ import (
 	"fmt"
 	"strings"
 	"sync"
-	"time"
 
 	"github.com/sirupsen/logrus"
 
@@ -77,11 +76,6 @@ const (
 
 	// GetPartitionUUIDCmdTmpl command for read GUID of the first partition, fill device and part number
 	GetPartitionUUIDCmdTmpl = sgdisk + "%s --info=%s"
-
-	// NumberOfRetriesToSyncPartTable how many times to sync fs tab
-	NumberOfRetriesToSyncPartTable = 5
-	// SleepBetweenRetriesToSyncPartTable default timeout between fs tab sync attempt
-	SleepBetweenRetriesToSyncPartTable = 3 * time.Second
 )
 
 // supportedTypes list of supported partition table types
@@ -89,34 +83,16 @@ var supportedTypes = []string{PartitionGPT}
 
 // WrapPartitionImpl is the basic implementation of WrapPartition interface
 type WrapPartitionImpl struct {
-	e                                  command.CmdExecutor
-	lsblkUtil                          lsblk.WrapLsblk
-	opMutex                            sync.Mutex
-	numberOfRetriesToSyncPartTable     int
-	sleepBetweenRetriesToSyncPartTable time.Duration
-	log                                *logrus.Logger
+	e         command.CmdExecutor
+	lsblkUtil lsblk.WrapLsblk
+	opMutex   sync.Mutex
 }
 
 // NewWrapPartitionImpl is a constructor for WrapPartitionImpl instance
 func NewWrapPartitionImpl(e command.CmdExecutor, log *logrus.Logger) *WrapPartitionImpl {
 	return &WrapPartitionImpl{
-		e:                                  e,
-		lsblkUtil:                          lsblk.NewLSBLK(log),
-		numberOfRetriesToSyncPartTable:     NumberOfRetriesToSyncPartTable,
-		sleepBetweenRetriesToSyncPartTable: SleepBetweenRetriesToSyncPartTable,
-		log:                                log,
-	}
-}
-
-// NewWrapPartitionImplWithParameters is a constructor for WrapPartitionImpl instance
-func NewWrapPartitionImplWithParameters(e command.CmdExecutor, log *logrus.Logger, numberOfRetriesToSyncPartTable int,
-	sleepBetweenRetriesToSyncPartTable time.Duration) *WrapPartitionImpl {
-	return &WrapPartitionImpl{
-		e:                                  e,
-		lsblkUtil:                          lsblk.NewLSBLK(log),
-		numberOfRetriesToSyncPartTable:     numberOfRetriesToSyncPartTable,
-		sleepBetweenRetriesToSyncPartTable: sleepBetweenRetriesToSyncPartTable,
-		log:                                log,
+		e:         e,
+		lsblkUtil: lsblk.NewLSBLK(log),
 	}
 }
 
@@ -275,22 +251,20 @@ func (p *WrapPartitionImpl) GetPartitionUUID(device, partNum string) (string, er
 // SyncPartitionTable syncs partition table for specific device
 // Receives device path to sync with partprobe, device could be an empty string (sync for all devices in the system)
 // Returns error if something went wrong
-func (p *WrapPartitionImpl) SyncPartitionTable(device string) (err error) {
+func (p *WrapPartitionImpl) SyncPartitionTable(device string) error {
 	cmd := fmt.Sprintf(BlockdevCmdTmpl, device)
 
-	for i := 0; i < p.numberOfRetriesToSyncPartTable; i++ {
-		// sync partition table
-		p.opMutex.Lock()
-		_, _, err = p.e.RunCmd(cmd, command.UseMetrics(true),
-			command.CmdName(strings.TrimSpace(fmt.Sprintf(BlockdevCmdTmpl, ""))))
-		p.opMutex.Unlock()
-		if err == nil {
-			return nil
-		}
-		time.Sleep(p.sleepBetweenRetriesToSyncPartTable)
+	p.opMutex.Lock()
+	_, _, err := p.e.RunCmd(cmd,
+		command.UseMetrics(true),
+		command.CmdName(strings.TrimSpace(fmt.Sprintf(BlockdevCmdTmpl, ""))))
+	p.opMutex.Unlock()
+
+	if err != nil {
+		return err
 	}
 
-	return
+	return nil
 }
 
 // GetPartitionNameByUUID gets partition name by it's UUID
@@ -317,7 +291,6 @@ func (p *WrapPartitionImpl) GetPartitionNameByUUID(device, partUUID string) (str
 
 	// try to find partition name
 	for _, id := range blockdevices[0].Children {
-		p.log.Debugf("Parition info: %v", id)
 		// ignore cases
 		if strings.EqualFold(partUUID, id.PartUUID) {
 			// partition name not detected
@@ -329,7 +302,8 @@ func (p *WrapPartitionImpl) GetPartitionNameByUUID(device, partUUID string) (str
 		}
 	}
 
-	return "", fmt.Errorf("unable to find partition name by UUID %s for device %s", partUUID, device)
+	return "", fmt.Errorf("unable to find partition name by UUID %s for device %s within %v",
+		partUUID, device, blockdevices)
 }
 
 // DeviceHasPartitionTable calls parted  and determine if device has partition table from output
diff --git a/pkg/crcontrollers/node/common/annotation.go b/pkg/crcontrollers/node/common/annotation.go
index 53cd9a5..4b27262 100644
--- a/pkg/crcontrollers/node/common/annotation.go
+++ b/pkg/crcontrollers/node/common/annotation.go
@@ -20,39 +20,13 @@ import (
 	"context"
 	"fmt"
 	"strings"
-	"time"
 
-	"github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
 	k8sClient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/dell/csi-baremetal/pkg/base/featureconfig"
 )
 
-const (
-	// NumberOfRetries to obtain Node ID
-	NumberOfRetries = 20
-	// DelayBetweenRetries to obtain Node ID
-	DelayBetweenRetries = 3
-)
-
-// ObtainNodeIDWithRetries obtains Node ID with retries
-func ObtainNodeIDWithRetries(client k8sClient.Client, featureConf featureconfig.FeatureChecker, nodeName string,
-	nodeIDAnnotation string, logger *logrus.Logger, retries int, delay time.Duration) (nodeID string, err error) {
-	// try to obtain node ID
-	for i := 0; i < retries; i++ {
-		logger.Info("Obtaining node ID...")
-		if nodeID, err = GetNodeIDByName(client, nodeName, nodeIDAnnotation, "", featureConf); err == nil {
-			logger.Infof("Node ID is %s", nodeID)
-			return nodeID, nil
-		}
-		logger.Warningf("Unable to get node ID due to %v, sleep and retry...", err)
-		time.Sleep(delay * time.Second)
-	}
-	// return empty node ID and error
-	return "", fmt.Errorf("number of retries %d exceeded", retries)
-}
-
 // GetNodeIDByName return special id for k8sNode with nodeName
 // depends on NodeIdFromAnnotation and ExternalNodeAnnotation features
 func GetNodeIDByName(client k8sClient.Client, nodeName, annotationKey, nodeSelector string, featureChecker featureconfig.FeatureChecker) (string, error) {
diff --git a/pkg/mocks/provisioners/mock_parititoner.go b/pkg/mocks/provisioners/mock_parititoner.go
index dae370d..e3c8dcf 100644
--- a/pkg/mocks/provisioners/mock_parititoner.go
+++ b/pkg/mocks/provisioners/mock_parititoner.go
@@ -44,8 +44,8 @@ func (m *MockPartitionOps) ReleasePartition(p utilwrappers.Partition) error {
 }
 
 // SearchPartName is a mock implementation
-func (m *MockPartitionOps) SearchPartName(device, partUUID string) (string, error) {
+func (m *MockPartitionOps) SearchPartName(device, partUUID string) string {
 	args := m.Mock.Called(device, partUUID)
 
-	return args.String(0), args.Error(1)
+	return args.String(0)
 }
diff --git a/pkg/node/provisioners/drive_provisioner.go b/pkg/node/provisioners/drive_provisioner.go
index f4501f2..932be61 100644
--- a/pkg/node/provisioners/drive_provisioner.go
+++ b/pkg/node/provisioners/drive_provisioner.go
@@ -156,10 +156,10 @@ func (d *DriveProvisioner) ReleaseVolume(vol *api.Volume, drive *api.Drive) erro
 		}
 	)
 
-	part.Name, err = d.partOps.SearchPartName(device, part.PartUUID)
-	if err != nil {
+	part.Name = d.partOps.SearchPartName(device, part.PartUUID)
+	if part.Name == "" {
 		return d.wipeDevice(device,
-			fmt.Errorf("unable to find partition name for volume %s: %w", vol.Id, err), ll)
+			fmt.Errorf("unable to find partition name for volume %s", vol.Id), ll)
 	}
 
 	// wipe FS on partition
@@ -224,10 +224,10 @@ func (d *DriveProvisioner) GetVolumePath(vol *api.Volume) (string, error) {
 	}
 	volumeUUID, _ = util.GetVolumeUUID(volumeUUID)
 
-	partNum, err := d.partOps.SearchPartName(device, volumeUUID)
-	if err != nil {
+	partNum := d.partOps.SearchPartName(device, volumeUUID)
+	if partNum == "" {
 		// on device disconnect or node reboot device name might change and we need to re-sync drive info
-		return "", fmt.Errorf("unable to find part name for device %s by uuid %s: %w", device, volumeUUID, err)
+		return "", fmt.Errorf("unable to find part name for device %s by uuid %s", device, volumeUUID)
 	}
 	return device + partNum, nil
 }
diff --git a/pkg/node/provisioners/utilwrappers/partition_operations.go b/pkg/node/provisioners/utilwrappers/partition_operations.go
index 0290ef0..61e6361 100644
--- a/pkg/node/provisioners/utilwrappers/partition_operations.go
+++ b/pkg/node/provisioners/utilwrappers/partition_operations.go
@@ -28,13 +28,6 @@ import (
 	"github.com/dell/csi-baremetal/pkg/metrics"
 )
 
-const (
-	// NumberOfRetriesToObtainPartName how many retries to obtain partition name
-	NumberOfRetriesToObtainPartName = 5
-	// SleepBetweenRetriesToObtainPartName default timeout between retries to obtain partition name
-	SleepBetweenRetriesToObtainPartName = 3 * time.Second
-)
-
 // PartitionOperations is a high-level interface
 // that encapsulates all low-level operations with partitions on node
 type PartitionOperations interface {
@@ -43,10 +36,17 @@ type PartitionOperations interface {
 	// ReleasePartition is fully release resources that had consumed by partition on node
 	ReleasePartition(p Partition) error
 	// SearchPartName returns partition name
-	SearchPartName(device, partUUID string) (string, error)
+	SearchPartName(device, partUUID string) string
 	ph.WrapPartition
 }
 
+const (
+	// NumberOfRetriesToSyncPartTable how many times to sync fs tab
+	NumberOfRetriesToSyncPartTable = 3
+	// SleepBetweenRetriesToSyncPartTable default timeout between fs tab sync attempt
+	SleepBetweenRetriesToSyncPartTable = 3 * time.Second
+)
+
 // Partition is hold all attributes of partition on block device
 type Partition struct {
 	Device    string
@@ -109,8 +109,8 @@ func (d *PartitionOperationsImpl) PreparePartition(p Partition) (*Partition, err
 		}
 		if currUUID == p.PartUUID {
 			ll.Infof("Partition has already prepared.")
-			p.Name, err = d.SearchPartName(p.Device, p.PartUUID)
-			if err != nil {
+			p.Name = d.SearchPartName(p.Device, p.PartUUID)
+			if p.Name == "" {
 				return nil, fmt.Errorf("unable to determine partition name after it being created: %w", err)
 			}
 			return &p, nil
@@ -127,11 +127,11 @@ func (d *PartitionOperationsImpl) PreparePartition(p Partition) (*Partition, err
 	if err = d.CreatePartition(p.Device, p.Label, p.PartUUID); err != nil {
 		return nil, fmt.Errorf("unable to create partition: %v", err)
 	}
+	_ = d.SyncPartitionTable(p.Device)
 
-	// obtain partition name
-	p.Name, err = d.SearchPartName(p.Device, p.PartUUID)
-	if err != nil {
-		return nil, fmt.Errorf("unable to determine partition name after it being created: %w", err)
+	p.Name = d.SearchPartName(p.Device, p.PartUUID)
+	if p.Name == "" {
+		return nil, fmt.Errorf("unable to determine partition name after it being created: %v", err)
 	}
 
 	return &p, nil
@@ -157,7 +157,7 @@ func (d *PartitionOperationsImpl) ReleasePartition(p Partition) error {
 
 // SearchPartName search (with retries) partition with UUID partUUID on device and returns partition name
 // e.g. "1" for /dev/sda1, "p1n1" for /dev/loopbackp1n1
-func (d *PartitionOperationsImpl) SearchPartName(device, partUUID string) (string, error) {
+func (d *PartitionOperationsImpl) SearchPartName(device, partUUID string) string {
 	defer d.metrics.EvaluateDurationForMethod("SearchPartName")()
 	ll := d.log.WithFields(logrus.Fields{
 		"method":   "SearchPartName",
@@ -171,30 +171,22 @@ func (d *PartitionOperationsImpl) SearchPartName(device, partUUID string) (strin
 	)
 
 	// get partition name
-	for i := 0; i < NumberOfRetriesToObtainPartName; i++ {
+	for i := 0; i < NumberOfRetriesToSyncPartTable; i++ {
 		// sync partition table
 		err = d.SyncPartitionTable(device)
 		if err != nil {
 			// log and ignore error
-			ll.Errorf("Unable to sync partition table for device %s: %v", device, err)
-			return "", err
+			ll.Warningf("Unable to sync partition table for device %s", device)
 		}
-		// sleep first to avoid issues with lsblk caching
-		time.Sleep(SleepBetweenRetriesToObtainPartName)
+		time.Sleep(SleepBetweenRetriesToSyncPartTable)
 		partName, err = d.GetPartitionNameByUUID(device, partUUID)
 		if err != nil {
-			ll.Warningf("Unable to find part name: %v. Sleep and retry...", err)
+			ll.Debugf("unable to find part name: %v", err)
 			continue
 		}
 		break
 	}
 
-	// partition not found
-	if partName == "" {
-		ll.Errorf("Partition not found: %v", err)
-		return "", err
-	}
-
 	ll.Debugf("Got partition number %s", partName)
-	return partName, nil
+	return partName
 }


Test patch:
diff --git a/pkg/base/linuxutils/partitionhelper/partitionhelper_test.go b/pkg/base/linuxutils/partitionhelper/partitionhelper_test.go
index a178d5e..21f9c1f 100644
--- a/pkg/base/linuxutils/partitionhelper/partitionhelper_test.go
+++ b/pkg/base/linuxutils/partitionhelper/partitionhelper_test.go
@@ -32,7 +32,7 @@ import (
 
 var (
 	testLogger      = logrus.New()
-	testPartitioner = NewWrapPartitionImplWithParameters(mocks.NewMockExecutor(mocks.DiskCommands), testLogger, 1, 1)
+	testPartitioner = NewWrapPartitionImpl(mocks.NewMockExecutor(mocks.DiskCommands), testLogger)
 	testPartNum     = "1"
 	testCSILabel    = "CSI"
 	testPartUUID    = "64be631b-62a5-11e9-a756-00505680d67f"
diff --git a/pkg/crcontrollers/node/common/annotation_test.go b/pkg/crcontrollers/node/common/annotation_test.go
index ad10cd9..3409fa4 100644
--- a/pkg/crcontrollers/node/common/annotation_test.go
+++ b/pkg/crcontrollers/node/common/annotation_test.go
@@ -34,39 +34,6 @@ var (
 	annotationValue = "1111-2222-3333-4444"
 )
 
-func TestObtainNodeIDWithRetries(t *testing.T) {
-	t.Run("Not found", func(t *testing.T) {
-		k8sClient, err := k8s.GetFakeKubeClient(testNS, testLogger)
-		assert.Nil(t, err)
-
-		featureConf := fc.NewFeatureConfig()
-
-		nodeID, err := ObtainNodeIDWithRetries(k8sClient, featureConf, nodeName, "app=baremetal-csi",
-			testLogger, 1, 0)
-		assert.NotNil(t, err)
-		assert.Equal(t, nodeID, "")
-	})
-
-	t.Run("Obtained", func(t *testing.T) {
-		k8sClient, err := k8s.GetFakeKubeClient(testNS, testLogger)
-		assert.Nil(t, err)
-
-		featureConf := fc.NewFeatureConfig()
-		featureConf.Update(fc.FeatureNodeIDFromAnnotation, true)
-		featureConf.Update(fc.FeatureExternalAnnotationForNode, true)
-
-		node := testNode.DeepCopy()
-		node.Annotations[annotationKey] = annotationValue
-		node.SetLabels(map[string]string{"app": "baremetal-csi"})
-
-		assert.Nil(t, k8sClient.Create(testCtx, node))
-
-		nodeID, err := ObtainNodeIDWithRetries(k8sClient, featureConf, nodeName, annotationKey, testLogger, 1, 0)
-		assert.Equal(t, annotationValue, nodeID)
-		assert.Nil(t, err)
-	})
-}
-
 func TestGetNodeID(t *testing.T) {
 	t.Run("All features disabled", func(t *testing.T) {
 		featureConf := fc.NewFeatureConfig()
diff --git a/pkg/node/provisioners/drive_provisioner_test.go b/pkg/node/provisioners/drive_provisioner_test.go
index 4d298ee..fb46bf9 100644
--- a/pkg/node/provisioners/drive_provisioner_test.go
+++ b/pkg/node/provisioners/drive_provisioner_test.go
@@ -259,7 +259,7 @@ func TestDriveProvisioner_ReleaseVolume_Fail(t *testing.T) {
 
 	// SearchPartName returns empty string and GetBlockDevices return error
 	mockPH.On("SearchPartName", deviceFile, testVolume2.Id).
-		Return("", errTest).Once()
+		Return("").Once()
 	mockLsblk.On("GetBlockDevices", deviceFile).
 		Return(nil, errTest)
 
@@ -270,7 +270,7 @@ func TestDriveProvisioner_ReleaseVolume_Fail(t *testing.T) {
 	// next scenarios rely on SearchPartName passes
 	var partName = "p1n1"
 	mockPH.On("SearchPartName", deviceFile, testVolume2.Id).
-		Return(partName, nil)
+		Return(partName)
 
 	// WipeFS failed
 	mockFS.On("WipeFS", deviceFile+partName).Return(errTest).Once()
@@ -349,7 +349,7 @@ func TestDriveProvisioner_GetVolumePath_Fail(t *testing.T) {
 	mockLsblk.On("SearchDrivePath", mock.Anything).
 		Return(deviceFile, nil).Once()
 	mockPH.On("SearchPartName", deviceFile, testVolume2.Id).
-		Return("", errTest).Once()
+		Return("").Once()
 
 	fullPath, err = dp.GetVolumePath(&testVolume2)
 	assert.Error(t, err)
diff --git a/tests/app/nginx.yaml b/tests/app/nginx.yaml
index 5f3715a..4283123 100644
--- a/tests/app/nginx.yaml
+++ b/tests/app/nginx.yaml
@@ -4,7 +4,7 @@ metadata:
   name: web
 spec:
   serviceName: "nginx"
-  replicas: 3
+  replicas: 4
   podManagementPolicy: Parallel
   selector:
     matchLabels:
diff --git a/tests/ci.sh b/tests/ci.sh
deleted file mode 100755
index f2aaa9f..0000000
--- a/tests/ci.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/bash
-if [ $# -gt 1 ]; then
-    echo "deploy.sh <number of devices>"
-fi
-
-# TODO check for REGISTRY env var
-export REGISTRY=asdrepo.isus.emc.com:9042
-
-NUMBER_OF_DEVICES=3
-if [ $# -eq 1 ]; then
-    NUMBER_OF_DEVICES=$1
-fi
-echo "Number of loopback devices per node:" $NUMBER_OF_DEVICES
-
-
-# build binaries
-make DRIVE_MANAGER_TYPE=loopbackmgr build
-if [ $? -ne 0 ]; then
-    echo "Failed to build binaries"
-    exit 1
-fi
-
-# build final images
-make DRIVE_MANAGER_TYPE=loopbackmgr images
-if [ $? -ne 0 ]; then
-    echo "Failed to build final images"
-    exit 1
-fi
-
-# pull sidecar images
-make kind-pull-sidecar-images
-if [ $? -ne 0 ]; then
-    echo "Failed to build final images"
-    exit 1
-fi
-
-# load to kind cluster
-make kind-tag-images
-if [ $? -ne 0 ]; then
-    echo "Failed to tag images"
-    exit 1
-fi
-
-make kind-load-images KIND=`which kind`
-if [ $? -ne 0 ]; then
-    echo "Failed to load images"
-    exit 1
-fi
-
-export OPERATOR_VERSION=`cd ../csi-baremetal-operator && make version`
-make load-operator-image KIND=`which kind`
-if [ $? -ne 0 ]; then
-    echo "Failed to load operator image"
-    exit 1
-fi
-
-export CSI_VERSION=`make version`
-export CSI_OPERATOR_VERSION=$OPERATOR_VERSION
-export SHORT_CI_TIMEOUT=20m
-export CHARTS_DIR=../csi-baremetal-operator/charts
-
-#CI=true CSI_VERSION=${CSI_VERSION} OPERATOR_VERSION=${OPERATOR_VERSION} go test -v test/e2e/baremetal_e2e_test.go -ginkgo.v -ginkgo.progress -ginkgo.failFast -all-tests -kubeconfig=${HOME}/.kube/config -chartsDir ${CHARTS_DIR}