Skip to content

Commit

Permalink
-cmd option
Browse files Browse the repository at this point in the history
  • Loading branch information
abbbi committed Jan 17, 2025
1 parent 71a803a commit 90b8dbf
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ spawn throwaway systemd or non-systemd based docker containers using ssh.
sshcont:
-bind string
bind address, 127.0.0.1:2222, use :2222 for all (default "127.0.0.1:2222")
-cmd string
Execute cmd after login, example: ls
-image string
Force image to be executed
-vol string
Expand Down Expand Up @@ -38,6 +40,24 @@ ssh -l "debian:bookworm" -o StrictHostKeychecking=no localhost -p 2222
ssh -l "alpine:latest" -o StrictHostKeychecking=no localhost -p 2222
```

# Executing scripts for CI testing

Currently it is not possible to specify a command for the ssh session, but the
`cmd` option can be used to execute an specified command within the container
for CI testing. Example:

```
cat /tmp/ci/test.sh
#!/bin/bash
exit 1
sshcon -vol /tmp/ci:/ci -cmd /ci/test.sh
user@host: ~ $ ssh -l "debian:bookworm" -o StrictHostKeychecking=no localhost -p 2222
Connection to localhost closed.
user@host: ~ $ echo $?
1
```

# Notes:

* No authentication implemented, you should not run this on a public network
Expand Down
37 changes: 26 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io"
"log"
"os"
"strings"
"time"

"github.com/docker/docker/api/types/container"
Expand All @@ -47,19 +48,13 @@ func main() {
bindAddress := flag.String("bind", "127.0.0.1:2222", "bind address, 127.0.0.1:2222, use :2222 for all")
vol := flag.String("vol", "", "Share volume into container, example: /home/:/home_shared")
image := flag.String("image", "", "Force image to be executed")
cmd := flag.String("cmd", "", "Execute cmd after login, example: ls")
flag.Parse()

ssh.Handle(func(sess ssh.Session) {
InfoPrint("Connection from: [%s]", sess.RemoteAddr())
var defaultImage = sess.User()

if sess.RawCommand() != "" {
sess.Write([]byte("Executing single commands not supported\n"))
ErrorPrint("Exiting: command specified")
sess.Close()
return
}

if *image != "" {
InfoPrint("Overriding image with: [%s]", *image)
sess.Write([]byte("Overriding image with: [" + *image + "]\n"))
Expand Down Expand Up @@ -99,7 +94,7 @@ func main() {
CgroupnsMode: "host",
SecurityOpt: []string{"apparmor=unconfined"},
}
status, cleanup, err := dockerRun(cfg, hostcfg, sess)
status, cleanup, err := dockerRun(cfg, hostcfg, sess, *cmd)
defer cleanup()
if err != nil {
fmt.Fprintln(sess, err)
Expand Down Expand Up @@ -162,7 +157,7 @@ func waitForContainerReady(ctx context.Context, sess ssh.Session, cli *client.Cl

return fmt.Errorf("timeout waiting for container to be ready")
}
func dockerRun(cfg *container.Config, hostcfg *container.HostConfig, sess ssh.Session) (status int64, cleanup func(), err error) {
func dockerRun(cfg *container.Config, hostcfg *container.HostConfig, sess ssh.Session, cmd string) (status int, cleanup func(), err error) {
docker, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
Expand All @@ -173,6 +168,17 @@ func dockerRun(cfg *container.Config, hostcfg *container.HostConfig, sess ssh.Se

cImage := cfg.Image
InfoPrint("Image: %s", cImage)
defaultCmd := []string{"/bin/sh", "-c", "/bin/bash || /bin/sh"}

if cmd != "" {
defaultCmd = strings.Fields(cmd)
}

if sess.RawCommand() != "" {
sess.Write([]byte("not implemented, use -cmd option\n"))
return
}
InfoPrint("Executing command: %s", defaultCmd)

networkingConfig := network.NetworkingConfig{}
platformConfig := v1.Platform{
Expand Down Expand Up @@ -217,8 +223,8 @@ func dockerRun(cfg *container.Config, hostcfg *container.HostConfig, sess ssh.Se
return
}
execResp, err := docker.ContainerExecCreate(ctx, resp.ID, container.ExecOptions{
Cmd: []string{"/bin/sh", "-c", "/bin/bash || /bin/sh"},
Tty: true,
Cmd: defaultCmd,
Tty: false,
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Expand Down Expand Up @@ -267,8 +273,17 @@ func dockerRun(cfg *container.Config, hostcfg *container.HostConfig, sess ssh.Se
}
}()
}

select {
case <-outputErr:

execInspect, ierr := docker.ContainerExecInspect(ctx, execResp.ID)
if ierr != nil {
WarnPrint("Unable to inspect command exit code: %s", err.Error())
}
status = execInspect.ExitCode
InfoPrint("Exit code from specified command: %d", status)

cleanup = func() {
InfoPrint("Killing container: %s", resp.ID)
docker.ContainerKill(ctx, resp.ID, "9")
Expand Down

0 comments on commit 90b8dbf

Please sign in to comment.