Giter VIP home page Giter VIP logo

sen's Introduction

sen

Build Status

sen is a terminal user interface for containers:

  • it can interactively manage your containers and images:
  • start, stop, restart, kill, delete,...
  • there is a "dashboard" view for containers and images
  • you are able to inspect containers and images
  • sen can fetch logs of containers and even stream logs real-time
  • some buffers support searching and filtering
  • sen receives real-time updates from docker when anything changes
  • e.g. if you pull a container in another terminal, sen will pick it up
  • sen notifies you whenever something happens (and reports slow queries)
  • supports a lot of vim-like keybindings (j, k, gg, /, ...)
  • you can get interactive tree view of all images (equivalent of docker images --tree)
  • see how much space containers, images and volumes occupy (just type :df)

You can see the features yourself.

Preview of sen

Status

maintenance mode

I lost interest in working on new features for sen. I will continue providing support for sen as much as I can, but only bug fixes. Please don't expect any new features written by me. If you want some feature in sen, you need to write it yourself โ€” I will gladly accept such pull request.

Installation and running sen

I strongly advise to run sen from a docker container provided on docker hub:

$ docker pull tomastomecek/sen

This repository has set up automated builds on docker hub. In case you run into some issue, try pulling latest version first before opening an issue.

This is the recommended way of running sen in a container:

$ docker run -v /var/run/docker.sock:/run/docker.sock -ti -e TERM tomastomecek/sen

Some distros have /var/run simlinked to /run, so you can do /run/docker.sock:/run/docker.sock instead.

In case you would like to try development version of sen, you can pull tomastomecek/sen:dev.

docker

You can easily build a docker image with sen inside:

$ docker build --tag=$USER/sen https://github.com/tomastomecek/sen
$ docker run -v /var/run/docker.sock:/run/docker.sock -ti -e TERM $USER/sen

PyPI

sen is using urwidtrees as a dependency. Unfortunately, the upstream maintainer doesn't maintain it on PyPI so we need to install it directly from git, before installing sen (the forked PyPI version has a bug in the installation process):

$ pip3 install git+https://github.com/pazz/urwidtrees.git@9142c59d3e41421ff6230708d08b6a134e0a8eed#egg=urwidtrees-1.0.3.dev

sen releases are available on PyPI:

$ pip3 install sen

If pip3 executable is not available on your system, you can run pip like this:

$ python3 -m pip install sen

And then start sen like this:

$ sen

git

sen is a python 3 only project. I recommend using at least python 3.4. This is how you can install sen from git:

$ git clone https://github.com/TomasTomecek/sen
$ cd sen
$ pip3 install --user -r ./requirements.txt
$ ./setup.py install
$ sen

Or even run sen straight from git:

$ git clone https://github.com/TomasTomecek/sen
$ cd sen
$ pip3 install --user -r ./requirements.txt
$ PYTHONPATH="$PWD:$PYTHONPATH" ./sen/cli.py

Prerequisite

Either:

  • The unix socket with the API for docker engine needs to be accessible. By default it's located at /run/docker.sock.

Or:

  • Have the DOCKER_HOST, DOCKER_TLS_VERIFY, and DOCKER_CERT_PATH set properly.

Podman

Starting Podman v2.0, there is a Docker-compatible API provided by Podman. sen works well while talking to Podman over this API.

Connecting to Podman

Run Podman as:

$ podman system service -t 0

Let's discover the unix socket path now:

$ podman info --format={{".Host.RemoteSocket.Path"}}
/run/user/1000/podman/podman.sock

And finally tell sen to connect to it:

$ DOCKER_HOST=unix://$(podman info --format={{".Host.RemoteSocket.Path"}}) sen

Keybindings

Since I am heavy vim user, these keybindings are trying to stay close to vim.

Global

/         search (provide empty query to disable searching)
n         next search occurrence
N         previous search occurrence
f4        display only lines matching provided query (provide empty query to clear filtering)
f5        open a tree view of all images (`docker images --tree` equivalent)
ctrl o    navigate to next buffer
ctrl i    navigate to previous buffer
x         remove buffer
q         remove buffer, quit if no buffer is left
ctrl l    redraw user interface
h, ?      show help
:         open command prompt

Movement

gg, home  go to first item
G, end    go to last item
j         go one line down
k         go one line up
pg up
ctrl u    go 10 lines up
pg down
ctrl d    go 10 lines down

Listing

@         refresh listing
f4        filtering, for more info run `help filter` in sen

Image commands in listing

i         inspect image
d         remove image (irreversible!)
D         remove image forcibly (irreversible!)
enter     display detailed info about image (when layer is focused)

Container commands in listing

i         inspect container
l         display logs of container
f         follow logs of container
d         remove container (irreversible!)
D         remove container forcibly (irreversible!)
t         stop container
s         start container
r         restart container
p         pause container
u         unpause container
b         open container's mapped ports in a web-browser
X         kill container
!         toggle realtime updates of the interface (this is useful when you are removing multiple
          objects and don't want the listing change during that so you accidentally remove something)

Tree buffer

enter  display detailed info about image (opens image info buffer)

Image info buffer

enter     display detailed info about image (when an image is focused)
i         inspect image or container, whatever is focused

Container info buffer

enter     display detailed info about image (when image of the container is focued)
i         inspect image (when image of the container is focued)

Disk usage buffer

You can enter it by typing command df.

Why I started sen?

Since I started using docker, I always dreamed of having a docker TUI. Something like tig, htop or alot. Some appeared over time. Such as docker-mon or ctop. Unfortunately, those are not proper docker TUIs. They are meant for monitoring and diagnostics.

So I realized that if I want make my dream come true, I need to do it myself. That's where I started working on sen (dream in Slovak).

But! As the time went, someone else had the same idea as I did: dry.

sen's People

Contributors

00-matt avatar cgwalters avatar dhodovsk avatar f-cap avatar gururajrkatti avatar hroncok avatar lachmanfrantisek avatar nagracks avatar ne0zen avatar pabardina avatar soyo42 avatar tomastomecek avatar vitexus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sen's Issues

improve image info buffer

Display:

  • digest -- this is empty in inspect atm (docker 1.9/1.10)
  • clickable list of all containers created from this image -- buffer not yet implemented
  • improve container listing
    • style
    • operations
  • build logs? -- impossible to do atm
  • is this remotely pulled? -- try with docker events
  • is there an update? tracking at #52

more management commands

  • start container
  • stop container
  • pause container
  • unpause container
  • kill container
  • remove container
  • remove image

blockers

  • colors
  • display prettier names
  • test all commands

rewrite footer

Current implementation is pretty poor. Abstract it to separate class.

  • don't allow duplicates

refactoring

There are multiple areas in code which require rewrite/improvement:

  • keybindings mapping -- this got to be a text file
  • commands -- create commands which can be directly mapped to keybindings and also being called from prompt
  • internal class logic (UI() class should not contain any application specific code)

split logs

  • one command to follow
  • one command to get all logs

Current solution is universal, but covers two stories.

new buffer: image info

Display:

  • id
  • date
  • size
  • digest
  • labels
  • clickable list of all intermediate layers
  • clickable list of all containers created from this image
  • clickable list of all repositories and tags
    • enable removing
  • build logs? impossible to do atm
  • is this remotely pulled? impossible to do atm
  • is there an update? #52

create container info buffer

Similar to image info buffer

  • link to image
  • status
  • history -- with docker events
  • test connection if port is opened
    • creating socket
    • doing GET
  • show volumes
  • describe network
  • process tree
  • stats
  • brief logs

systemctl status could be an inspiration

tests

  • CI
  • integration tests

sen won't start on docker 1.8

this is worth of doing a new release

Traceback (most recent call last):
  File "/home/ttomecek/dev/sen/sen/util.py", line 23, in wrapper
    response = func(*args, **kwargs)
  File "/home/ttomecek/dev/sen/sen/tui/init.py", line 151, in chain_fcs
    self.main_list_buffer.refresh(focus_on_top=True)
  File "/home/ttomecek/dev/sen/sen/tui/buffer.py", line 100, in refresh
    self.widget.populate(focus_on_top=focus_on_top)
  File "/home/ttomecek/dev/sen/sen/tui/widgets/list/main.py", line 145, in populate
    widgets = self._assemble_initial_content()
  File "/home/ttomecek/dev/sen/sen/tui/widgets/list/main.py", line 180, in _assemble_initial_content
    line = MainLineWidget(o)
  File "/home/ttomecek/dev/sen/sen/tui/widgets/list/main.py", line 87, in __init__
    image = AdHocAttrMap(urwid.Text(o.image_name()), get_map())
  File "/home/ttomecek/dev/sen/sen/docker_backend.py", line 464, in image_name
    image = self.docker_backend.get_image_by_id(self.image_id)
  File "/home/ttomecek/dev/sen/sen/docker_backend.py", line 458, in image_id
    image_id = self.data["ImageID"]
KeyError: 'ImageID'

exit gracefully when docker socket is not available

  File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py", line 353, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib64/python3.4/http/client.py", line 1090, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib64/python3.4/http/client.py", line 1128, in _send_request
    self.endheaders(body)
  File "/usr/lib64/python3.4/http/client.py", line 1086, in endheaders
    self._send_output(message_body)
  File "/usr/lib64/python3.4/http/client.py", line 924, in _send_output
    self.send(msg)
  File "/usr/lib64/python3.4/http/client.py", line 859, in send
    self.connect()
  File "/usr/lib/python3.4/site-packages/docker/unixconn/unixconn.py", line 41, in connect
    sock.connect(self.unix_socket)
requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/site-packages/docker/client.py", line 89, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
  File "/usr/lib/python3.4/site-packages/docker/api/daemon.py", line 78, in version
    return self._result(self._get(url), json=True)
  File "/usr/lib/python3.4/site-packages/docker/client.py", line 110, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 480, in get
    return self.request('GET', url, **kwargs)
  File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3.4/site-packages/requests/adapters.py", line 412, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.4/threading.py", line 921, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.4/threading.py", line 869, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.4/site-packages/sen/tui/widget.py", line 430, in realtime_updates
    for content in self.d.realtime_updates():
  File "/usr/lib/python3.4/site-packages/sen/docker_backend.py", line 441, in realtime_updates
    for event in self.client.events(decode=True):
  File "/usr/lib/python3.4/site-packages/sen/docker_backend.py", line 413, in client
    self._client = docker.AutoVersionClient()
  File "/usr/lib/python3.4/site-packages/docker/client.py", line 325, in __init__
    super(AutoVersionClient, self).__init__(*args, **kwargs)
  File "/usr/lib/python3.4/site-packages/docker/client.py", line 77, in __init__
    self._version = self._retrieve_server_version()
  File "/usr/lib/python3.4/site-packages/docker/client.py", line 97, in _retrieve_server_version
    'Error while fetching server API version: {0}'.format(e)
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

add status bar

  • time it took to perform a remote api call
    • show longest one from bulk
    • make it a queue of timeouts
  • # of images
  • # of (running) containers
  • list of buffers (show active)
    • add colors
    • shortcuts [I] fedora [L] fedora [M]
  • error mesages
  • events (low prio)

distruingush between images and containers in listing

I hope this could be done this way: whole rows will have colors. Color meanings:

  • green: container is running
  • orange: container is stopped or exited well
  • red: container crashed, not ended well or there is some problem
  • transparent: images
  • blue: volumes
  • yellow: networks

improve python packaging

  • prettier description on PyPI
  • add classifiers #46 (thanks @hroncok!)
  • automatically push to PyPI when released
  • test release:
    • from docker hub
    • from PyPI
  • provide wheels

urwid is not thread-safe: lock rendering

11:25:22 sen                ERROR  Exception caught: AssertionError('rows, render mismatch',)
Traceback (most recent call last):
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 277, in run
    self._run()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 374, in _run
    self.event_loop.run()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 677, in run
    self._loop()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 705, in _loop
    self._entering_idle()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 666, in _entering_idle
    callback()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 559, in entering_idle
    self.draw_screen()
  File "/usr/lib64/python3.5/site-packages/urwid/main_loop.py", line 573, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/usr/lib64/python3.5/site-packages/urwid/widget.py", line 140, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib64/python3.5/site-packages/urwid/decoration.py", line 224, in render
    canv = self._original_widget.render(size, focus=focus)
  File "/usr/lib64/python3.5/site-packages/urwid/widget.py", line 140, in cached_render
    canv = fn(self, size, focus=focus)
  File "/usr/lib64/python3.5/site-packages/urwid/container.py", line 1095, in render
    assert foot.rows() == frows, "rows, render mismatch"
AssertionError: rows, render mismatch

When bulk-removing a lot of objects, this happens a lot.

urwid/urwid#165

remote registry interaction

  • is there an image update?
  • fetch all tags of a repository
  • display manifest
  • let user provide list of registry
  • allow pushing image to a registry

0.1 release

  • test everything (all commands, searching, filtering)
  • update image in readme with gif

should respect DOCKER_* environment variables (if defined)

when using docker-machine or boot2docker, these tools create environment variables which are used to configure the docker client, docker-compose, etc to point @ the docker daemon running w/in their vm.

Should be relatively painless to create your client leveraging the same logic.

Improve listing

Merge status of containers with created of images. Display image for containers and base image for images.

use `docker events` to refresh UI

This is going to have much better performance than polling with docker ps -a and docker images

  • add lock mode: do not refresh ui when performing commands (to accidentally change another object)

sen crashes when container logs retrieved from removed container

I tried looking at a log for a removed container and got:
2015-10-22 14:42:24,318 - sen - ERROR - Exception caught: APIError(HTTPError('404 Client Error: Not Found',),)bing_fermat

Interactions with removed containers should be limited or disallowed. (Somewhat related to issue #19)

refresh container status periodically

Would be nice to be able to in addition to the @ keybinding refresh to be able to have it automatically do so at a specific interval, perhaps similar to how watch works.

UnicodeEncodeError when viewing docker logs

Somehow I ended up with this on screen:

2015-10-24 16:05:41,168 - sen - ERROR - Exception caught: UnicodeEncodeError('ascii', '\u251c\u2500\u2500 [email protected]', 0, 3, 'ordinal not in range(128)')

I wish I had more info, or even a stack trace but that is it, sorry.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.