Open eyalch opened 6 years ago
In the src/dockerMenu.js file, in fact, partially. If we delete the last container and click on the extension icon, the icon is hidden. When launching a new container, then you need Alt + F2 to restart the shell so that the icon appears again.
'use strict';
const St = imports.gi.St;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const DockerSubMenuMenuItem = Me.imports.src.dockerSubMenuMenuItem;
const DockerMenuStatusItem = Me.imports.src.dockerMenuStatusItem;
// Docker icon on status menu
const DockerMenu = new Lang.Class({
Name: 'DockerMenu.DockerMenu',
Extends: PanelMenu.Button,
// Init the docker menu
_init: function() {
this.parent(0.0, _("Docker containers"));
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
let gicon = Gio.icon_new_for_string(Me.path + "/docker.svg");
let dockerIcon = new St.Icon({ gicon: gicon, icon_size: '24'});
hbox.add_child(dockerIcon);
hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.actor.add_child(hbox);
this.actor.connect('button_press_event', Lang.bind(this, this._refreshMenu));
this._renderMenu();
this._indicatorHide();
},
// Refresh the menu everytime the user click on it
// It allows to have up-to-date information on docker containers
_refreshMenu: function() {
if(this.menu.isOpen) {
this.menu.removeAll();
this._renderMenu();
this._indicatorHide();
}
},
// Checks if docker is installed on the host machine
_isDockerInstalled: function() {
return GLib.find_program_in_path('docker') != undefined;
},
// Checks if the docker daemon is running or not
_isDockerRunning: function() {
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ps', 'cax'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
// Look for the docker process running
let dockerRunning = false;
let hasLine = true;
do {
let [out, size] = out_reader.read_line(null);
if(out != null && out.toString().indexOf("docker") > -1) {
dockerRunning = true;
} else if(size <= 0) {
hasLine = false;
}
} while(!dockerRunning && hasLine);
return dockerRunning;
},
// Show docker menu icon only if installed and append docker containers
_renderMenu: function() {
if(this._isDockerInstalled()) {
if(this._isDockerRunning()) {
this._feedMenu();
} else {
let errMsg = _("Докер не запущен");
this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
log(errMsg);
}
// Add Turn On / Turn Off Switch always
let statusSwitch = new DockerMenuStatusItem.DockerMenuStatusItem('Статус докера');
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addMenuItem(statusSwitch);
} else {
let errMsg = _("Двоичный файл докера не найден в PATH");
this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
log(errMsg);
}
this.actor.show();
},
// Append containers to menu
_feedMenu: function() {
let delimiter = ',';
let [res, out, err, status] = GLib.spawn_command_line_sync("docker ps -a --format '{{.Names}}" + delimiter + "{{.Status}}'");
if(status == 0) {
let outStr = String.fromCharCode.apply(String, out);
let dockerContainers = outStr.split('\n');
let numberContainers = dockerContainers.length-1;
if (numberContainers) {
// foreach container, add an entry in the menu
for(let i = 0; i < numberContainers; i++) {
let [containerName, containerStatusMessage] = dockerContainers[i].split(delimiter);
let subMenu = new DockerSubMenuMenuItem.DockerSubMenuMenuItem(containerName, containerStatusMessage);
this.menu.addMenuItem(subMenu);
}
}
} else {
let errMsg = "Ошибка при получении контейнеров";
this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
log(errMsg);
log(err);
}
},
// Docker hide indicator if there are no containers
_indicatorHide() {
let delimiter = ',';
let [res, out, err, status] = GLib.spawn_command_line_sync("docker ps -a --format '{{.Names}}" + delimiter + "{{.Status}}'");
if(status == 0) {
let outStr = String.fromCharCode.apply(String, out);
let dockerContainers = outStr.split('\n');
let numberContainers = dockerContainers.length-1;
if (numberContainers) {
this.actor.visible = true;
} else {
this.actor.visible = false;
}
}
}
});
Since there's no functionality when there are no containers, could we please have an option to remove the icon from the status bar when in such condition?