Helper Function for opening a terminal in containers


(Shigbeard) #1

So I’ve had issues with getting into containers to do stuff, these issues mostly stemming from things such as screen and tmux complaining that I’m not in a terminal. I got sick of it, and after a friend gave me a handy command to get around it, I decided to write a helper function with auto-complete and share it, should be handy for a few of you guys/gals.

enter-container() {
        lxc exec $1 -- sh -c "exec >/dev/tty 2>/dev/tty </dev/tty && /usr/bin/screen -s /bin/bash"
}
_enter-container() {
        local cont=( $( lxc list --format=json | jq -r '.[].name' ) )
        local cont2=${cont[@]}
        local cur=${COMP_WORDS[COMP_CWORD]}
        if [[ $COMP_CWORD == 1 ]]; then
                COMPREPLY=( $(compgen -W "${cont2}" -- $cur) )
        else
                COMPREPLY=()
        fi
}
complete -F _enter-container enter-container

As I said, just wanted to share this is all. It’s been a huge time saver for me when I’d be going between containers and working with tmux. I take no credit for the contents of enter-container() but I do for everything else.

EDIT: Oh, and fyi, you need the jq package, to parse the json string returned by lxc list. Doesn’t come stock standard on ubuntu 16.04, so you’ll need to install that.


#2

Hi!
First of all, it’s amazing that you dug into the shell completion. It helps a lot into the usability of LXD.

You are using lxc exec, which means that you are using LXD instead of LXC 1.0 (see Comparing LXD vs. LXC).

In LXC 1.0 there has been a lxc-console command for quite some time, which could also be reused on LXD (https://github.com/lxc/lxd/issues/1129).
In LXD, since last autumn (I think LXD version 2.17 or newer), you can use lxc console to get a console to the container. The stock LXD version in Ubuntu 16.04 LTS does not have lxc console so you would either need to upgrade to the snap version of LXD, or install LXD from the backports repository.

Having said that, here are the new possibilities:

Shell access to container tty
lxc exec c1 – sh not a tty
lxc console c1 /dev/console
enter_container c1 /dev/pts/0

I do not fully understand how it gets the /dev/pty/0 tty.

You mention that your contribution is the bash autocomplete. I think it would be great to have this autocompletion for the full set of LXD subcommands, especially for lxc config which tends to get complicated with the many options. The user would type, for example, lxc config <TAB><TAB> and then get a list of keywords that are suitable to come after lxc config.

The jq requirement could be an issue. In LXD 2.21, there is a new format, csv. The first field is the container name and the second is either RUNNING or STOPPED. Therefore, it would be possible to avoid jq outright in LXD 3.0. In older LXD, it should be possible to use some shell commands to extract the container names.


(Stéphane Graber) #3

Such bash completion is already present in LXD.

root@sateda:~# lxc 
config    delete    file      help      info      launch    manpage   move      profile   query     rename    restore   snapshot  stop      version
copy      exec      finger    image     init      list      monitor   network   publish   remote    restart   shell     start     storage   
root@sateda:~# lxc config 
device    edit      get       metadata  set       show      template  trust     unset     
root@sateda:~# lxc config set 
asterisk01                      core.proxy_https                images.auto_update_cached       munin01
cacti01                         core.proxy_ignore_hosts         images.auto_update_interval     nagios01
core.https_address              core.trust_password             images.compression_algorithm    openhab01
core.https_allowed_credentials  cups03                          images.remote_cache_expiry      samba-dc02
core.https_allowed_headers      dhcpd01                         jenkins01                       smokeping01
core.https_allowed_methods      dnses02                         maas01                          smtpin02
core.https_allowed_origin       dnsr01                          maas.api.key                    smtpout02
core.macaroon.endpoint          dnsr06                          maas.api.url                    tftpd01
core.proxy_http                 freeradius02                    maas.machine                    
root@sateda:~# lxc config set asterisk01 
boot.autostart                           limits.processes                         security.syscalls.blacklist
boot.autostart.delay                     linux.kernel_modules                     security.syscalls.blacklist_compat
boot.autostart.priority                  migration.incremental.memory             security.syscalls.blacklist_default
boot.host_shutdown_timeout               migration.incremental.memory.goal        user.meta-data
boot.stop.priority                       migration.incremental.memory.iterations  user.network-config
environment.                             raw.apparmor                             user.network_mode
limits.cpu                               raw.idmap                                user.user-data
limits.cpu.allowance                     raw.lxc                                  user.vendor-data
limits.cpu.priority                      raw.seccomp                              volatile.apply_quota
limits.disk.priority                     security.devlxd                          volatile.apply_template
limits.memory                            security.idmap.base                      volatile.base_image
limits.memory.enforce                    security.idmap.isolated                  volatile.idmap.base
limits.memory.swap                       security.idmap.size                      volatile.idmap.next
limits.memory.swap.priority              security.nesting                         volatile.last_state.idmap
limits.network.priority                  security.privileged                      volatile.last_state.power
root@sateda:~# lxc config set asterisk01 

#4

Indeed, there are bash completion rules for LXD.

In Ubuntu, bash completion rules are activated per user instead of globally.
That is, there are commands in /etc/bashrc to activate the bash completion rules, however these commands are commented out.
Instead, when you create a new account with the default shell (BASH), it copies the .bashrc from /etc/skel/ which has the commands to source all available bash completion rules (found in /etc/bash_completion.d/).

In my case, I previously adapted my ~/.bashrc and those completion rules were not being loaded :-(.

This is one more piece of LXD info that should be disseminated.