Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ns related funcs #80

Merged
merged 3 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/scripts/upgrade_ndm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ target_img=$(yq -e .image.repository ndm-override.yaml)
echo "upgrade target image: ${target_img}, upgrading ..."
$HELM upgrade -f $TOP_DIR/ndm-override.yaml harvester-node-disk-manager harvester-node-disk-manager/ -n harvester-system

sleep 10 # wait 10 seconds for ndm start to respwan pods
sleep 30 # wait 30 seconds for ndm respwan pods

wait_ndm_ready
# check image
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ require (
github.com/harvester/go-common v0.0.0-20231214093547-3e3f7fdd879a
github.com/jaypipes/ghw v0.8.1-0.20210701154532-dd036bd38c40
github.com/kevinburke/ssh_config v1.2.0
github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7
github.com/longhorn/longhorn-manager v1.5.3
github.com/melbahja/goph v1.3.0
github.com/pilebones/go-udev v0.0.0-20210126000448-a3c2a7a4afb7
github.com/pkg/errors v0.9.1
github.com/prometheus/procfs v0.9.0
github.com/rancher/lasso v0.0.0-20221227210133-6ea88ca2fbcc
github.com/rancher/wrangler v1.1.1
github.com/sirupsen/logrus v1.9.3
Expand Down Expand Up @@ -84,18 +85,17 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.15.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.14.0 // indirect
Expand Down
3 changes: 1 addition & 2 deletions pkg/block/block_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/jaypipes/ghw/pkg/linuxpath"
"github.com/jaypipes/ghw/pkg/option"
"github.com/jaypipes/ghw/pkg/util"
iscsiutil "github.com/longhorn/go-iscsi-helper/util"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/blake2b"

Expand Down Expand Up @@ -493,7 +492,7 @@ func partitionInfo(ctx *context.Context, paths *linuxpath.Paths, part string) (s
func openProcMounts(ctx *context.Context, paths *linuxpath.Paths) (*os.File, error) {
file := paths.ProcMounts
if path, ok := ctx.PathOverrides[ndmutils.ProcPath]; ok {
ns := iscsiutil.GetHostNamespacePath(path)
ns := ndmutils.GetHostNamespacePath(path)
file = strings.TrimSuffix(ns, "ns/") + "mounts"
}
return os.Open(file)
Expand Down
83 changes: 83 additions & 0 deletions pkg/utils/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package utils

import (
"bytes"
"os/exec"
"path/filepath"
"time"

"github.com/pkg/errors"
)

const (
NSBinary = "nsenter"
cmdTimeoutDefault = 180 * time.Second // 3 minutes by default
cmdTimeoutNone = 0 * time.Second // no timeout
)

type Executor struct {
namespace string
cmdTimeout time.Duration
}

func NewExecutor() *Executor {
return &Executor{
namespace: "",
cmdTimeout: cmdTimeoutDefault,
}
}

func NewExecutorWithNS(ns string) (*Executor, error) {
exec := NewExecutor()
exec.namespace = ns
Vicente-Cheng marked this conversation as resolved.
Show resolved Hide resolved

// test if nsenter is available
if _, err := execute(NSBinary, []string{"-V"}, cmdTimeoutNone); err != nil {
return nil, errors.Wrap(err, "cannot find nsenter for namespace switching")
}
return exec, nil
}

func (exec *Executor) SetTimeout(timeout time.Duration) {
exec.cmdTimeout = timeout
}

func (exec *Executor) Execute(cmd string, args []string) (string, error) {
command := cmd
cmdArgs := args
if exec.namespace != "" {
cmdArgs = []string{
"--mount=" + filepath.Join(exec.namespace, "mnt"),
"--net=" + filepath.Join(exec.namespace, "net"),
"--ipc=" + filepath.Join(exec.namespace, "ipc"),
cmd,
}
command = NSBinary
cmdArgs = append(cmdArgs, args...)
}
return execute(command, cmdArgs, exec.cmdTimeout)
}

func execute(command string, args []string, timeout time.Duration) (string, error) {
cmd := exec.Command(command, args...)

var output, stderr bytes.Buffer
cmd.Stdout = &output
cmd.Stderr = &stderr

timer := time.NewTimer(cmdTimeoutNone)
if timeout != cmdTimeoutNone {
// add timer to kill the process if timeout
timer = time.AfterFunc(timeout, func() {
cmd.Process.Kill()
})
}
defer timer.Stop()

if err := cmd.Run(); err != nil {
return "", errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s",
command, args, output.String(), stderr.String())
}

return output.String(), nil
}
Vicente-Cheng marked this conversation as resolved.
Show resolved Hide resolved
73 changes: 73 additions & 0 deletions pkg/utils/process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package utils

import (
"fmt"

"github.com/prometheus/procfs"
)

const (
DockerdProcess = "dockerd"
ContainerdProcess = "containerd"
ContainerdProcessShim = "containerd-shim"
)

func getPidProc(hostProcPath string, pid int) (*procfs.Proc, error) {
fs, err := procfs.NewFS(hostProcPath)
if err != nil {
return nil, err
}
proc, err := fs.Proc(pid)
if err != nil {
return nil, err
}
return &proc, nil
}

func getSelfProc(hostProcPath string) (*procfs.Proc, error) {
fs, err := procfs.NewFS(hostProcPath)
if err != nil {
return nil, err
}
proc, err := fs.Self()
if err != nil {
return nil, err
}
return &proc, nil
}

func findAncestorByName(hostProcPath string, ancestorProcess string) (*procfs.Proc, error) {
proc, err := getSelfProc(hostProcPath)
if err != nil {
return nil, err
}

for {
st, err := proc.Stat()
if err != nil {
return nil, err
}
if st.Comm == ancestorProcess {
return proc, nil
}
if st.PPID == 0 {
break
}
proc, err = getPidProc(hostProcPath, st.PPID)
if err != nil {
return nil, err
}
}
return nil, fmt.Errorf("failed to find the ancestor process: %s", ancestorProcess)
}

func GetHostNamespacePath(hostProcPath string) string {
containerNames := []string{DockerdProcess, ContainerdProcess, ContainerdProcessShim}
for _, name := range containerNames {
proc, err := findAncestorByName(hostProcPath, name)
if err == nil {
return fmt.Sprintf("%s/%d/ns/", hostProcPath, proc.PID)
}
}
return fmt.Sprintf("%s/%d/ns/", hostProcPath, 1)
}
9 changes: 4 additions & 5 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"sync"
"syscall"

iscsiutil "github.com/longhorn/go-iscsi-helper/util"
"github.com/longhorn/longhorn-manager/util"
)

Expand Down Expand Up @@ -134,8 +133,8 @@ func mountExt4(device, path string, readonly bool) error {

// mountExt4OnHostNamespace provides the same functionality as mountExt4 but on host namespace.
func mountExt4OnHostNamespace(device, path string, readonly bool) error {
ns := iscsiutil.GetHostNamespacePath(util.HostProcPath)
executor, err := iscsiutil.NewNamespaceExecutor(ns)
ns := GetHostNamespacePath(util.HostProcPath)
executor, err := NewExecutorWithNS(ns)
if err != nil {
return err
}
Expand All @@ -150,8 +149,8 @@ func mountExt4OnHostNamespace(device, path string, readonly bool) error {
}

func executeOnHostNamespace(cmd string, args []string) (string, error) {
ns := iscsiutil.GetHostNamespacePath(util.HostProcPath)
executor, err := iscsiutil.NewNamespaceExecutor(ns)
ns := GetHostNamespacePath(util.HostProcPath)
executor, err := NewExecutorWithNS(ns)
if err != nil {
return "", err
}
Expand Down
Loading