Skip to content

Commit

Permalink
Add a cpuns command
Browse files Browse the repository at this point in the history
This command lets you ssh to a system with the cpu command.
You can then run this command, with or without arguments,
and it will give you a cpu environment.

A typical way to run it:
sudo -E unshare -m cpuns

The -E is important to get the SUDO_UID and SUDO_GID

Signed-off-by: Ronald G Minnich <rminnich@gmail.com>
  • Loading branch information
rminnich committed Jul 10, 2024
1 parent 564fc4e commit 017780f
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 56 deletions.
9 changes: 5 additions & 4 deletions client/fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package client
import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -111,16 +112,17 @@ func (c *Cmd) HostKeyConfig(hostKeyFile string) error {
// SetEnv sets zero or more environment variables for a Session.
// If envs is nil or a zero length slice, no variables are set.
func (c *Cmd) SetEnv(envs ...string) error {
var err error
for _, v := range envs {
env := strings.SplitN(v, "=", 2)
if len(env) == 1 {
env = append(env, "")
}
if err := c.session.Setenv(env[0], env[1]); err != nil {
return fmt.Errorf("Warning: c.session.Setenv(%q, %q): %v", v, os.Getenv(v), err)
err = errors.Join(fmt.Errorf("Warning: c.session.Setenv(%q, %q): %v", v, os.Getenv(v), err))
}
}
return nil
return err
}

// SSHStdin implements an ssh-like reader, honoring ~ commands.
Expand Down Expand Up @@ -202,8 +204,7 @@ func GetHostName(host string) string {

// GetPort gets a port. It verifies that the port fits in 16-bit space.
// The rules here are messy, since config.Get will return "22" if
// there is no entry in .ssh/config. 22 is not allowed. So in the case
// of "22", convert to defaultPort.
// there is no entry in .ssh/config.
func GetPort(host, port string) (string, error) {
p := port
verbose("getPort(%q, %q)", host, port)
Expand Down
5 changes: 1 addition & 4 deletions cmds/cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ func getHostName(host string) string {
}

// getPort gets a port.
// The rules here are messy, since config.Get will return "22" if
// there is no entry in .ssh/config. 22 is not allowed. So in the case
// of "22", convert to defaultPort
func getPort(host, port string) string {
p := port
verbose("getPort(%q, %q)", host, port)
Expand All @@ -127,7 +124,7 @@ func getPort(host, port string) string {
p = cp
}
}
if len(p) == 0 || p == "22" {
if len(p) == 0 {
p = defaultPort
verbose("getPort: return default %q", p)
}
Expand Down
7 changes: 7 additions & 0 deletions cmds/cpu/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,11 @@
// If you want to learn more read the factotum paper by Grosse et. al. and the original
// Plan 9 papers on cpu, but be aware there are many subtle details visible only
// in code.
//
// You can now tentatively talk to standard sshd.
// Here is an example:
// ./cpu -nfs=true -9p=false -d -key ~/.ssh/homemac -sp 22 127.0.0.1
// A few things: 9p has to be off, since sshd don't understand the -9 switch
// Failing to Setenv is no longer an error, so you may not be able to set things
// like SHELL.
package main
75 changes: 58 additions & 17 deletions cmds/cpuns/main_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ package main

import (
"flag"
"fmt"
"log"
"os"
"runtime"
"strconv"
"strings"
"syscall"

"github.com/moby/sys/mountinfo"
"github.com/u-root/cpu/session"
"golang.org/x/sys/unix"
)

var (
Expand All @@ -21,30 +23,38 @@ var (
v = func(string, ...interface{}) {}
)

// os.Unshare is tricky to call. Go runtime does not really handle it
// correctly; if you have muiltiple procs, it only runs for one of them.
// init functions run in single-process context, or so we understand ...
func init() {
m := runtime.GOMAXPROCS(1)
if err := syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
log.Fatalf("can not run if unshare fails: %v", err)
}
if err := unix.Mount("", "/", "", syscall.MS_REC|syscall.MS_PRIVATE, ""); err != nil {
log.Fatalf(`unix.Mount("", "/", "", syscall.MS_REC|syscall.MS_PRIVATE, ""); %v`, err)
}
runtime.GOMAXPROCS(m)
}

func verbose(f string, a ...interface{}) {
v("CPUNS:"+f, a...)
}

func checkprivate() error {
mnts, err := mountinfo.GetMounts(mountinfo.SingleEntryFilter("/"))
if err != nil {
return err
}
if len(mnts) != 1 {
return fmt.Errorf("got more than 1 mount for /(%v):%v", mnts, os.ErrInvalid)
}
entry := mnts[0]
fmt.Printf("Optional is %q\n", entry.Optional)
isShared := strings.Contains(entry.Optional, "shared:1")
if isShared {
return fmt.Errorf("/ is not private")
}
return nil
}

func main() {
fmt.Printf("uid %v git %v", os.Getuid(), os.Getgid())
if err := checkprivate(); err != nil {
log.Fatal(err)
}
flag.CommandLine = flag.NewFlagSet("cpuns", flag.ExitOnError)
debug := flag.Bool("d", false, "enable debug prints")
flag.Parse()
if *debug {
v = log.Printf
session.SetVerbose(v)
}
args := flag.Args()
shell := "/bin/sh"
Expand All @@ -60,7 +70,38 @@ func main() {
// good way to pass it (it is passed as as switch in cpud).
// That is ok, 9p has never been that good on Linux.
s := session.New("", args[0], args[1:]...)
if err := s.Run(); err != nil {
if err := s.NameSpace(); err != nil {
log.Fatalf("CPUD(remote): %v", err)
}

if err := s.Terminal(); err != nil {
log.Printf("s.Terminal failed(%v); continuing anyway", err)
}

u, ok := os.LookupEnv("SUDO_UID")
if !ok {
log.Printf("no SUDO_UID; continuing anyway")
}
g, ok := os.LookupEnv("SUDO_GID")
if !ok {
log.Printf("no SUDO_GID; continuing anyway")
}

uid, err := strconv.Atoi(u)
if err != nil {
log.Fatal(err)
}

gid, err := strconv.Atoi(g)
if err != nil {
log.Fatal(err)
}
c := s.Command()
c.Stdin, c.Stdout, c.Stderr = s.Stdin, s.Stdout, s.Stderr
c.SysProcAttr = &syscall.SysProcAttr{}
c.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}

Check failure

Code scanning / CodeQL

Incorrect conversion between integer types High

Incorrect conversion of an integer with architecture-dependent bit size from
strconv.Atoi
to a lower bit size type uint32 without an upper bound check.

Check failure

Code scanning / CodeQL

Incorrect conversion between integer types High

Incorrect conversion of an integer with architecture-dependent bit size from
strconv.Atoi
to a lower bit size type uint32 without an upper bound check.
if err := c.Run(); err != nil {
log.Fatalf("Run %v returns %v", c, err)
}

}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/go-git/go-billy/v5 v5.5.1-0.20240514075308-8f1b719cb6a2
github.com/google/uuid v1.5.0
github.com/mdlayher/vsock v1.2.1
github.com/moby/sys/mountinfo v0.7.1
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/willscott/go-nfs v0.0.2
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad
Expand All @@ -35,7 +36,6 @@ require (
github.com/miekg/dns v1.1.55 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
Expand Down
30 changes: 4 additions & 26 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,19 @@ github.com/brutella/dnssd v1.2.9 h1:eUqO0qXZAMaFN4W4Ms1AAO/OtAbNoh9U87GAlN+1FCs=
github.com/brutella/dnssd v1.2.9/go.mod h1:yZ+GHHbGhtp5yJeKTnppdFGiy6OhiPoxs0WHW1KUcFA=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-billy/v5 v5.5.1-0.20240514075308-8f1b719cb6a2 h1:vWpyklHBOaIWDj1n3s/6M7rfLFDBXXbT1jrNOtBVo7Y=
github.com/go-git/go-billy/v5 v5.5.1-0.20240514075308-8f1b719cb6a2/go.mod h1:7u9KSvLbAYN7/p0U+SsuzbbMuqCAk7MYkPI8l2+71s4=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/goexpect v0.0.0-20191001010744-5b6988669ffa h1:PMkmJA8ju9DjqAJjIzrBdrmhuuPsoNnNLYgKQBopWL0=
github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2 h1:CVuJwN34x4xM2aT4sIKhmeib40NeBPhRihNjQmpJsA4=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
Expand All @@ -49,25 +43,19 @@ github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 h1:UVArwN/wkKjMVhh2EQGC0tEc1+FqiLlvYXY5mQ2f8Wg=
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93/go.mod h1:Nfe4efndBz4TibWycNE+lqyJZiMX4ycx+QKV8Ta0f/o=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
Expand All @@ -92,8 +80,6 @@ github.com/willscott/go-nfs-client v0.0.0-20240104095149-b44639837b00/go.mod h1:
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad h1:g0bG7Z4uG+OgH2QDODnjp6ggkk1bJDsINcuWmJN1iJU=
Expand All @@ -102,8 +88,6 @@ golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
Expand All @@ -114,20 +98,17 @@ golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand All @@ -139,8 +120,5 @@ golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion session/fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func verbose(f string, a ...interface{}) {
v("session:"+f, a...)
}

func runCmd(c *exec.Cmd) error {
func RunCmd(c *exec.Cmd) error {
sigChan := make(chan os.Signal, 1)
defer close(sigChan)
signal.Notify(sigChan, unix.SIGTERM, unix.SIGINT)
Expand Down
63 changes: 60 additions & 3 deletions session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (s *Session) DropPrivs() error {
uid := unix.Getuid()
verbose("dropPrives: uid is %v", uid)
if uid == 0 {
verbose("dropPrivs: not dropping privs")
verbose("dropPrivs: uid is 0: not dropping privs")
return nil
}
gid := unix.Getgid()
Expand Down Expand Up @@ -206,10 +206,10 @@ func (s *Session) Run() error {
c.Stdin, c.Stdout, c.Stderr, c.Dir = s.Stdin, s.Stdout, s.Stderr, os.Getenv("PWD")
dirInfo, err := os.Stat(c.Dir)
if err != nil || !dirInfo.IsDir() {
log.Printf("CPUD: your $PWD %s is not in the remote namespace", c.Dir)
log.Printf("CPUD: your $PWD %q is not in the remote namespace", c.Dir)
return os.ErrNotExist
}
err = runCmd(c)
err = RunCmd(c)
verbose("Run %v returns %v", c, err)
if err != nil {
if s.fail && len(wtf) != 0 {
Expand Down Expand Up @@ -237,3 +237,60 @@ func New(port9p, cmd string, args ...string) *Session {
// so we had a way out!
return &Session{msize: 64 * 1024, Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, port9p: port9p, cmd: cmd, args: args}
}

// The following two functions were set up for cpuns.
// They provide a bit more flexibility in setting things
// up until we can agree on how it should all work.
// Side note: it's probably time to remove all the
// wtf support, above; it has been years since we needed it.
// Run starts up a remote cpu session. It is started by a cpu
// daemon via a -remote switch.

// NameSpace prepares the namespace for the session.
func (s *Session) NameSpace() error {
var errs error

if err := runSetup(); err != nil {
return err
}
if err := s.TmpMounts(); err != nil {
verbose("TmpMounts error: %v", err)
s.fail = true
errs = errors.Join(errs, err)
}

verbose("call s.NameSpace")
err := s.Namespace()
if err != nil {
return errors.Join(errs, fmt.Errorf("CPUD:Namespace: %v", err))
}

// The CPU_FSTAB environment variable is, literally, an fstab.
// Why an environment variable and not a file? We do not
// want to require any 9p mounts at all. People should be able
// to do this:
// CPU_FSTAB=`cat fstab`
// and get the mounts they want. The first uses of this will
// be building namespaces with drive and virtiofs.

// In some cases if you set LD_LIBRARY_PATH it is ignored.
// This is disappointing to say the least. We just bind a few things into /
// bind *may* hide local resources but for now it's the least worst option.
if tab, ok := os.LookupEnv("CPU_FSTAB"); ok {
verbose("Mounting %q", tab)
if err := mount.Mount(tab); err != nil {
verbose("fstab mount failure: %v", err)
// Should we die if the mounts fail? For now, we think not;
// the user may be able to debug. Just record that it failed.
s.fail = true
}
}

return nil
}

// Command returns an exec.Command that users can additionally modify.
// This will all certainly change.
func (s *Session) Command() *exec.Cmd {
return exec.Command(s.cmd, s.args...)
}

0 comments on commit 017780f

Please sign in to comment.