Allow for signal forwarding during exec #1830

Closed
bzeller opened this Issue Mar 30, 2016 · 12 comments

Comments

Projects
None yet
5 participants

bzeller commented Mar 30, 2016

Required information

  • Distribution: Ubuntu
  • Distribution version: Xenial
  • The output of "lxc info"
apicompat: 0
auth: trusted
environment:
  addresses: []
  architectures:
  - x86_64
  - i686
  certificate: |
    -----BEGIN CERTIFICATE-----
    .....
    -----END CERTIFICATE-----
  driver: lxc
  driverversion: 2.0.0.rc12
  kernel: Linux
  kernelarchitecture: x86_64
  kernelversion: 4.4.0-15-generic
  server: lxd
  serverpid: 2146
  serverversion: 2.0.0.rc5
  storage: zfs
  storageversion: "5"
config:
  storage.zfs_pool_name: lxd
public: false

Issue description

When running GUI applications inside a LXD container, sending SIGTERM
to the "lxc exec" PID will result in the lxc process going away but the process
inside the container will continue to run.

Steps to reproduce

  1. Enable X11 apps for a container
  2. Run any X11 app "lxc exec container -- su -l -s /bin/bash user -c "DISPLAY=:0 xeyes""
  3. send SIGTERM to the lxc exec process
  4. the lxc exec process goes away, but the GUI app will continue to run
Owner

stgraber commented Mar 30, 2016

It's not that lxc exec doesn't handle sigterm properly it's that it doesn't forward signals at all :)

We just don't support it right now and I'm not sure to what extent we can even support this given the existing go-lxc API (do we know the process PID to which we should forward the signal?)

Member

tych0 commented Mar 30, 2016

This isn't really related to it being a GUI application, it's just any application which doesn't exit when its stdin is closed. Probably the right thing to do here is receive SIGTERM in the client and cancel.

@stgraber stgraber changed the title from lxc exec does not handle SIGTERM correctly for GUI apps to Allow for signal forwarding during exec Mar 30, 2016

@stgraber stgraber added the Feature label Mar 30, 2016

@stgraber stgraber added this to the later milestone Mar 30, 2016

Contributor

jpillora commented Apr 14, 2016

Easier steps to reproduce:

  • lxc exec <id> bash
  • kill $PID_OF_LXC_EXEC
  • ps aux | grep bash bash is still running

@stgraber stgraber modified the milestones: later, soon Apr 25, 2016

@stgraber stgraber added API Easy Blocked and removed Easy labels Apr 25, 2016

Owner

stgraber commented Apr 27, 2016

Just realized that this is blocked on us having a better go-lxc API, as right now we don't get the PID of the running task and so can't send signals to it.

@stgraber stgraber modified the milestones: later, soon Apr 27, 2016

Contributor

jpillora commented May 17, 2016

@stgraber is there an alternate non-LXD command we can use to execute commands within a container?

Owner

stgraber commented May 17, 2016

@jpillora you can just run sshd and ssh into your container

Contributor

jpillora commented May 17, 2016

For security purposes, our containers have no host network access. I'm approaching a solution I think though, I'm running an agent, also written in Go, alongside LXD and so I'm directly using lxd.Client.Exec(). I usually cross compile darwin->linux for development though it appears I'm not able to cross compile the shared package. I'm currently getting around this by copying the source over for compilation. I was going to make a separate issue about this though I thought I'd ask: was the LXD client (lxc) ever meant to be cross-platform?

bzeller commented May 17, 2016

I wrote a small wrapper tool that helps me to execute applications inside the containers and send signals to them. You can check it out here :
http://bazaar.launchpad.net/~zeller-benjamin/ubuntu-sdk-tools/copyright/view/head:/usdk-wrapper/usdk-wrapper.go
It basically creates a pidfile that can be used to send signals to the process. Line 107 and following in the file.

Contributor

jpillora commented May 18, 2016

Thanks @bzeller. Since it seems the heart of the issue is that func (c *containerLXC) Exec(...) has no way to terminate the program. I'm going to try to just not use lxc exec and go with @stgraber suggestion and use ssh, though I'll need it to over a unix socket since I have no network access to containers, if that doesn't work I'll give your code a shot.

Edit: Got POC for my idea and it seems to work. Since there's no way to get SSH to listen on a unix socket, I'll use something like this to forward onto the container's port 22. This way SSH will do all the heavy lifting :)

root@container123:~# ./sockfwd
2016/04/22 19:05:20 listening on /tmp/fwd.sock
2016/04/22 19:05:31 connected to 127.0.0.1:22
root@host:~# socat - UNIX-CONNECT:/var/lib/lxd/containers/container123/rootfs/tmp/fwd.sock
SSH-2.0-OpenSSH_6.9p1 Ubuntu-2ubuntu0.1

Next step is to dial in with https://godoc.org/golang.org/x/crypto/ssh and I'll have my programmatic control from there

Edit: This is now working well :) I released my small socket forwarding program here https://github.com/jpillora/sockfwd and it is running in the containers I need SSH access to

@stgraber stgraber modified the milestones: later, soon Oct 4, 2016

@stgraber stgraber modified the milestones: soon, lxd-2.5 Oct 11, 2016

Member

brauner commented Oct 12, 2016

Once lxc/go-lxc#68 is merged I can send a branch that adds a function ExecNoWait() to lxd/container_lxc.go and lxd/container.go that sends back the PID of the executing process which we can then wait on. After we agree that this is ok, I can send further commits that implement the actual signal forwarding.

Member

brauner commented Oct 12, 2016

Fwiw, the branch (without the signal forwarding) is here: https://github.com/brauner/lxd/commits/2016-10-12/exec_signal_forwarding. It needs to be build against a version of go-lxc with lxc/go-lxc#68 applied.

bzeller commented Oct 12, 2016

That sounds good to me

@stgraber stgraber removed the Blocked label Oct 13, 2016

@stgraber stgraber closed this Oct 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment