Fix windows build

This commit is contained in:
divolgin
2021-10-27 21:20:06 +00:00
parent e7daba9d0c
commit db3d27d38f
4 changed files with 366 additions and 296 deletions

View File

@@ -118,6 +118,26 @@ jobs:
- run: ./bin/support-bundle ./examples/support-bundle/sample-supportbundle.yaml
- run: ./bin/support-bundle https://kots.io
goreleaser-test:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') != true
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Unshallow
run: git fetch --prune --unshallow
- uses: actions/setup-go@v1
with:
go-version: "1.17"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: "v0.183.0"
args: build --rm-dist --snapshot --config deploy/.goreleaser.yaml
goreleaser:
runs-on: ubuntu-latest
needs:
@@ -159,7 +179,7 @@ jobs:
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: "v0.166.1"
version: "v0.183.0"
args: release --rm-dist --config deploy/.goreleaser.yaml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

306
pkg/longhorn/util/iscsi.go Normal file
View File

@@ -0,0 +1,306 @@
// +build !windows
package util
import (
"encoding/json"
"fmt"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
iscsi_util "github.com/longhorn/go-iscsi-helper/util"
)
func GetDiskInfo(directory string) (info *DiskInfo, err error) {
defer func() {
err = errors.Wrapf(err, "cannot get disk info of directory %v", directory)
}()
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath)
output, err := Execute([]string{}, "nsenter", mountPath, "stat", "-fc", "{\"path\":\"%n\",\"fsid\":\"%i\",\"type\":\"%T\",\"freeBlock\":%f,\"totalBlock\":%b,\"blockSize\":%S}", directory)
if err != nil {
return nil, err
}
output = strings.Replace(output, "\n", "", -1)
diskInfo := &DiskInfo{}
err = json.Unmarshal([]byte(output), diskInfo)
if err != nil {
return nil, err
}
diskInfo.StorageMaximum = diskInfo.TotalBlock * diskInfo.BlockSize
diskInfo.StorageAvailable = diskInfo.FreeBlock * diskInfo.BlockSize
return diskInfo, nil
}
func RemoveHostDirectoryContent(directory string) (err error) {
defer func() {
err = errors.Wrapf(err, "failed to remove host directory %v", directory)
}()
dir, err := filepath.Abs(filepath.Clean(directory))
if err != nil {
return err
}
if strings.Count(dir, "/") < 2 {
return fmt.Errorf("prohibit removing the top level of directory %v", dir)
}
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(initiatorNSPath)
if err != nil {
return err
}
// check if the directory already deleted
if _, err := nsExec.Execute("ls", []string{dir}); err != nil {
logrus.Warnf("cannot find host directory %v for removal", dir)
return nil
}
if _, err := nsExec.Execute("rm", []string{"-rf", dir}); err != nil {
return err
}
return nil
}
func CopyHostDirectoryContent(src, dest string) (err error) {
defer func() {
err = errors.Wrapf(err, "failed to copy the content from %v to %v for the host", src, dest)
}()
srcDir, err := filepath.Abs(filepath.Clean(src))
if err != nil {
return err
}
destDir, err := filepath.Abs(filepath.Clean(dest))
if err != nil {
return err
}
if strings.Count(srcDir, "/") < 2 || strings.Count(destDir, "/") < 2 {
return fmt.Errorf("prohibit copying the content for the top level of directory %v or %v", srcDir, destDir)
}
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(initiatorNSPath)
if err != nil {
return err
}
// There can be no src directory, hence returning nil is fine.
if _, err := nsExec.Execute("bash", []string{"-c", fmt.Sprintf("ls %s", filepath.Join(srcDir, "*"))}); err != nil {
logrus.Infof("cannot list the content of the src directory %v for the copy, will do nothing: %v", srcDir, err)
return nil
}
// Check if the dest directory exists.
if _, err := nsExec.Execute("mkdir", []string{"-p", destDir}); err != nil {
return err
}
// The flag `-n` means not overwriting an existing file.
if _, err := nsExec.Execute("bash", []string{"-c", fmt.Sprintf("cp -an %s %s", filepath.Join(srcDir, "*"), destDir)}); err != nil {
return err
}
return nil
}
func CreateDiskPathReplicaSubdirectory(path string) error {
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return err
}
if _, err := nsExec.Execute("mkdir", []string{"-p", filepath.Join(path, ReplicaDirectory)}); err != nil {
return errors.Wrapf(err, "error creating data path %v on host", path)
}
return nil
}
func DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(
nsExec *iscsi_util.NamespaceExecutor, path string) error {
var err error
dirPath := filepath.Join(path, ReplicaDirectory)
filePath := filepath.Join(path, DiskConfigFile)
// Check if the replica directory exist, delete it
if _, err := nsExec.Execute("ls", []string{dirPath}); err == nil {
if _, err := nsExec.Execute("rmdir", []string{dirPath}); err != nil {
return errors.Wrapf(err, "error deleting data path %v on host", path)
}
}
// Check if the disk cfg file exist, delete it
if _, err := nsExec.Execute("ls", []string{filePath}); err == nil {
if _, err := nsExec.Execute("rm", []string{filePath}); err != nil {
err = errors.Wrapf(err, "error deleting disk cfg file %v on host", filePath)
}
}
return err
}
func ExpandFileSystem(volumeName string) (err error) {
devicePath := filepath.Join(DeviceDirectory, volumeName)
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return err
}
fsType, err := DetectFileSystem(volumeName)
if err != nil {
return err
}
if !IsSupportedFileSystem(fsType) {
return fmt.Errorf("volume %v is using unsupported file system %v", volumeName, fsType)
}
// make sure there is a mount point for the volume before file system expansion
tmpMountNeeded := true
mountPoint := ""
mountRes, err := nsExec.Execute("bash", []string{"-c", "mount | grep \"/" + volumeName + " \" | awk '{print $3}'"})
if err != nil {
logrus.Warnf("failed to use command mount to get the mount info of volume %v, consider the volume as unmounted: %v", volumeName, err)
} else {
// For empty `mountRes`, `mountPoints` is [""]
mountPoints := strings.Split(strings.TrimSpace(mountRes), "\n")
if !(len(mountPoints) == 1 && strings.TrimSpace(mountPoints[0]) == "") {
// pick up a random mount point
for _, m := range mountPoints {
mountPoint = strings.TrimSpace(m)
if mountPoint != "" {
tmpMountNeeded = false
break
}
}
if tmpMountNeeded {
logrus.Errorf("BUG: Found mount point records %v for volume %v but there is no valid(non-empty) mount point", mountRes, volumeName)
}
}
}
if tmpMountNeeded {
mountPoint = filepath.Join(TemporaryMountPointDirectory, volumeName)
logrus.Infof("The volume %v is unmounted, hence it will be temporarily mounted on %v for file system expansion", volumeName, mountPoint)
if _, err := nsExec.Execute("mkdir", []string{"-p", mountPoint}); err != nil {
return errors.Wrapf(err, "failed to create a temporary mount point %v before file system expansion", mountPoint)
}
if _, err := nsExec.Execute("mount", []string{devicePath, mountPoint}); err != nil {
return errors.Wrapf(err, "failed to temporarily mount volume %v on %v before file system expansion", volumeName, mountPoint)
}
}
switch fsType {
case "ext2":
fallthrough
case "ext3":
fallthrough
case "ext4":
if _, err = nsExec.Execute("resize2fs", []string{devicePath}); err != nil {
return err
}
case "xfs":
if _, err = nsExec.Execute("xfs_growfs", []string{mountPoint}); err != nil {
return err
}
default:
return fmt.Errorf("volume %v is using unsupported file system %v", volumeName, fsType)
}
// cleanup
if tmpMountNeeded {
if _, err := nsExec.Execute("umount", []string{mountPoint}); err != nil {
return errors.Wrapf(err, "failed to unmount volume %v on the temporary mount point %v after file system expansion", volumeName, mountPoint)
}
if _, err := nsExec.Execute("rm", []string{"-r", mountPoint}); err != nil {
return errors.Wrapf(err, "failed to remove the temporary mount point %v after file system expansion", mountPoint)
}
}
return nil
}
func DetectFileSystem(volumeName string) (string, error) {
devicePath := filepath.Join(DeviceDirectory, volumeName)
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return "", err
}
// The output schema of `blkid` can be different.
// For filesystem `btrfs`, the schema is: `<device path>: UUID="<filesystem UUID>" UUID_SUB="<filesystem UUID_SUB>" TYPE="<filesystem type>"`
// For filesystem `ext4` or `xfs`, the schema is: `<device path>: UUID="<filesystem UUID>" TYPE="<filesystem type>"`
cmd := fmt.Sprintf("blkid %s | sed 's/.*TYPE=//g'", devicePath)
output, err := nsExec.Execute("bash", []string{"-c", cmd})
if err != nil {
return "", errors.Wrapf(err, "failed to get the file system info for volume %v, maybe there is no Linux file system on the volume", volumeName)
}
fsType := strings.Trim(strings.TrimSpace(output), "\"")
if fsType == "" {
return "", fmt.Errorf("cannot get the filesystem type by using the command %v", cmd)
}
return fsType, nil
}
func GetDiskConfig(path string) (*DiskConfig, error) {
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return nil, err
}
filePath := filepath.Join(path, DiskConfigFile)
output, err := nsExec.Execute("cat", []string{filePath})
if err != nil {
return nil, fmt.Errorf("cannot find config file %v on host: %v", filePath, err)
}
cfg := &DiskConfig{}
if err := json.Unmarshal([]byte(output), cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal %v content %v on host: %v", filePath, output, err)
}
return cfg, nil
}
func GenerateDiskConfig(path string) (*DiskConfig, error) {
cfg := &DiskConfig{
DiskUUID: UUID(),
}
encoded, err := json.Marshal(cfg)
if err != nil {
return nil, fmt.Errorf("BUG: Cannot marshal %+v: %v", cfg, err)
}
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return nil, err
}
filePath := filepath.Join(path, DiskConfigFile)
if _, err := nsExec.Execute("ls", []string{filePath}); err == nil {
return nil, fmt.Errorf("disk cfg on %v exists, cannot override", filePath)
}
defer func() {
if err != nil {
if derr := DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(nsExec, path); derr != nil {
err = errors.Wrapf(err, "cleaning up disk config path %v failed with error: %v", path, derr)
}
}
}()
if _, err := nsExec.ExecuteWithStdin("dd", []string{"of=" + filePath}, string(encoded)); err != nil {
return nil, fmt.Errorf("cannot write to disk cfg on %v: %v", filePath, err)
}
if err := CreateDiskPathReplicaSubdirectory(path); err != nil {
return nil, err
}
if _, err := nsExec.Execute("sync", []string{filePath}); err != nil {
return nil, fmt.Errorf("cannot sync disk cfg on %v: %v", filePath, err)
}
return cfg, nil
}

View File

@@ -0,0 +1,39 @@
// +build windows
package util
import (
"github.com/pkg/errors"
)
func GetDiskInfo(directory string) (*DiskInfo, error) {
return nil, errors.Errorf("cannot get disk info of directory %v", directory)
}
func RemoveHostDirectoryContent(directory string) error {
return errors.Errorf("failed to remove host directory %v", directory)
}
func CopyHostDirectoryContent(src, dest string) error {
return errors.Errorf("failed to copy the content from %v to %v for the host", src, dest)
}
func CreateDiskPathReplicaSubdirectory(path string) error {
return errors.Errorf("error creating data path %v on host", path)
}
func ExpandFileSystem(volumeName string) error {
return errors.Errorf("error expanding filsystem on %v", volumeName)
}
func DetectFileSystem(volumeName string) (string, error) {
return "", errors.Errorf("error detecting filsystem on %v", volumeName)
}
func GetDiskConfig(path string) (*DiskConfig, error) {
return nil, errors.Errorf("error getting disk config from %v", path)
}
func GenerateDiskConfig(path string) (*DiskConfig, error) {
return nil, errors.Errorf("error generating disk config from %v", path)
}

View File

@@ -4,7 +4,6 @@ import (
"bytes"
"crypto/sha512"
"encoding/hex"
"encoding/json"
"fmt"
"hash/fnv"
"io"
@@ -15,7 +14,6 @@ import (
"os"
"os/exec"
"os/signal"
"path/filepath"
"reflect"
"regexp"
"sort"
@@ -38,8 +36,6 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/version"
clientset "k8s.io/client-go/kubernetes"
iscsi_util "github.com/longhorn/go-iscsi-helper/util"
)
const (
@@ -407,30 +403,6 @@ func CheckBackupType(backupTarget string) (string, error) {
return u.Scheme, nil
}
func GetDiskInfo(directory string) (info *DiskInfo, err error) {
defer func() {
err = errors.Wrapf(err, "cannot get disk info of directory %v", directory)
}()
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath)
output, err := Execute([]string{}, "nsenter", mountPath, "stat", "-fc", "{\"path\":\"%n\",\"fsid\":\"%i\",\"type\":\"%T\",\"freeBlock\":%f,\"totalBlock\":%b,\"blockSize\":%S}", directory)
if err != nil {
return nil, err
}
output = strings.Replace(output, "\n", "", -1)
diskInfo := &DiskInfo{}
err = json.Unmarshal([]byte(output), diskInfo)
if err != nil {
return nil, err
}
diskInfo.StorageMaximum = diskInfo.TotalBlock * diskInfo.BlockSize
diskInfo.StorageAvailable = diskInfo.FreeBlock * diskInfo.BlockSize
return diskInfo, nil
}
func RetryOnConflictCause(fn func() (interface{}, error)) (interface{}, error) {
return RetryOnErrorCondition(fn, apierrors.IsConflict)
}
@@ -461,73 +433,6 @@ func RunAsync(wg *sync.WaitGroup, f func()) {
}()
}
func RemoveHostDirectoryContent(directory string) (err error) {
defer func() {
err = errors.Wrapf(err, "failed to remove host directory %v", directory)
}()
dir, err := filepath.Abs(filepath.Clean(directory))
if err != nil {
return err
}
if strings.Count(dir, "/") < 2 {
return fmt.Errorf("prohibit removing the top level of directory %v", dir)
}
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(initiatorNSPath)
if err != nil {
return err
}
// check if the directory already deleted
if _, err := nsExec.Execute("ls", []string{dir}); err != nil {
logrus.Warnf("cannot find host directory %v for removal", dir)
return nil
}
if _, err := nsExec.Execute("rm", []string{"-rf", dir}); err != nil {
return err
}
return nil
}
func CopyHostDirectoryContent(src, dest string) (err error) {
defer func() {
err = errors.Wrapf(err, "failed to copy the content from %v to %v for the host", src, dest)
}()
srcDir, err := filepath.Abs(filepath.Clean(src))
if err != nil {
return err
}
destDir, err := filepath.Abs(filepath.Clean(dest))
if err != nil {
return err
}
if strings.Count(srcDir, "/") < 2 || strings.Count(destDir, "/") < 2 {
return fmt.Errorf("prohibit copying the content for the top level of directory %v or %v", srcDir, destDir)
}
initiatorNSPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(initiatorNSPath)
if err != nil {
return err
}
// There can be no src directory, hence returning nil is fine.
if _, err := nsExec.Execute("bash", []string{"-c", fmt.Sprintf("ls %s", filepath.Join(srcDir, "*"))}); err != nil {
logrus.Infof("cannot list the content of the src directory %v for the copy, will do nothing: %v", srcDir, err)
return nil
}
// Check if the dest directory exists.
if _, err := nsExec.Execute("mkdir", []string{"-p", destDir}); err != nil {
return err
}
// The flag `-n` means not overwriting an existing file.
if _, err := nsExec.Execute("bash", []string{"-c", fmt.Sprintf("cp -an %s %s", filepath.Join(srcDir, "*"), destDir)}); err != nil {
return err
}
return nil
}
type filteredLoggingHandler struct {
filteredPaths map[string]struct{}
handler http.Handler
@@ -596,43 +501,6 @@ func ValidateTags(inputTags []string) ([]string, error) {
return tags, nil
}
func CreateDiskPathReplicaSubdirectory(path string) error {
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return err
}
if _, err := nsExec.Execute("mkdir", []string{"-p", filepath.Join(path, ReplicaDirectory)}); err != nil {
return errors.Wrapf(err, "error creating data path %v on host", path)
}
return nil
}
func DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(
nsExec *iscsi_util.NamespaceExecutor, path string) error {
var err error
dirPath := filepath.Join(path, ReplicaDirectory)
filePath := filepath.Join(path, DiskConfigFile)
// Check if the replica directory exist, delete it
if _, err := nsExec.Execute("ls", []string{dirPath}); err == nil {
if _, err := nsExec.Execute("rmdir", []string{dirPath}); err != nil {
return errors.Wrapf(err, "error deleting data path %v on host", path)
}
}
// Check if the disk cfg file exist, delete it
if _, err := nsExec.Execute("ls", []string{filePath}); err == nil {
if _, err := nsExec.Execute("rm", []string{filePath}); err != nil {
err = errors.Wrapf(err, "error deleting disk cfg file %v on host", filePath)
}
}
return err
}
func IsKubernetesDefaultToleration(toleration v1.Toleration) bool {
if strings.Contains(toleration.Key, DefaultKubernetesTolerationKey) {
return true
@@ -693,109 +561,6 @@ func GetTolerationChecksum(t v1.Toleration) string {
return GetStringChecksum(string(t.Key) + string(t.Operator) + string(t.Value) + string(t.Effect))
}
func ExpandFileSystem(volumeName string) (err error) {
devicePath := filepath.Join(DeviceDirectory, volumeName)
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return err
}
fsType, err := DetectFileSystem(volumeName)
if err != nil {
return err
}
if !IsSupportedFileSystem(fsType) {
return fmt.Errorf("volume %v is using unsupported file system %v", volumeName, fsType)
}
// make sure there is a mount point for the volume before file system expansion
tmpMountNeeded := true
mountPoint := ""
mountRes, err := nsExec.Execute("bash", []string{"-c", "mount | grep \"/" + volumeName + " \" | awk '{print $3}'"})
if err != nil {
logrus.Warnf("failed to use command mount to get the mount info of volume %v, consider the volume as unmounted: %v", volumeName, err)
} else {
// For empty `mountRes`, `mountPoints` is [""]
mountPoints := strings.Split(strings.TrimSpace(mountRes), "\n")
if !(len(mountPoints) == 1 && strings.TrimSpace(mountPoints[0]) == "") {
// pick up a random mount point
for _, m := range mountPoints {
mountPoint = strings.TrimSpace(m)
if mountPoint != "" {
tmpMountNeeded = false
break
}
}
if tmpMountNeeded {
logrus.Errorf("BUG: Found mount point records %v for volume %v but there is no valid(non-empty) mount point", mountRes, volumeName)
}
}
}
if tmpMountNeeded {
mountPoint = filepath.Join(TemporaryMountPointDirectory, volumeName)
logrus.Infof("The volume %v is unmounted, hence it will be temporarily mounted on %v for file system expansion", volumeName, mountPoint)
if _, err := nsExec.Execute("mkdir", []string{"-p", mountPoint}); err != nil {
return errors.Wrapf(err, "failed to create a temporary mount point %v before file system expansion", mountPoint)
}
if _, err := nsExec.Execute("mount", []string{devicePath, mountPoint}); err != nil {
return errors.Wrapf(err, "failed to temporarily mount volume %v on %v before file system expansion", volumeName, mountPoint)
}
}
switch fsType {
case "ext2":
fallthrough
case "ext3":
fallthrough
case "ext4":
if _, err = nsExec.Execute("resize2fs", []string{devicePath}); err != nil {
return err
}
case "xfs":
if _, err = nsExec.Execute("xfs_growfs", []string{mountPoint}); err != nil {
return err
}
default:
return fmt.Errorf("volume %v is using unsupported file system %v", volumeName, fsType)
}
// cleanup
if tmpMountNeeded {
if _, err := nsExec.Execute("umount", []string{mountPoint}); err != nil {
return errors.Wrapf(err, "failed to unmount volume %v on the temporary mount point %v after file system expansion", volumeName, mountPoint)
}
if _, err := nsExec.Execute("rm", []string{"-r", mountPoint}); err != nil {
return errors.Wrapf(err, "failed to remove the temporary mount point %v after file system expansion", mountPoint)
}
}
return nil
}
func DetectFileSystem(volumeName string) (string, error) {
devicePath := filepath.Join(DeviceDirectory, volumeName)
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return "", err
}
// The output schema of `blkid` can be different.
// For filesystem `btrfs`, the schema is: `<device path>: UUID="<filesystem UUID>" UUID_SUB="<filesystem UUID_SUB>" TYPE="<filesystem type>"`
// For filesystem `ext4` or `xfs`, the schema is: `<device path>: UUID="<filesystem UUID>" TYPE="<filesystem type>"`
cmd := fmt.Sprintf("blkid %s | sed 's/.*TYPE=//g'", devicePath)
output, err := nsExec.Execute("bash", []string{"-c", cmd})
if err != nil {
return "", errors.Wrapf(err, "failed to get the file system info for volume %v, maybe there is no Linux file system on the volume", volumeName)
}
fsType := strings.Trim(strings.TrimSpace(output), "\"")
if fsType == "" {
return "", fmt.Errorf("cannot get the filesystem type by using the command %v", cmd)
}
return fsType, nil
}
func IsSupportedFileSystem(fsType string) bool {
if fsType == "ext4" || fsType == "ext3" || fsType == "ext2" || fsType == "xfs" {
return true
@@ -817,66 +582,6 @@ type DiskConfig struct {
DiskUUID string `json:"diskUUID"`
}
func GetDiskConfig(path string) (*DiskConfig, error) {
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return nil, err
}
filePath := filepath.Join(path, DiskConfigFile)
output, err := nsExec.Execute("cat", []string{filePath})
if err != nil {
return nil, fmt.Errorf("cannot find config file %v on host: %v", filePath, err)
}
cfg := &DiskConfig{}
if err := json.Unmarshal([]byte(output), cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal %v content %v on host: %v", filePath, output, err)
}
return cfg, nil
}
func GenerateDiskConfig(path string) (*DiskConfig, error) {
cfg := &DiskConfig{
DiskUUID: UUID(),
}
encoded, err := json.Marshal(cfg)
if err != nil {
return nil, fmt.Errorf("BUG: Cannot marshal %+v: %v", cfg, err)
}
nsPath := iscsi_util.GetHostNamespacePath(HostProcPath)
nsExec, err := iscsi_util.NewNamespaceExecutor(nsPath)
if err != nil {
return nil, err
}
filePath := filepath.Join(path, DiskConfigFile)
if _, err := nsExec.Execute("ls", []string{filePath}); err == nil {
return nil, fmt.Errorf("disk cfg on %v exists, cannot override", filePath)
}
defer func() {
if err != nil {
if derr := DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(nsExec, path); derr != nil {
err = errors.Wrapf(err, "cleaning up disk config path %v failed with error: %v", path, derr)
}
}
}()
if _, err := nsExec.ExecuteWithStdin("dd", []string{"of=" + filePath}, string(encoded)); err != nil {
return nil, fmt.Errorf("cannot write to disk cfg on %v: %v", filePath, err)
}
if err := CreateDiskPathReplicaSubdirectory(path); err != nil {
return nil, err
}
if _, err := nsExec.Execute("sync", []string{filePath}); err != nil {
return nil, fmt.Errorf("cannot sync disk cfg on %v: %v", filePath, err)
}
return cfg, nil
}
func MinInt(a, b int) int {
if a <= b {
return a