LXC is cool

Posted on 2015-04-03 (Fri) in linux

With this script it’s even cooler.

It shows you the resources of your containers or a single one. The script itself it not from me. I found it in an ansible playbook and made it a little nicer.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env bash
# stolen from here:
# https://github.com/deimosfr/ansible-lxc/blob/master/files/lxc-resources-stats

readonly PROGNAME=$(basename $0)
readonly PROGDIR=$(readlink -m $(dirname $0))
readonly ARGS="$@"

is_debian() {
    [ "$(cat /etc/os-release | grep '^NAME=')" == "NAME=\"Debian GNU/Linux\"" ] && return 0
    return 1
}

is_archlinux() {
    [ "$(cat /etc/os-release | grep '^NAME=')" == "NAME=\"Arch Linux\"" ] && return 0
    return 1
}

is_debian_wheezy() {
    [ -d /sys/fs/cgroup/lxc ] && return 0
    return 1
}

is_debian_jessie() {
    [ -d /sys/fs/cgroup/cpu/lxc ] && return 0
    return 1
}

usage() {
    cat << EOF
usage: $PROGNAME [-n CONTAINER]

Program show the resources used by LXC containers on this system. You can show a single container by adding it's name to the command.

OPTIONS:
    -n --name CONTAINER  Show only info for named container.
    -h --help            Show this help.

Examples:
    Show all containers:
    $PROGNAME

    Show a specific container:
    $PROGNAME -n mycontainer
EOF
}

cmdline() {
    local arg=
    for arg
    do
        local delim=""
        case "$arg" in
            #translate --gnu-long-options to -g (short options)
            --help)         args="${args}-h ";;
            --name)         args="${args}-n ";;
            #pass through anything else
            *) [[ "${arg:0:1}" == "-" ]] || delim="\""
                args="${args}${delim}${arg}${delim} ";;
        esac
    done

    #Reset the positional parameters to the short options
    eval set -- $args

    while getopts "hn:" OPTION
    do
        case $OPTION in
        h)
            usage
            exit 0
            ;;
        n)
            readonly CONTAINER=$OPTARG
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            ;;
        esac
    done

    return 0
}

show_container() {
    local container=$1
    local dir
    local cpuset
    local cpushare
    local memlimit
    local memswlimit
    local memusage
    local memswuage
    local maxusage
    local memswmaxusage
    local blkio

    if is_debian ; then
        if is_debian_wheezy ; then
            dir='/sys/fs/cgroup/lxc'
            cpuset="$dir/$container/cpuset.cpus"
            cpushare="$dir/$container/cpu.shares"
            memlimit="$dir/$container/memory.limit_in_bytes"
            memswlimit="$dir/$container/memory.memsw.limit_in_bytes"
            memusage="$dir/$container/memory.usage_in_bytes"
            memswusage="$dir/$container/memory.memsw.usage_in_bytes"
            maxusage="$dir/$container/memory.max_usage_in_bytes"
            memswmaxusage="$dir/$container/memory.memsw.max_usage_in_bytes"
            blkio="$dir/$i/blkio.weight"
        elif is_debian_jessie ; then
            dir='/sys/fs/cgroup'
            cpuset="$dir/cpuset/lxc/$container/cpuset.cpus"
            cpushare="$dir/cpu,cpuacct/lxc/$container/cpu.shares"
            memlimit="$dir/memory/lxc/$container/memory.limit_in_bytes"
            memswlimit="$dir/memory/lxc/$container/memory.memsw.limit_in_bytes"
            memusage="$dir/memory/lxc/$container/memory.usage_in_bytes"
            memswusage="$dir/memory/lxc/$container/memory.memsw.usage_in_bytes"
            maxusage="$dir/memory/lxc/$container/memory.max_usage_in_bytes"
            memswmaxusage="$dir/memory/lxc/$container/memory.memsw.max_usage_in_bytes"
            blkio="$dir/blkio/lxc/$container/blkio.weight"
        fi
    elif is_archlinux ; then
        dir='/sys/fs/cgroup'
        cpuset="$dir/cpuset/lxc/$container/cpuset.cpus"
        cpushare="$dir/cpu,cpuacct/lxc/$container/cpu.shares"
        memlimit="$dir/memory/lxc/$container/memory.limit_in_bytes"
        memswlimit="/sys/fs/cgroup/memory/lxc/$container/memory.kmem.limit_in_bytes"
        memusage="$dir/memory/lxc/$container/memory.usage_in_bytes"
        memswusage="$dir/memory/lxc/$container/memory.kmem.usage_in_bytes"
        maxusage="$dir/memory/lxc/$container/memory.max_usage_in_bytes"
        memswmaxusage="$dir/memory/lxc/$container/memory.kmem.max_usage_in_bytes"
        blkio="$dir/blkio/lxc/$container/blkio.weight"
    else
        echo "Can't locate cgroup filesystem."
        echo "Supported distros are Debian Wheezy/Jessie and Archlinux."
        echo "You can fix this issue by contributing to https://github.com/XenGi/lxc-resource-stats"
        exit 1
    fi

    echo "===== $container ====="
    echo "CPU, cap:               " $(cat $cpuset)
    echo "CPU, shares:            " $(cat $cpushare)
    awk '{ printf "RAM, limit usage:        %sM\n", $1/ 1024 / 1024 }' $memlimit
    awk '{ printf "RAM+SWAP, limit usage:   %sM\n", $1/ 1024 / 1024 }' $memswlimit
    awk '{ printf "RAM, current usage:      %sM\n", $1/ 1024 / 1024 }' $memusage
    awk '{ printf "RAM+SWAP, current usage: %sM\n", $1/ 1024 / 1024 }' $memswusage
    awk '{ printf "RAM, max usage:          %sM\n", $1/ 1024 / 1024 }' $maxusage
    awk '{ printf "RAM+SWAP, max usage:     %sM\n", $1/ 1024 / 1024 }' $memswmaxusage
    echo "DISK I/O weight:        " $(cat $blkio)
    echo ""
}

main() {
    cmdline $ARGS

    local i

    if [[ -z ${CONTAINER+x} ]] ; then
        for i in $(lxc-ls --active -1) ; do
            show_container $i
        done
    else
        show_container $CONTAINER
    fi
}
main