martedì 25 gennaio 2011

Spegnere OpenBox con vera classe

Facendo seguito alla classica guida di Santiago, Oblogout, spegnere Openbox con classe, voglio qui presentarvi un metodo che consente di ottenere il medesimo risultato, ma in modo più 'pulito' e senza installare alcunché di nuovo.

In effetti, in una mia recentissima configurazione di OpenBox, non ero riuscito a far funzionare il programma suggerito dall'amico Santiago. Dopo una lunga ricerca di alternative, ho trovato un paio di belle soluzioni in una wiki in francese di ArchLinux, che qui vi propongo.

Premessa

Condicio sine qua non è conferire al nostro utente i dovuti privilegi. Da terminale,
# visudo
ed aggiungiamo nel corrispondente punto la stringa seguente (qui evidenziata in grassetto):
# Allow members of group sudo to execute any command
# (Note that later entries override this, so you might need to move
# it further down)
%sudo ALL=(ALL) ALL
%users  ALL=NOPASSWD: /sbin/shutdown
Naturalmente, assicuriamoci che il nostro utente sia inserito nel gruppo users.
A questo punto, non dobbiamo fare altro che scegliere uno dei seguenti metodi.

Metodo 1 (Crunchbang ~ GDM)

Se utilizzate GDM (proprio lui, e non, ad esempio, GDM3!), possiamo semplicemente ricorrere allo script di quella che non esito a definire la distro più bella che esista, Crunchbang.

Ricordo che per aggiungerne le caratteristiche in una Debian, possiamo utilizzare il repository di questa distro:
deb http://packages.crunchbanglinux.org/statler statler main #CrunchBang Linux 10.xx aka Statler
Quindi, dovremo installarne la chiave di sicurezza e il pacchetto che ci interessa:
# aptitude update && aptitude install crunchbang-keyring openbox-logout-script
È bene ricordare che questo repository è compatibile al 100% con Squeeze, ma non so come si comporterà con la prossima Wheezy: data la natura dei pacchetti ivi contenuti, penso che non ci dovrebbero essere problemi, ma è meglio stare all'erta.

Metodo 2

Se invece non utilizziamo GDM, possiamo ricorrere ad uno dei seguenti script, basati su quello di CrunchBang, ma modificati in modo da essere indipendenti da quel login manager.
Il primo, più spartano, è il seguente:
#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import os

class DoTheLogOut:

    # Cancel/exit
    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    # Logout
    def logout(self, widget):
        os.system("openbox --exit")

    # Reboot
    def reboot(self, widget):
        os.system("sudo shutdown -r now")

    # Shutdown
    def shutdown(self, widget):
        os.system("sudo shutdown -h now")

    def __init__(self):
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Vuoi uscire? Scegli un'opzione:")
        self.window.set_resizable(False)
        self.window.set_position(1)
        self.window.connect("delete_event", self.delete_event)
        self.window.set_border_width(20)

        # Create a box to pack widgets into
        self.box1 = gtk.HBox(False, 0)
        self.window.add(self.box1)

        # Create cancel button
        self.button1 = gtk.Button("Annulla")
        self.button1.set_border_width(10)
        self.button1.connect("clicked", self.delete_event, "Ho cambiato idea :)")
        self.box1.pack_start(self.button1, True, True, 0)
        self.button1.show()

        # Create logout button
        self.button2 = gtk.Button("Log out")
        self.button2.set_border_width(10)
        self.button2.connect("clicked", self.logout)
        self.box1.pack_start(self.button2, True, True, 0)
        self.button2.show()

        # Create reboot button
        self.button3 = gtk.Button("Riavvia")
        self.button3.set_border_width(10)
        self.button3.connect("clicked", self.reboot)
        self.box1.pack_start(self.button3, True, True, 0)
        self.button3.show()

        # Create shutdown button
        self.button4 = gtk.Button("Arresta")
        self.button4.set_border_width(10)
        self.button4.connect("clicked", self.shutdown)
        self.box1.pack_start(self.button4, True, True, 0)
        self.button4.show()

        self.box1.show()
        self.window.show()

def main():
    gtk.main()

if __name__ == "__main__":
    gogogo = DoTheLogOut()
    main()
Salviamolo dove preferiamo, rendiamolo eseguibile e quindi lanciamolo. Ovviamente, potremo aggiungere una voce al menu tramite obmenu oppure una scorciatoia da tastiera tramite obkey.
Il risultato sarà comunque simile a questo:


Metodo 3

Si tratta di uno script identico al precendete, ma più 'colorato'. Potete scaricare quello della wiki di Arch sopra linkata, o quello da me tradotto in italiano, che potrete trovare in questo LINK.
Una volta scompattato, per lanciarlo dovrete usare questo comando:
$ python /percorso_alla_cartella/ob_logout
Anche in questo caso, possiamo aggiungere una voce al menu tramite obmenu oppure una scorciatoia da tastiera tramite obkey, ma il risultato finale sarà il seguente:


---------------------------------
by Doc, last modified 24 January 2011
Powered by Bluefish

12 commenti:

  1. ottimo post (come sempre in questo blog) :D

    RispondiElimina
  2. Ciao Doc,
    se posso permettermi, avrei un piccolo suggerimento.

    Utilizzando il comando di shutdown, quindi da utente root, scavalchi tutta l'infrastruttura di PolicyKit sottostante. Per quanto possa essere ininfluente in un sistema monoutente, non è una soluzione molto elegante né formalmente corretta.
    Se ti è capitato di farci caso, quando p.e. in gnome o kde usi l'arresto, se ci sono altri utenti loggati, i privilegi di utente non ti consentono di effettuare lo spegnimento, appare una finestra di richiesta d'immissione di password per ottenere i privilegi necessari. Ciò avviene perché il comando di spegnimento usa una chiamata d-bus, non lo shutdown.

    Per farla breve, se vuoi ottenere lo stesso risultato, che tra l'altro ti evita anche la configurazione aggiuntiva dei sudoers, puoi sostituire ai comandi di shutdown queste chiamate d-bus:

    Spegnimento:
    dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop
    Riavvio:
    dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart

    Inoltre, volendo aggiungerle, sospensione:
    dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Suspend
    Ibernazione:
    dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Hibernate

    N.B. Queste chiamate sono valide per i sistemi che hanno abbandonato hal in favore di ConsoleKit, per intenderci, in termini di dist. Debian, da Squeeze in poi.
    Giusto a titolo di esempio, questa è la chiamata per lo spegnimento dei sistemi che ancora usano hal:
    dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown

    Ciao, lac.

    RispondiElimina
  3. @lihin
    Caro Lac,
    come vedi, questa mia guidarella non fa altro che tradurre in italiano quella di Arch linkata all'inizio.

    Tuttavia, subito dopo averla pubblicata, mi son messo a "studiare" come aggiungere le altre voci utili (sospensione, ibernazione e blocco schermo) ed avevo trovato info in tal senso, sebbene sparse.

    Quindi, il tuo commento casca proprio a fagiuolo e mi risparmia un sacco di tempo e danaro!!!

    Grazie mille! Implementerò i tuoi suggerimenti ed aggiornerò la guida di conseguenza.

    [OT] A proposito di ibernazione, hai notato che su sid e squeeze da alcuni giorni l'ibernazione è saltata, almeno sul 1000he, dopo mesi e mesi di funzionamento perfetto?
    Ho ricostruito che il problema (su sid) deve essere sorto intorno al 13 gennaio, probabilmente con l'avvento del k. 2.6.32-30.

    RispondiElimina
  4. Quoto quanto detto da lihin.
    Tempo fa avevo preparato un programmino in pygtk che fa appunto questo, e ne avevo parlato sul forum di arch http://www.archlinux.it/forum/viewtopic.php?id=9086
    Occhio che se hai eliminato hal, su arch c'è attualmente un bug coi permessi di consolekit, per il quale un workaround è spiegato nella pagina wiki di xfce a questo paragrafo https://wiki.archlinux.org/index.php/Xfce#Reboot.2FShutdown

    RispondiElimina
  5. @Gianpiero
    Grazie anche a te!

    Però, non uso Arch, ma debian. Ad ogni modo, vedrò di integrare le tue info in guida, se vuoi.

    RispondiElimina
  6. @ ALL

    Ho intanto modificato lo script più semplice. Chi lo volesse testare, può intanto trovarlo qua: http://pastebin.com/2HKc83bB

    Per ora, non posso che testarlo sul mio fisso, dove non ho swap e dunque non iberno.

    P.S.: mi sono accorto ora di qualche errore, ma niente di grave!

    RispondiElimina
  7. Comunque è solo uno script in python. Per farlo funzionare su debian basta che alla prima riga sostituisci "python" a "python2"

    RispondiElimina
  8. @Gianpiero
    L'avevo già provato e funziona, anche senza cambiamenti: python rimanda direttamente a python2.

    Mi riferivo al fatto che da noi non si riscontra il problema dei permessi di consolekit da te segnalato.

    Ad ogni modo, grazie mille e, se vuoi, testa pure quello linkato nel mio precedente commento.

    RispondiElimina
  9. L'ho provato. È simile al mio (che non brilla certo per originalità) a parte la mancanza delle icone ed una differenza che ritengo fondamentale:
    per lanciare la tua connessione a dbus, hai usato la chiamata di sistema os.system. Non è una grande idea, in quanto per dbus sono presenti i bindings in python, quindi aprire una sub-shell è inutile, e potenzialmente (anche se non in questo caso) poco portabile. Se ti interessa, rispetto alla versione linkata sul forum di archlinux, ho aggiunto anche gli switch da riga di comando, utili per il keybinding delle funzioni ad esempio ai tasti multimediali. Sempre in attesa di riuscire ad utilizzare la funzione consolekit relativa alla chiusura della sessione...

    RispondiElimina
  10. @Gianpiero
    Grazie mille!
    Per le icone, ci sarebbe il secondo script della guida, che ho già modificato sulla falsariga di quello sopra linkato.

    Purtroppo, non posso studiare la cosa in questi giorni, per impegni di lavoro, ma mi riprometto di farlo.

    Solo una precisazione: non capisco niente di python e mi son limitato ad adattare gli scripts della wiki francese linkata in guida.

    Però la cosa è importante e vale la pena di unire gli sforzi per addivenire ad una soluzione "definitiva" utile per tutti.
    Che ne dici di sentirci via mail? Comincia, se vuoi, utilizzando la mail del gruppo, in modo che possano leggere le comunicazioni anche gli altri amici, alcuni dei quali sono arcieri agguerriti.
    Potresti addirittura entrare nel nostro gruppo, se vuoi. L'impegno è piccolo: se hai qualcosa da scrivere, la scrivi, altrimenti ti fai i fatti tuoi.

    RispondiElimina
  11. Guarda non credo di aver molto da dire, non avendo un netbook nè un notebook :D
    Sono arrivato qui tramite il planet di arch. Sul programmino (ma proprio ino-ino-ino...) comunque sono disponibile, ed anzi mi farebbe piacere ricevere qualche richiesta di funzioni aggiuntive o modifiche. L'ultima versione è nell'ultimo post sempre di questo thread http://www.archlinux.it/forum/viewtopic.php?id=9086&p=1
    Ti ricordo di scaricare sia lo script vero e proprio sia il file di config nella stessa cartella, al primo avvio i occuperà lui di creare la directory dentro a ~/.config ed di piazzarci il file. Per vedere le (attualmente poche) opzioni di configurazione, basta guardare il file di config.

    RispondiElimina
  12. @Gianpiero
    Grazie mille!
    I tuoi posts, per motivi arcani, erano finiti in spam. Li ho ripristinati!
    Di nuovo, grazie infinite per la collaborazione, che spero possa continuare! ;-)

    RispondiElimina

EDIT 30/12/2017: abbiamo deciso di chiudere i commenti ma lasciare le guide intatte.

Nota. Solo i membri di questo blog possono postare un commento.