Skip to content

Commit

Permalink
feat: multi delete and namespace array
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmetozer committed Jun 29, 2024
1 parent 3501209 commit 2f70770
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 58 deletions.
8 changes: 6 additions & 2 deletions pkg/cmd/clear.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"log"

"github.com/ahmetozer/sandal/pkg/config"
"github.com/ahmetozer/sandal/pkg/container"
)
Expand All @@ -11,9 +13,11 @@ func clear(args []string) error {
if !c.Remove {
continue
}
if !container.IsRunning(&c) {
deRunContainer(&c)
if container.IsRunning(&c) {
log.Printf("container %s is running, %v", c.Name, c.Remove)
continue
}
deRunContainer(&c)
}
return nil
}
4 changes: 2 additions & 2 deletions pkg/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ case "$1" in
restart)
log_daemon_msg "Restarting Sandal" "sandal" || true
start-stop-daemon --stop --background -m --quiet --oknodo --retry 30 --pidfile /run/sandal.pid --exec /bin/sandal
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /run/sandal.pid --exec /bin/sandal
# shellcheck disable=SC2086
if start-stop-daemon --start --quiet --oknodo --chuid 0:0 --pidfile /run/sandal.pid --exec /bin/sandal -- $SANDAL_OPTS; then
if start-stop-daemon --start --background -m --quiet --oknodo --chuid 0:0 --pidfile /run/sandal.pid --exec /bin/sandal -- $SANDAL_OPTS; then
log_end_msg 0 || true
else
log_end_msg 1 || true
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,6 @@ func printDry(c *config.Config, t *tabwriter.Writer) {
}

func printNamespaces(c *config.Config, t *tabwriter.Writer) {
fmt.Fprintf(t, "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", c.Name, c.ContPid, c.NS.Cgroup, c.NS.Ipc, c.NS.Mnt, c.NS.Net, c.NS.Pid, c.NS.User, c.NS.Uts)

fmt.Fprintf(t, "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", c.Name, c.ContPid, c.NS["cgroup"].Value, c.NS["ipc"].Value, c.NS["mnt"].Value, c.NS["net"].Value, c.NS["pid"].Value, c.NS["user"].Value, c.NS["uts"].Value)
}
35 changes: 22 additions & 13 deletions pkg/cmd/rm.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"errors"
"flag"
"fmt"

Expand All @@ -22,20 +23,28 @@ func rm(args []string) error {
flags.Parse(thisFlags)

conts, _ := config.AllContainers()
for _, c := range conts {
if c.Name == args[0] {
err := container.CheckExistence(&c)
if err != nil {
return fmt.Errorf("unable to check existence of '%s' container: %v", c.Name, err)
}
if c.Status == container.ContainerStatusRunning {
return fmt.Errorf("container %s is running, please stop it first", c.Name)
}

c.Remove = true
deRunContainer(&c)
var errs []error
RequestedContainers:
for _, name := range args {
for _, c := range conts {
if c.Name == name {
err := container.CheckExistence(&c)
if err != nil {
errs = append(errs, fmt.Errorf("unable to check existence of '%s' container: %v", c.Name, err))
}
if c.Status == container.ContainerStatusRunning {
errs = append(errs, fmt.Errorf("container %s is running, please stop it first", c.Name))
}

c.Remove = true
deRunContainer(&c)
continue RequestedContainers
}
}
errs = append(errs, fmt.Errorf("container %s is not found", name))
}
if len(errs) > 0 {
return errors.Join(errs...)
}
return fmt.Errorf("container %s is not found", args[0])
return nil
}
15 changes: 9 additions & 6 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ func run(args []string) error {
f.StringVar(&c.Resolv, "resolv", "cp", "cp (copy), cp-n (copy if not exist), image (use image), 1.1.1.1;2606:4700:4700::1111 (provide nameservers)")
f.StringVar(&c.Hosts, "hosts", "cp", "cp (copy), cp-n (copy if not exist), image(use image)")

f.StringVar(&c.NS.Net, "ns-net", "", "net namespace or host")
f.StringVar(&c.NS.Pid, "ns-pid", "", "pid namespace or host")
f.StringVar(&c.NS.Uts, "ns-uts", "", "uts namespace or host")
f.StringVar(&c.NS.User, "ns-user", "host", "user namespace or host")
for _, k := range config.Namespaces {
defaultValue := ""
if k == "user" {
defaultValue = "host"
}
f.StringVar(&c.NS[k].Value, "ns-"+k, defaultValue, fmt.Sprintf("%s namespace or host", k))
}

f.StringVar(&c.ChangeDir, "chd", "", "changes save location default /var/lib/sandal/containers/<name>/changes")

Expand Down Expand Up @@ -115,7 +118,7 @@ func run(args []string) error {
func Start(c *config.Config, HostIface, PodIface config.NetIface) error {
// Starting container
var err error
if c.NS.Net != "host" {
if c.NS["net"].Value != "host" {

if HostIface.Type == "bridge" {
err = net.CreateIface(c, &HostIface)
Expand Down Expand Up @@ -159,7 +162,7 @@ func deRunContainer(c *config.Config) {
slog.Debug("umount", slog.String("err", e.Error()))
}
}
if c.NS.Net != "host" {
if c.NS["net"].Value != "host" {
net.Clear(c)
}

Expand Down
24 changes: 11 additions & 13 deletions pkg/config/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@ import (
"time"
)

type NS struct {
Net string
Pid string
Uts string
User string
Ipc string
Cgroup string
NS string
Mnt string
Time string
}

type ALocFor uint8

const (
Expand Down Expand Up @@ -50,6 +38,10 @@ func (f *StringFlags) Set(value string) error {
return nil
}

type StringWrapper struct {
Value string
}

type Config struct {
Name string

Expand All @@ -66,7 +58,7 @@ type Config struct {
EnvAll bool
Background bool
Startup bool
NS NS
NS map[string]*StringWrapper
ChangeDir string
Exec string
Devtmpfs string
Expand All @@ -89,11 +81,17 @@ var (
TypeUint uint
)

var Namespaces []string = []string{"pid", "net", "user", "uts", "ipc", "cgroup", "mnt", "time", "ns"}

func NewContainer() Config {
Config := Config{}
Config.HostPid = os.Getpid()
Config.Created = time.Now().UTC().Unix()
Config.Ifaces = []NetIface{{ALocFor: ALocForHost}}
Config.NS = make(map[string]*StringWrapper, len(Namespaces))
for _, ns := range Namespaces {
Config.NS[ns] = &StringWrapper{Value: ""}
}
return Config
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/container/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ func Exec() {
log.Fatalf("unable to set hostname %s", err)
}

configureIfaces(&c)
if c.NS["net"].Value != "host" {
configureIfaces(&c)
}

childSysMounts(&c)
childSysNodes(&c)
Expand All @@ -43,7 +45,7 @@ func Exec() {

func loadConfig() (config.Config, error) {

config := config.Config{}
config := config.NewContainer()
confFileLoc := os.Getenv(CHILD_CONFIG_ENV_NAME)
if confFileLoc == "" {
return config, fmt.Errorf("config file location not present in env")
Expand Down
4 changes: 2 additions & 2 deletions pkg/container/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ func childSysMounts(c *config.Config) {

mount("proc", "/proc", "proc", unix.MS_NOSUID|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_RELATIME, "")

mount("cgroup", "/sys/fs/cgroup", "cgroup2", unix.MS_NOSUID|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_RELATIME, "nsdelegate,memory_recursiveprot")

if c.Devtmpfs != "/dev" {
mount("tmpfs", "/dev", "tmpfs", unix.MS_RELATIME, "size=65536k,mode=755")
}
Expand All @@ -53,6 +51,8 @@ func childSysMounts(c *config.Config) {

mount("sysfs", "/sys", "sysfs", unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_RELATIME, "ro")

mount("cgroup2", "/sys/fs/cgroup", "cgroup2", unix.MS_NOSUID|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_RELATIME, "nsdelegate,memory_recursiveprot")

mount("devpts", "/dev/pts", "devpts", unix.MS_NOSUID|unix.MS_NOEXEC|unix.MS_RELATIME, "gid=5,mode=620,ptmxmode=666")

mount("shm", "/dev/shm", "tmpfs", unix.MS_NOSUID|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_RELATIME, "size=64000k")
Expand Down
28 changes: 12 additions & 16 deletions pkg/container/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,24 @@ func Start(c *config.Config, args []string) (int, error) {

var cmdFlags uintptr = syscall.CLONE_NEWNS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWCGROUP

if c.NS.Pid != "host" {
if c.NS["pid"].Value != "host" {
cmdFlags |= syscall.CLONE_NEWPID
}
if c.NS.Net != "host" {
if c.NS["net"].Value != "host" {
cmdFlags |= syscall.CLONE_NEWNET
}
if c.NS.User != "host" {
if c.NS["user"].Value != "host" {
cmdFlags |= syscall.CLONE_NEWUSER
}
if c.NS.Uts != "host" {
if c.NS["uts"].Value != "host" {
cmdFlags |= syscall.CLONE_NEWUTS
}

cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: cmdFlags,
}

if c.NS.User != "host" && c.NS.Pid != "host" {
if c.NS["user"].Value != "host" && c.NS["pid"].Value != "host" {
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: cmdFlags,
UidMappings: []syscall.SysProcIDMap{
Expand All @@ -80,6 +80,7 @@ func Start(c *config.Config, args []string) (int, error) {
c.SaveConftoDisk()

err := cmd.Start()

if err != nil {
return 0, fmt.Errorf("starting container: %v", err)
}
Expand Down Expand Up @@ -146,16 +147,12 @@ func childArgs(args []string) (string, []string) {
}

func loadNamespaceIDs(c *config.Config) {

c.NS.Pid = readNamespace(fmt.Sprintf("/proc/%d/ns/pid", c.ContPid))
c.NS.Net = readNamespace(fmt.Sprintf("/proc/%d/ns/net", c.ContPid))
c.NS.User = readNamespace(fmt.Sprintf("/proc/%d/ns/user", c.ContPid))
c.NS.Uts = readNamespace(fmt.Sprintf("/proc/%d/ns/uts", c.ContPid))
c.NS.Ipc = readNamespace(fmt.Sprintf("/proc/%d/ns/ipc", c.ContPid))
c.NS.Cgroup = readNamespace(fmt.Sprintf("/proc/%d/ns/cgroup", c.ContPid))
c.NS.Mnt = readNamespace(fmt.Sprintf("/proc/%d/ns/mnt", c.ContPid))
c.NS.Time = readNamespace(fmt.Sprintf("/proc/%d/ns/time", c.ContPid))
c.NS.NS = readNamespace(fmt.Sprintf("/proc/%d/ns/ns", c.ContPid))
for _, ns := range config.Namespaces {
if c.NS[ns].Value == "host" {
continue
}
c.NS[ns].Value = readNamespace(fmt.Sprintf("/proc/%d/ns/%s", c.ContPid, ns))
}
}

func readNamespace(f string) string {
Expand All @@ -181,7 +178,6 @@ func parseNamspaceInfo(s string) string {
func AttachContainerToPID(c *config.Config, masterPid int) error {
if err := syscall.Setpgid(c.ContPid, masterPid); err != nil {
return fmt.Errorf("error setting %d process group id: %s", c.ContPid, err)

}

if pgid, err := syscall.Getpgid(c.ContPid); err != nil || pgid != masterPid {
Expand Down
2 changes: 1 addition & 1 deletion pkg/net/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func CreateIface(c *config.Config, iface *config.NetIface) error {
ifaceLink := netlink.Link(nil)
err := error(nil)
if c.NS.Net == "host" {
if c.NS["net"].Value == "host" {
return nil
}

Expand Down

0 comments on commit 2f70770

Please sign in to comment.