diff --git a/internal/cephfs/util.go b/internal/cephfs/util.go index 9142423fa..f530a1a7d 100644 --- a/internal/cephfs/util.go +++ b/internal/cephfs/util.go @@ -41,7 +41,7 @@ func execCommandJSON(ctx context.Context, v interface{}, program string, args .. return err } - if err = json.Unmarshal(stdout, v); err != nil { + if err = json.Unmarshal([]byte(stdout), v); err != nil { return fmt.Errorf("failed to unmarshal JSON for %s %v: %s: %w", program, util.StripSecretInArgs(args), stdout, err) } diff --git a/internal/cephfs/volume.go b/internal/cephfs/volume.go index ddfa13042..f6a3d4599 100644 --- a/internal/cephfs/volume.go +++ b/internal/cephfs/volume.go @@ -67,16 +67,15 @@ func getVolumeRootPathCeph(ctx context.Context, volOptions *volumeOptions, cr *u "--keyfile="+cr.KeyFile) if err != nil { - stdErrString := string(stderr) - klog.Errorf(util.Log(ctx, "failed to get the rootpath for the vol %s(%s) stdError %s"), string(volID), err, stdErrString) + klog.Errorf(util.Log(ctx, "failed to get the rootpath for the vol %s(%s) stdError %s"), string(volID), err, stderr) - if strings.HasPrefix(stdErrString, errNotFoundString) { + if strings.HasPrefix(stderr, errNotFoundString) { return "", util.JoinErrors(ErrVolumeNotFound, err) } return "", err } - return strings.TrimSuffix(string(stdout), "\n"), nil + return strings.TrimSuffix(stdout, "\n"), nil } type localClusterState struct { diff --git a/internal/cephfs/volumemounter.go b/internal/cephfs/volumemounter.go index 5bc8a61c0..d85317c9f 100644 --- a/internal/cephfs/volumemounter.go +++ b/internal/cephfs/volumemounter.go @@ -176,7 +176,7 @@ func mountFuse(ctx context.Context, mountPoint string, cr *util.Credentials, vol // We need "starting fuse" meaning the mount is ok // and PID of the ceph-fuse daemon for unmount - match := fusePidRx.FindSubmatch(stderr) + match := fusePidRx.FindSubmatch([]byte(stderr)) // validMatchLength is set to 2 as match is expected // to have 2 items, starting fuse and PID of the fuse daemon const validMatchLength = 2 diff --git a/internal/rbd/rbd_attach.go b/internal/rbd/rbd_attach.go index d05621b1b..ca20258e4 100644 --- a/internal/rbd/rbd_attach.go +++ b/internal/rbd/rbd_attach.go @@ -90,9 +90,9 @@ func rbdGetDeviceList(ctx context.Context, accessType string) ([]rbdDeviceInfo, } if accessType == accessTypeKRbd { - err = json.Unmarshal(stdout, &rbdDeviceList) + err = json.Unmarshal([]byte(stdout), &rbdDeviceList) } else { - err = json.Unmarshal(stdout, &nbdDeviceList) + err = json.Unmarshal([]byte(stdout), &nbdDeviceList) } if err != nil { return nil, fmt.Errorf("error to parse JSON output of device list for devices of type (%s): (%v)", accessType, err) @@ -231,7 +231,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (s // Execute map stdout, stderr, err := util.ExecCommand(ctx, rbd, mapOptions...) if err != nil { - klog.Warningf(util.Log(ctx, "rbd: map error %v, rbd output: %s"), err, string(stderr)) + klog.Warningf(util.Log(ctx, "rbd: map error %v, rbd output: %s"), err, stderr) // unmap rbd image if connection timeout if strings.Contains(err.Error(), rbdMapConnectionTimeout) { detErr := detachRBDImageOrDeviceSpec(ctx, imagePath, true, isNbd, volOpt.Encrypted, volOpt.VolID) @@ -239,9 +239,9 @@ func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (s klog.Warningf(util.Log(ctx, "rbd: %s unmap error %v"), imagePath, detErr) } } - return "", fmt.Errorf("rbd: map failed %v, rbd output: %s", err, string(stderr)) + return "", fmt.Errorf("rbd: map failed with error %v, rbd error output: %s", err, stderr) } - devicePath := strings.TrimSuffix(string(stdout), "\n") + devicePath := strings.TrimSuffix(stdout, "\n") return devicePath, nil } @@ -311,13 +311,13 @@ func detachRBDImageOrDeviceSpec(ctx context.Context, imageOrDeviceSpec string, i // Messages for krbd and nbd differ, hence checking either of them for missing mapping // This is not applicable when a device path is passed in if isImageSpec && - (strings.Contains(string(stderr), fmt.Sprintf(rbdUnmapCmdkRbdMissingMap, imageOrDeviceSpec)) || - strings.Contains(string(stderr), fmt.Sprintf(rbdUnmapCmdNbdMissingMap, imageOrDeviceSpec))) { + (strings.Contains(stderr, fmt.Sprintf(rbdUnmapCmdkRbdMissingMap, imageOrDeviceSpec)) || + strings.Contains(stderr, fmt.Sprintf(rbdUnmapCmdNbdMissingMap, imageOrDeviceSpec))) { // Devices found not to be mapped are treated as a successful detach util.TraceLog(ctx, "image or device spec (%s) not mapped", imageOrDeviceSpec) return nil } - return fmt.Errorf("rbd: unmap for spec (%s) failed (%v): (%s)", imageOrDeviceSpec, err, string(stderr)) + return fmt.Errorf("rbd: unmap for spec (%s) failed (%v): (%s)", imageOrDeviceSpec, err, stderr) } return nil diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 3a90a8d80..55eb70ce9 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -307,11 +307,11 @@ func addRbdManagerTask(ctx context.Context, pOpts *rbdVolume, arg []string) (boo if err != nil { switch { - case strings.Contains(string(stderr), rbdTaskRemoveCmdInvalidString1) && - strings.Contains(string(stderr), rbdTaskRemoveCmdInvalidString2): + case strings.Contains(stderr, rbdTaskRemoveCmdInvalidString1) && + strings.Contains(stderr, rbdTaskRemoveCmdInvalidString2): klog.Warningf(util.Log(ctx, "cluster with cluster ID (%s) does not support Ceph manager based rbd commands (minimum ceph version required is v14.2.3)"), pOpts.ClusterID) supported = false - case strings.HasPrefix(string(stderr), rbdTaskRemoveCmdAccessDeniedMessage): + case strings.HasPrefix(stderr, rbdTaskRemoveCmdAccessDeniedMessage): klog.Warningf(util.Log(ctx, "access denied to Ceph MGR-based rbd commands on cluster ID (%s)"), pOpts.ClusterID) supported = false default: @@ -883,17 +883,17 @@ func (rv *rbdVolume) updateVolWithImageInfo(cr *util.Credentials) error { "info", rv.String()) if err != nil { klog.Errorf("failed getting information for image (%s): (%s)", rv, err) - if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+ + if strings.Contains(stderr, "rbd: error opening image "+rv.RbdImageName+ ": (2) No such file or directory") { return util.JoinErrors(ErrImageNotFound, err) } return err } - err = json.Unmarshal(stdout, &imgInfo) + err = json.Unmarshal([]byte(stdout), &imgInfo) if err != nil { klog.Errorf("failed to parse JSON output of image info (%s): (%s)", rv, err) - return fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, string(stdout)) + return fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, stdout) } rv.VolSize = imgInfo.Size @@ -1051,7 +1051,7 @@ func resizeRBDImage(rbdVol *rbdVolume, cr *util.Credentials) error { _, stderr, err := util.ExecCommand(context.TODO(), "rbd", args...) if err != nil { - return fmt.Errorf("failed to resize rbd image (%w), command output: %s", err, string(stderr)) + return fmt.Errorf("failed to resize rbd image (%w), command output: %s", err, stderr) } return nil @@ -1129,17 +1129,17 @@ func (rv *rbdVolume) listSnapshots(ctx context.Context, cr *util.Credentials) ([ "--all", rv.String()) if err != nil { klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rv, err) - if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+ + if strings.Contains(stderr, "rbd: error opening image "+rv.RbdImageName+ ": (2) No such file or directory") { return snapInfo, util.JoinErrors(ErrImageNotFound, err) } return snapInfo, err } - err = json.Unmarshal(stdout, &snapInfo) + err = json.Unmarshal([]byte(stdout), &snapInfo) if err != nil { klog.Errorf(util.Log(ctx, "failed to parse JSON output of snapshot info (%s)"), err) - return snapInfo, fmt.Errorf("unmarshal failed: %w. raw buffer response: %s", err, string(stdout)) + return snapInfo, fmt.Errorf("unmarshal failed: %w. raw buffer response: %s", err, stdout) } return snapInfo, nil } diff --git a/internal/util/cephcmds.go b/internal/util/cephcmds.go index 17453be41..edaa8fbb6 100644 --- a/internal/util/cephcmds.go +++ b/internal/util/cephcmds.go @@ -33,7 +33,7 @@ const InvalidPoolID int64 = -1 // ExecCommand executes passed in program with args and returns separate stdout // and stderr streams. In case ctx is not set to context.TODO(), the command // will be logged after it was executed. -func ExecCommand(ctx context.Context, program string, args ...string) (stdout, stderr []byte, err error) { +func ExecCommand(ctx context.Context, program string, args ...string) (string, string, error) { var ( cmd = exec.Command(program, args...) // #nosec:G204, commands executing not vulnerable. sanitizedArgs = StripSecretInArgs(args) @@ -44,19 +44,23 @@ func ExecCommand(ctx context.Context, program string, args ...string) (stdout, s cmd.Stdout = &stdoutBuf cmd.Stderr = &stderrBuf - if err := cmd.Run(); err != nil { + err := cmd.Run() + stdout := stdoutBuf.String() + stderr := stderrBuf.String() + + if err != nil { err = fmt.Errorf("an error (%w) occurred while running %s args: %v", err, program, sanitizedArgs) if ctx != context.TODO() { UsefulLog(ctx, "%s", err) } - return stdoutBuf.Bytes(), stderrBuf.Bytes(), err + return stdout, stderr, err } if ctx != context.TODO() { UsefulLog(ctx, "command succeeded: %s %v", program, sanitizedArgs) } - return stdoutBuf.Bytes(), nil, nil + return stdout, stderr, nil } // GetPoolID fetches the ID of the pool that matches the passed in poolName