Several minor improvements and enhancements:

- can now use `podman` as alternative to `docker`
- added option to change the width at which the text breaks
- fixed problem with unhandled `CREATED` status
This commit is contained in:
b0wter 2023-04-23 23:01:13 +02:00
parent c8388f484e
commit 1f969c7bf4
2 changed files with 42 additions and 22 deletions

View File

@ -1,9 +1,9 @@
# Docker Widget
# Docker / Podman Widget
[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/docker)](https://github.com/streetturtle/awesome-wm-widgets/labels/docker)
![Twitter URL](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2Fstreetturtle%2Fawesome-wm-widgets%2Fedit%2Fmaster%2Fdocker-widget)
The widget allows to manage docker containers, namely start/stop/pause/unpause:
The widget allows to manage docker and podman containers, namely start/stop/pause/unpause:
<p align="center">
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/docker-widget/docker.gif"/>
@ -17,6 +17,10 @@ It is possible to customize widget by providing a table with all or some of the
|---|---|---|
| `icon` | `./docker-widget/icons/docker.svg` | Path to the icon |
| `number_of_containers` | `-1` | Number of last created containers to show |
| `executable_name` | `podman` | Name of the executable to use, defaults to `docker` |
| `max_widget_width` | 270 | Maximum width of the widget before the text breaks |
The `executable_name` allows you to use `Podman` instead of docker. This works since `Podman` is compatible to `docker` in the sense that the syntax and command outputs are identical.
## Installation

View File

@ -19,9 +19,12 @@ local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/docker-widget'
local ICONS_DIR = WIDGET_DIR .. '/icons/'
local LIST_CONTAINERS_CMD = [[bash -c "docker container ls -a -s -n %s]]
local LIST_CONTAINERS_CMD = [[bash -c "%s container ls -a -s -n %s]]
.. [[ --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}::{{.Size}}'"]]
local DOCKER_DEFAULT_STATUS_PATTERN = '(.*)::(.*)::(.*)::(%w*) (.*)::(.*)'
local DOCKER_CREATED_STATUS_PATTERN = '(.*)::(.*)::(.*)::Created::(.*)'
--- Utility function to show warning messages
local function show_warning(message)
naughty.notify{
@ -60,10 +63,16 @@ local docker_widget = wibox.widget {
}
local parse_container = function(line)
local name, id, image, status, how_long, size = line:match('(.*)::(.*)::(.*)::(%w*) (.*)::(.*)')
local actual_status
if status == 'Up' and how_long:find('Paused') then actual_status = 'Paused'
else actual_status = status end
local name, id, image, how_long, size, actual_status
if string.find(line, 'Created') then
name, id, image, size = line:match(DOCKER_CREATED_STATUS_PATTERN)
actual_status = 'Created'
how_long = 'Never started'
else
name, id, image, status, how_long, size = line:match(DOCKER_DEFAULT_STATUS_PATTERN)
if status == 'Up' and how_long:find('Paused') then actual_status = 'Paused'
else actual_status = status end
end
how_long = how_long:gsub('%s?%(.*%)%s?', '')
@ -76,13 +85,15 @@ local parse_container = function(line)
size = size,
is_up = function() return status == 'Up' end,
is_paused = function() return actual_status:find('Paused') end,
is_exited = function() return status == 'Exited' end
is_exited = function() return status == 'Exited' end,
is_created = function() return status == 'Created' end
}
return container
end
local status_to_icon_name = {
Up = ICONS_DIR .. 'play.svg',
Created = ICONS_DIR .. 'play.svg',
Exited = ICONS_DIR .. 'square.svg',
Paused = ICONS_DIR .. 'pause.svg'
}
@ -93,6 +104,10 @@ local function worker(user_args)
local icon = args.icon or ICONS_DIR .. 'docker.svg'
local number_of_containers = args.number_of_containers or -1
local executable_name = args.executable_name or 'docker'
-- 180 is the default width of the container details part of the widget and
-- 90 is the default width of the control buttons
local max_widget_width = args.max_widget_width or 180 + 90
docker_widget:set_icon(icon)
@ -122,12 +137,12 @@ local function worker(user_args)
local start_stop_button
if container.is_up() or container.is_exited() then
if container.is_up() or container.is_exited() or container.is_created() then
start_stop_button = wibox.widget {
{
{
id = 'icon',
image = ICONS_DIR .. (container:is_up() and 'stop-btn.svg' or 'play-btn.svg'),
image = ICONS_DIR .. (container:is_exited() and 'play-btn.svg' or 'stop-btn.svg'),
opacity = 0.4,
resize = false,
widget = wibox.widget.imagebox
@ -162,16 +177,16 @@ local function worker(user_args)
start_stop_button:buttons(
gears.table.join( awful.button({}, 1, function()
local command
if container:is_up() then command = 'stop' else command = 'start' end
if container:is_exited() then command = 'start' else command = 'stop' end
status_icon:set_opacity(0.2)
status_icon:emit_signal('widget::redraw_needed')
spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function()
if errors ~= '' then show_warning(errors) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
function(stdout, stderr)
rebuild_widget(stdout, stderr)
spawn.easy_async(executable_name .. ' ' .. command .. ' ' .. container['name'], function(_, stderr)
if stderr ~= '' then show_warning(stderr) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, executable_name, number_of_containers),
function(stdout, container_errors)
rebuild_widget(stdout, container_errors)
end)
end)
end) ) )
@ -226,9 +241,9 @@ local function worker(user_args)
status_icon:set_opacity(0.2)
status_icon:emit_signal('widget::redraw_needed')
awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(_, stderr)
awful.spawn.easy_async(executable_name .. ' ' .. command .. ' ' .. container['name'], function(_, stderr)
if stderr ~= '' then show_warning(stderr) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, executable_name, number_of_containers),
function(stdout, container_errors)
rebuild_widget(stdout, container_errors)
end)
@ -258,9 +273,9 @@ local function worker(user_args)
}
delete_button:buttons(
gears.table.join( awful.button({}, 1, function()
awful.spawn.easy_async('docker rm ' .. container['name'], function(_, rm_stderr)
awful.spawn.easy_async(executable_name .. ' rm ' .. container['name'], function(_, rm_stderr)
if rm_stderr ~= '' then show_warning(rm_stderr) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, executable_name, number_of_containers),
function(lc_stdout, lc_stderr)
rebuild_widget(lc_stdout, lc_stderr) end)
end)
@ -315,7 +330,8 @@ local function worker(user_args)
text = container['how_long'],
widget = wibox.widget.textbox
},
forced_width = 180,
-- 90 is the reserved width of the control buttons
forced_width = max_widget_width - 90,
layout = wibox.layout.fixed.vertical
},
valign = 'center',
@ -361,7 +377,7 @@ local function worker(user_args)
popup.visible = not popup.visible
else
docker_widget:set_bg(beautiful.bg_focus)
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, executable_name, number_of_containers),
function(stdout, stderr)
rebuild_widget(stdout, stderr)
popup:move_next_to(mouse.current_widget_geometry)