Servidor de impressão com cotas no FreeBSD (CUPS + PostgreSQL + PyKota)

Tutorial completo de como configurar um servidor de impressão com cotas no FreeBSD. Abordaremos a instalação e configuração do CUPS, PostgreSQL e PyKota.

[ Hits: 10.136 ]

Por: Ricardo Xerfan em 11/12/2018


Instalar e realizar a configuração básica do PyKota



Instalar o Python:

# pkg install python27-2.7.15 python2-2_3 python-2.7_3,2

Instalar as dependências do pykota:

OBS.: em virtude dos problemas citados no início do tutorial, é necessário uma pincelada básica sobre algumas dependências.

# pkg install py27-lxml-4.1.1 py27-wsaccel-0.6.2

py27-PyGreSQL-5.0.6,1 (precisa do "postgresql95-client-9.5.14")

PYTHON-SQLITE

ATENÇÃO: para instalar o "Python-SQLite" é necessário fazê-lo de forma manual (o pacote pode ser baixado na Internet). Procedimentos:

01. Copiar para dentro da máquina o arquivo "pysqlite-2.3.5.tar.gz" e extrair o pacote:

# tar xvfz pysqlite-2.3.5.tar.gz

02. Entrar no diretório do mesmo:

# cd pysqlite-2.3.5

03. Alterar o arquivo "setup.cfg", na linha "include_dirs=/usr/include" para "include_dirs=/usr/local/include/". Devendo ficar da forma abaixo:

[build_ext]
define=
include_dirs=/usr/local/include/
library_dirs=/usr/lib
libraries=sqlite3

04. Tornar executável o arquivo "setup.py":

# chmod +x setup.py

05. Executar o arquivo de instalação do pacote:

# python setup.py install

py27-MySQLdb-1.2.5_1 (precisa do "libedit-3.1.20170329_2,1", "mysql56-client-5.6.42", "libevent-2.1.8_2")

PYTHON-EGENIX-MXDATETIME

ATENÇÃO: para instalar o "Python-egenix-mxDateTime" é necessário fazê-lo de forma manual (o pacote pode ser baixado na Internet). Procedimentos:

01. Copiar para dentro da máquina o arquivo "egenix-mx-base-3.0.0.tar.gz" e extrair o pacote:

# tar xvfz egenix-mx-base-3.0.0.tar.gz

02. Entrar no diretório do mesmo:

# cd egenix-mx-base-3.0.0

03. Tornar executável o arquivo "setup.py":

# chmod +x setup.py

04. Executar o arquivo de instalação do pacote:

# python setup.py install

py27-ldap-3.1.0 (precisa do "py27-pyasn1-modules-0.2.2" e do "py27-pyasn1-0.4.2")

py27-osd-0.2.14_11 (precisa do "xosd-2.2.14_3", "py27-twisted-17.9.0", "py27-hyperlink-18.0.0", "py27-idna-2.7", "py27-zope.interface-4.1.3", "py27-incremental-17.5.0", "py27-constantly-15.1.0", "py27-Automat-0.7.0", "py27-six-1.11.0", "py27-attrs-18.2.0")

py27-snmp4-4.3.2 (precisa do "py27-pycrypto-2.6.1_3")

py27-jaxml-3.02_2

py27-reportlab-3.2.0 (precisa do "adobe-cmaps-20051217_3")

ATENÇÃO: o pacote "python-imaging" já é instalado como dependência no momento da instalação do CUPS descrita acima, porém, com nome de pacote diferente.

FALTA PYTHON-PSYCO.

pkpgcounter-3.50_3

FALTA PYTHON-PAM.

pkipplib-0.07

py27-chardet-3.0.4

Baixar o pacote do pykota:

Links:
Descompactar o pacote:

# unzip PyKota126fixed.zip

Entrar no diretório do mesmo:

# cd PyKota126fixed

Verificar se as dependências do PyKota estão instaladas:

# python2.7 checkdeps.py

ATENÇÃO: o resultado desse comando deve ser parecido com a saída abaixo (ignore os erros nos pacotes "Python-Psyco", "Python-PAM" e "Netatalk"):

# python2.7 checkdeps.py
Checking PyKota dependencies...
Checking for Python-PygreSQL availability : OK
Checking for Python-SQLite availability : OK
Checking for MySQL-Python availability : OK
Checking for Python-egenix-mxDateTime availability : OK
Checking for Python-LDAP availability : OK
Checking for Python-OSD availability : OK
Checking for Python-SNMP availability : OK
Checking for Python-JAXML availability : OK
Checking for Python-ReportLab availability : OK
Checking for Python-Imaging availability : OK
Checking for Python-Psyco availability : NO.
ERROR : Python-Psyco not available !
Python-Psyco speeds up parsing of print files, you should use it.
See http://psyco.sourceforge.net/
Checking for Python-pkpgcounter availability : OK
Checking for Python-PAM availability : NO.
ERROR : Python-PAM not available !
Python-PAM is recommended if you plan to use pknotify+PyKotIcon.
Grab it from http://www.pangalactic.org/PyPAM/
Checking for Python-pkipplib availability : OK
Checking for Python-chardet availability : OK
Checking for GhostScript availability : OK
Checking for SNMP Tools availability : OK
Checking for Netatalk availability : NO.
ERROR : Netatalk not available !
Netatalk is needed if you want to use AppleTalk enabled printers.


OBS.: as dependências "Python-Psyco", "Python-PAM" e "Netatalk" não foram encontradas, no entanto, não houve erros ao executar o pykota no ambiente de homologação, por isso, pode prosseguir o tutorial sem medo!

Estando tudo ok, vamos partir para a instalação do PyKota.

Ainda dentro do diretório que foi extraído o PyKota, execute o comando abaixo:

# python2.7 setup.py install

ATENÇÃO: esse arquivos binários (/usr/local/bin) abaixo devem ser verificados, caso ocorra algum erro:

autopykota
dumpykota
edpykota
pkbanner
pkbcodes
pkinvoice
pkmail
pknotify
pkprinters
pkrefund
pksetup
pksubscribe
pkturnkey
pkusers
pykosd
pykotme
repykota
warnpykota

Mais informações em: http://www.pykota.com/wiki/CommandLineTools

Testar o PyKota com o comando "pkusers":

# pkusers --help

ATENÇÃO: como ainda resta realizar algumas configurações, o comando acima vai retornar alguns erros conforme a saída abaixo:

ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 456, in deferredInit
ERROR:     Tool.deferredInit(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 185, in deferredInit
ERROR:     self.config = config.PyKotaConfig(confdir)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/config.py", line 49, in __init__
ERROR:     raise PyKotaConfigError, _("Configuration file %s can't be read. Please check that the file exists and that your permissions are sufficient.") % self.filename
ERROR: PyKotaConfigError: Configuration file /etc/pykota/pykota.conf can't be read. Please check that the file exists and that your permissions are sufficient.


Solucionar os erros:

Criar o diretório do PyKota em "/etc/pykota":

# cd /etc && mkdir pykota

Verificar se foi criado o diretório:

# ls -alh |grep pykota
drwxr-xr-x   2 root  wheel      512B Dec  5 09:11 pykota

Copiar os arquivos de configuração do pykota ("pykota.conf.sample" e "pykotadmin.conf.sample") para dentro do diretório recém criado com os nomes "pykota.conf" e "pykotadmin.conf", respectivamente:

# cp /usr/local/share/pykota/conf/pykota.conf.sample /etc/pykota/pykota.conf
# cp /usr/local/share/pykota/conf/pykotadmin.conf.sample /etc/pykota/pykotadmin.conf


Editar os arquivos de configuração recém copiados.

Alterar parâmetros do arquivo pykota.conf:

storagebackend: pgstorage
storageserver: IP_DO_SERVIDOR
storagename: pykota
storageuser : pykotauser
storageuserpw : readonlypw
accounter: software(/usr/local/bin/pkpgcounter)
preaccounter: software(/usr/local/bin/pkpgcounter)

Alterar o arquivo pykotadmin.conf:

storageadmin : pykotaadmin
storageadminpw : readwritepw

Executar novamente o comando "pkusers":

# pkusers --help

ATENÇÃO: os erros diferenciaram em alguns aspectos:

OBS.: se aparecer um erro parecido com o abaixo ("ERROR: Error: could not connect to server: Connection refused"; "ERROR: Is the server running on host "IP" (IP/32) and accepting"; "ERROR: TCP/IP connections on port 5432?:"), verifique as configurações iniciais do PostgreSQL no arquivo "postgresql.conf" citadas acima:

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 457, in deferredInit
ERROR:     self.storage = storage.openConnection(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storage.py", line 874, in openConnection
ERROR:     return storagebackend.Storage(pykotatool, host, database, admin, adminpw)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py", line 60, in __init__
ERROR:     raise PGError, msg
ERROR: Error: could not connect to server: Connection refused
ERROR:  Is the server running on host "IP" (IP/32) and accepting
ERROR:  TCP/IP connections on port 5432?
ERROR:  --- the most probable cause of your problem is that PostgreSQL is down, or doesn't accept incoming connections because you didn't configure it as explained in PyKota's documentation.


OBS.: se aparecer um erro parecido com o abaixo ("ERROR: Error: FATAL: no pg_hba.conf entry for host "IP", user "pykotaadmin", database "pykota", SSL off"), verifique as configurações iniciais do PostgreSQL no arquivo "pg_hba.conf" citadas acima:

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 457, in deferredInit
ERROR:     self.storage = storage.openConnection(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storage.py", line 874, in openConnection
ERROR:     return storagebackend.Storage(pykotatool, host, database, admin, adminpw)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py", line 60, in __init__
ERROR:     raise PGError, msg
ERROR: Error: FATAL:  no pg_hba.conf entry for host "IP", user "pykotaadmin", database "pykota", SSL off
ERROR:  --- the most probable cause of your problem is that PostgreSQL is down, or doesn't accept incoming connections because you didn't configure it as explained in PyKota's documentation.


OBS.: se o erro for parecido com o abaixo ("ERROR: Error: FATAL: role "pykotaadmin" does not exist"), pode prosseguir com o tutorial, senão volte e reveja ou refaça as configurações:

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 457, in deferredInit
ERROR:     self.storage = storage.openConnection(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storage.py", line 874, in openConnection
ERROR:     return storagebackend.Storage(pykotatool, host, database, admin, adminpw)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py", line 60, in __init__
ERROR:     raise PGError, msg
ERROR: Error: FATAL:  role "pykotaadmin" does not exist
ERROR:  --- the most probable cause of your problem is that PostgreSQL is down, or doesn't accept incoming connections because you didn't configure it as explained in PyKota's documentation.


Continuando a correção dos erros...

Criar o DB do PyKota no PostgreSQL:

ATENÇÃO: antes de criar o DB do PyKota, editar o arquivo "/usr/local/share/pykota/postgresql/pykota-postgresql.sql" e verificar se os usuários e senhas estão iguais as dos arquivos de configuração "pykota.conf" e "pykotadmin.conf":

CREATE DATABASE pykota WITH ENCODING='UTF-8';

--
-- Create the print quota database users
-- NOTE: Change the password values to the passwords you would like.
--
CREATE USER pykotauser WITH UNENCRYPTED PASSWORD 'readonlypw' NOCREATEDB NOCREATEUSER;
CREATE USER pykotaadmin WITH UNENCRYPTED PASSWORD 'readwritepw' NOCREATEDB NOCREATEUSER;

Verificado o arquivo, agora basta criar o DB:

# su - pgsql -c "psql -f /usr/local/share/pykota/postgresql/pykota-postgresql.sql template1"
CREATE DATABASE
CREATE ROLE
CREATE ROLE
You are now connected to database "pykota" as user "pgsql".
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE TABLE
REVOKE
REVOKE
GRANT
GRANT
GRANT


Executar novamente o comando "pkusers":

# pkusers --help

ATENÇÃO: os erros diferenciaram em alguns aspectos:

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 457, in deferredInit
ERROR:     self.storage = storage.openConnection(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storage.py", line 874, in openConnection
ERROR:     return storagebackend.Storage(pykotatool, host, database, admin, adminpw)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py", line 65, in __init__
ERROR:     self.quote = pg._quote
ERROR: AttributeError: 'module' object has no attribute '_quote'


Esse erro está relacionado ao código do arquivo "pgstorage.py" que tem de alterar algumas linhas (Mais informações em: https://forge.univention.org/bugzilla/show_bug.cgi?id=46575.

Continuando a correção dos erros:

Editar o arquivo "pgstorage.py" que fica localizado no caminho "/usr/local/lib/python2.7/site-packages/pykota/storages/":

# ee /usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py

ATENÇÃO: comentar as linhas 63 ("self.quote = self.database._quote"), 64 ("except AttributeError : # pg
raise PGError, msg
self.closed = 0
try :
#   self.quote = self.database._quote
#   except AttributeError : # pg
#   self.quote = pg._quote
    self.database.query("SET CLIENT_ENCODING TO 'UTF-8';")
    except PGError, msg :
    self.tool.logdebug("Impossible to set database client encoding to UTF-8 : %s" % msg)

VERIFICAR: a linha 90 ("self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))") deve estar comentada também:

def commitTransaction(self):
        """Commits a transaction."""
        self.database.query("COMMIT;")
        after = time.time()
        self.tool.logdebug("Transaction committed.")
        #self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))

VERIFICAR: a linha 97 ("self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))") deve estar comentada também:

def rollbackTransaction(self):
        """Rollbacks a transaction."""
        self.database.query("ROLLBACK;")
        after = time.time()
        self.tool.logdebug("Transaction aborted.")
        #self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))

VERIFICAR: a linha 112 ("#self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))") deve estar comentada também:

else:
        after = time.time()
        #self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
        return result

VERIFICAR: a linha 135 ("#self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))") deve estar comentada também:

else:
        after = time.time()
        #self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
        return result

ATENÇÃO: comentar as linhas 140 ("if type(field) == type(0.0) :"), 141 ("typ = "decimal""), 142 ("elif type(field) == type(0) :"), 143 ("typ = "int""), 144 ("elif type(field) == type(0L) :"), 145 ("typ = "int""), 146 ("else :"), 147 ("typ = "text""), 148 ("return self.quote(field, typ)") e adicionar a linha 149 ("return self.database.adapter.adapt_inline(field)" (sem aspas)):

def doQuote(self, field) :
"""Quotes a field for use as a string in SQL queries."""
#        if type(field) == type(0.0) :
#            typ = "decimal"
#        elif type(field) == type(0) :
#            typ = "int"
#        elif type(field) == type(0L) :
#            typ = "int"
#        else :
#            typ = "text"
#        return self.quote(field, typ)

return self.database.adapter.adapt_inline(field)

Executar novamente o comando "pkusers":

# pkusers --help

ATENÇÃO: se acontecer esse erro ("ERROR: IndentationError: unexpected indent"), identar o código inserido de acordo com o exemplo citado acima:

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
ERROR: PyKota v1.26_fixes_unofficial
ERROR: pkusers failed
ERROR: Traceback (most recent call last):
ERROR:   File "/usr/local/bin/pkusers", line 406, in
ERROR:     manager.deferredInit()
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/tool.py", line 457, in deferredInit
ERROR:     self.storage = storage.openConnection(self)
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storage.py", line 866, in openConnection
ERROR:     "%s.py" % backend.lower()))
ERROR:   File "/usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py", line 151
ERROR:     def prepareRawResult(self, result) :
ERROR:     ^
ERROR: IndentationError: unexpected indent


ATENÇÃO: se o resultado do comando "pkusers" for igual ao descrito abaixo, parabéns, você está quase lá!

# pkusers --help
WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.
pkusers v1.26_fixes_unofficial (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet - alet@librelogiciel.com

An Users and Groups Manager for PyKota.

command line usage :

pkusers [options] user1 user2 user3 ... userN

or :

pkusers --groups [options] group1 group2 group3 ... groupN

options :

-v | --version       Prints pkusers's version number then exits.
-h | --help          Prints this message then exits.

-a | --add           Adds users if they don't exist on the database.
                                 If they exist, they are modified unless
                                 -s|--skipexisting is also used.

-d | --delete        Deletes users from the quota storage.

-e | --email addr    Sets the email address for the users.
                                 If the addr parameter begins with @, then
                                 the username is prepended to addr to form
                                 a valid email address.

-D | --description d Adds a textual description to users or groups.

-g | --groups        Edit users groups instead of users.

-o | --overcharge f  Sets the overcharging factor applied to the user
                                 when computing the cost of a print job. Positive or
                                 negative floating point values are allowed,
                                 this allows you to do some really creative
                                 things like giving money to an user whenever
                                 he prints. The number of pages in a print job
                                 is not modified by this coefficient, only the
                                 cost of the job for a particular user.
                                 Only users have such a coefficient.

-i | --ingroups g1[,g2...]  Puts the users into each of the groups
                                                listed, separated by commas. The groups
                                                must already exist in the Quota Storage.

-L | --list          Lists users or groups.

-l | --limitby l     Choose if the user/group is limited in printing
                                 by its account balance or by its page quota.
                                 The default value is 'quota'. Allowed values
                                 are 'quota' 'balance' 'noquota' 'noprint'
                                 and 'nochange' :

                                        - quota : limit by number of pages per printer.
                                        - balance : limit by number of credits in account.
                                        - noquota : no limit, accounting still done.
                                        - nochange : no limit, accounting not done.
                                        - noprint : printing is denied.
                                 NB : nochange and noprint are not supported for groups.

-b | --balance b     Sets the user's account balance to b.
                                 Account balance may be increase or decreased
                                 if b is prefixed with + or -.
                                 WARNING : when decreasing account balance,
                                 the total paid so far by the user is decreased
                                 too.
                                 Groups don't have a real balance, but the
                                 sum of their users' account balance.

-C | --comment txt   Defines some informational text to be associated
                                 with a change to an user's account balance.
                                 Only meaningful if -b | --balance is also used.


-r | --remove        In combination with the --ingroups option above,
                                 remove users from the specified users groups.

-s | --skipexisting  In combination with the --add option above, tells
                                 pkusers to not modify existing users.

user1 through userN and group1 through groupN can use wildcards
if the --add option is not set.

examples :

$ pkusers --add john paul george ringo/ringo@example.com

This will add users john, paul, george and ringo to the quota
database. User ringo's email address will also be set to
'ringo@example.com'

$ pkusers --ingroups coders,it jerome

User jerome is put into the groups "coders" and "it" which must
already exist in the quota database.

$ pkusers --limitby balance jerome

This will tell PyKota to limit jerome by his account's balance
when printing.

$ pkusers --balance +10.0 --comment "He paid with his blood !" jerome

This will increase jerome's account balance by 10.0 (in your
own currency). You can decrease the account balance with a
dash prefix, and set it to a fixed amount with no prefix.
A comment will be stored for this balance change.

$ pkusers --delete jerome rachel

This will completely delete jerome and rachel from the quota
database. All their quotas and jobs will be deleted too.

$ pkusers --overcharge 2.5 poorstudent

This will overcharge the poorstudent user by a factor of 2.5.

$ pkusers --overcharge -1 jerome

User jerome will actually earn money whenever he prints.

$ pkusers --overcharge 0 boss

User boss can print at will, it won't cost him anything because the
cost of each print job will be multiplied by zero before charging
his account.

$ pkusers --email @example.com

This will set the email address for each user to username@example.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Please report bugs to : Jerome Alet - alet@librelogiciel.com


OBS.: observe que ainda resta um aviso ("WARN: The 'pykota' system account is missing. Configuration files were searched in /etc/pykota instead.") na saída do comando. Isso ocorre porque ainda falta criar o usuário pykota.

Criar o usuário pykota:

# adduser

ATENÇÃO: as informações devem ser colocadas igual ao exemplo abaixo:

Username: pykota
Full name: pykota
Uid (Leave empty for default):
Login group [pykota]:
Login group is pykota. Invite pykota into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh nologin) [sh]: nologin
Home directory [/home/pykota]: /etc/pykota
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]: no
Lock out the account after creation? [no]: no
Username   : pykota
Password   :
Full Name  : pykota
Uid        : 1002
Class      :
Groups     : pykota wheel
Home       : /etc/pykota
Home Mode  :
Shell      : /usr/sbin/nologin
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (pykota) to the user database.
Add another user? (yes/no): no
Goodbye!


Executar novamente o comando "pkusers":

# pkusers --help
pkusers v1.26_fixes_unofficial (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet - alet@librelogiciel.com
An Users and Groups Manager for PyKota.

...


ATENÇÃO: perceba que o erro não foi informado mais, isso significa que o PyKota já está quase 100% operacional, falta mais um detalhe:

Copiar o backend do pykota para dentro do diretório de backends do CUPS:

# cp /usr/local/share/pykota/cupspykota /usr/local/libexec/cups/backend/

Reiniciar o daemon do CUPS:

# /usr/local/etc/rc.d/cupsd restart

ou

# service cupsd restart

Acessar o frontend do CUPS no navegador e ir no menu "Administração" e clicar no botão "Adicionar impressora".

ATENÇÃO: perceba que ainda não aparece a opção para adicionar o backend do PyKota:

Impressoras locais:

CUPS-PDF (Virtual PDF Printer)
HP Printer (HPLIP)

Impressoras de rede descobertas:

HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)

Outras impressoras de rede:

Protocolo de Impressão para Internet (https)
Protocolo de Impressão para Internet (ipp)
Protocolo de Impressão para Internet (ipps)
Impressora ou máquina LPD/LPR
AppSocket/HP JetDirect
Windows Printer via SAMBA
Protocolo de Impressão para Internet (http)
Backend Error Handler


OBS.: existe um pequeno erro que passa despercebido, mas que faz o backend do pykota não funcionar. Para corrigir esse problema, retire o espaço após a "#!" e o "^M" na primeira linha ("#! /usr/bin/env python^M") do arquivo "cupspykota":

# ee /usr/local/libexec/cups/backend/cupspykota

#!/usr/bin/env python

ATENÇÃO: caso o python esteja em diretório diverso deste exemplo acima, altere a linha de acordo com a localização do mesmo:

#!/usr/local/bin/python

Salve o arquivo e reinicie o daemon do CUPS:

# /usr/local/etc/rc.d/cupsd restart

ou

# service cupsd restart

ATENÇÃO: perceba que ao retornar à página de "Administração/Adicionar impressora", o backend do PyKota já aparece dentre as opções:

Impressoras locais:

CUPS-PDF (Virtual PDF Printer)
HP Printer (HPLIP)
PyKota managed HP Printer (HPLIP) (PyKota+Unknown)
PyKota managed Virtual Printer (PyKota+Nothing)


Impressoras de rede descobertas:

HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)
HP LaserJet Pro MFP M127fn (HP LaserJet Pro MFP M127fn)

Outras impressoras de rede:

Protocolo de Impressão para Internet (https)
Protocolo de Impressão para Internet (ipp)
Protocolo de Impressão para Internet (ipps)
Impressora ou máquina LPD/LPR
AppSocket/HP JetDirect
Windows Printer via SAMBA
Protocolo de Impressão para Internet (http)
Backend Error Handler
PyKota managed Protocolo de Impressão para Internet (https) (PyKota+Unknown)
PyKota managed Protocolo de Impressão para Internet (ipp) (PyKota+Unknown)
PyKota managed Protocolo de Impressão para Internet (ipps) (PyKota+Unknown)
PyKota managed Impressora ou máquina LPD/LPR (PyKota+Unknown)
PyKota managed AppSocket/HP JetDirect (PyKota+Unknown)
PyKota managed Windows Printer via SAMBA (PyKota+Unknown)
PyKota managed Protocolo de Impressão para Internet (http) (PyKota+Unknown)
PyKota managed Backend Error Handler (PyKota+Unknown)


OBS.: não esqueça de forçar a atualização do navegador ("CTRL + F5" ou "CTRL + Shift + r"), caso contrário, não vai aparecer o backend do PyKota.

Agora mais alguns testes:

Executar o comando "pkprinters":

# pkprinters --help

ATENÇÃO: caso a saída do comando seja mostrada da forma como está abaixo, é porque falta retirar o espaço após a "#!" e o "^M" na primeira linha ("#! /usr/bin/env python^M") do arquivo "pkprinters":

: No such file or directory

OBS.: para corrigir isso, basta editar o arquivo e alterar a linha descrita acima:

# ee /usr/local/bin/pkprinters

ATENÇÃO: a primeira linha deve ficar assim:

#!/usr/bin/env python

Salvar o arquivo e repetir o comando "pkprinters":

# pkprinters --help

A saída deverá mostrar um "help" do comando.

ATENÇÃO: faça a correção acima para cada um dos comandos abaixo. Não esqueça de fazer o "comando --help", os que mostrarem o help não é necessário alterar, já os que apresentarem erro, estes devem ser alterados:
  • autopykota
  • dumpykota
  • edpykota
  • pkbanner
  • pkbcodes (talvez este não precise)
  • pkinvoice (talvez este não precise)
  • pkmail
  • pknotify (talvez este não precise)
  • pkprinters (se você chegou até aqui, não precisa editar este)
  • pkrefund (talvez este não precise)
  • pksetup (talvez este não precise)
  • pksubscribe (talvez este não precise)
  • pkturnkey (talvez este não precise)
  • pkusers (se você chegou até aqui, não precisa editar este)
  • pykosd
  • pykotme
  • repykota
  • warnpykota

Adicionar impressora no frontend do CUPS com o backend do PyKota:

ATENÇÃO: para adicionar a impressora, é necessário escolher um backend do PyKota na página de administração do PyKota em seu frontend. Para este exemplo foi utilizada a opção "PyKota managed AppSocket/HP JetDirect (PyKota+Unknown)":

Na caixa "Conexão" adicione a linha abaixo (não esqueça de alterar o IP da impressora):

cupspykota:socket://IP.da.Impressora:9100

Depois é só finalizar a adição da impressora normalmente.

OBS.: se for enviar qualquer impressão para a impressora recém configurada com o backend do PyKota, a impressão não vai sair em virtude de que não existe nenhuma impressora e nenhum usuário cadastrados no DB do PyKota e, nenhum usuário está atrelado a impressora em questão, logo ninguém está autorizado a imprimir na mesma. Isso pode ser constatado no log, basta tentar imprimir e depois visualizar o arquivo de logs ("/var/log/messages") do próprio FreeBSD. Veja a saída do log de testes:

# tail -f /var/log/messages
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => Tentando identificação lógica (/usr/local/bin/pkpgcounter)...
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => Código de erro para contador lógico /usr/local/bin/pkpgcounter : 0
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => Impressora PRINTER01-tutorial-cups-pykota não registada no sistema Pykota, foi aplicada por omissão a política (DENY)
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => Usuario root não registrado no sistema PyKota, aplicando configurações padrões (DENY) para a impressora PRINTER01-tutorial-cups-pykota
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => O utilizador root não tem cota na impressora PRINTER01-tutorial-cups-pykota, foi aplicada por omissão a política (DENY)
Dec 6 10:11:39 pykota-tuto PyKota: (PID 963) : root@PRINTER01-tutorial-cups-pykota(4) => Printing is denied by printer policy.


Hora de povoar o DB do PyKota:

OBS.: como o objetivo aqui não é esgotar todas as possibilidades dos comandos citados, para mais informações você pode consultar a qualquer momento o help do comando que desejar, bastando, para isso, digitar "comando --help".

Adicionar usuário ao DB do PyKota:

# pkusers -a root

ou

# pkusers --add root

# pkusers -a root
Creation...
Done. Average speed : 15.23 entries per second.


ATENÇÃO: o nome de usuário a ser adicionado ao DB do PyKota deve ser EXATAMENTE o mesmo nome de usuário da máquina ou do domínio, EXCLUÍDO o nome do domínio (@domínio.com).

Listar usuários adicionados ao PyKota:

# pkusers -L

ou

# pkusers --list

root -
Limited by : quota
Account balance : 0.00
Total paid so far : 0.00
Overcharging factor : 1.00


ATENÇÃO: como ainda, não foi adicionada nenhuma impressora ao banco do PyKota e, por questão de lógica, o usuário recém criado criado não está atrelado a nenhuma. Portanto, se for enviar qualquer impressão, a mesma não irá sair e o log apresentado será quase igual ao anterior, com uma diferença: a linha "Usuario root não registrado no sistema PyKota, aplicando configurações padrões (DENY) para a impressora PRINTER01-tutorial-cups-pykota" não será exibida, pois o usuário já está registrado no DB do PyKota.

Adicionar impressora ao DB do PyKota:

# pkprinters -a PRINTER01-tutorial-cups-pykota

ou

# pkprinters -a PRINTER01-tutorial-cups-pykota

Creation...
Done. Average speed : 36.78 entries per second.
You have new mail.


Listar impressoras adicionadas ao PyKota:

# pkprinters -l

ou

# pkprinters --list

PRINTER01-tutorial-cups-pykota [] (0.0 + #*0.0)
Passthrough mode : OFF
Maximum job size : Unlimited
Routed through PyKota : YES


ATENÇÃO: como, ainda, não foi atrelado o usuário à impressora, se for enviar qualquer impressão, esta continuará sendo negada, observe o log abaixo:

# tail -f /var/log/messages
Dec 6 11:18:54 pykota-tuto PyKota: (PID 1532) : root@PRINTER01-tutorial-cups-pykota(7) => Tentando identificação lógica (/usr/local/bin/pkpgcounter)...
Dec 6 11:18:54 pykota-tuto PyKota: (PID 1532) : root@PRINTER01-tutorial-cups-pykota(7) => Código de erro para contador lógico /usr/local/bin/pkpgcounter : 0
Dec 6 11:18:54 pykota-tuto PyKota: (PID 1532) : root@PRINTER01-tutorial-cups-pykota(7) => O utilizador root não tem cota na impressora PRINTER01-tutorial-cups-pykota, foi aplicada por omissão a política (DENY)
Dec 6 11:18:54 pykota-tuto PyKota: (PID 1532) : root@PRINTER01-tutorial-cups-pykota(7) => Printing is denied by printer policy.


Atrelar usuário à impressora no PyKota, já criando a cota de impressão:

# edpykota -P PRINTER01-tutorial-cups-pykota -S 4 -H 5 -a root

ou

# edpykota --printer PRINTER01-tutorial-cups-pykota -S 4 -H 5 -a root

Extracting datas...
Creation...
Done. Average speed : 40.72 entries per second.


Listar cotas do usuário na impressora:

# edpykota -L

ou

# edpykota --list
Page counter : 0
Lifetime page counter : 0
Soft limit : 4
Hard limit : 5
Date limit : None
Maximum job size : Unlimited (Not supported yet)
Warning banners printed : 0

ATENÇÃO: a partir de agora o usuário root já pode imprimir qualquer trabalho e quando chegar ao limite de impressões estipulado no "edpykota", automaticamente o mesmo não poderá mais imprimir, a não ser que seja resetada ou incrementada a cota. Observe o log da impressão:

# tail -f /var/log/messages
Dec 6 11:47:53 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Tentando identificação lógica (/usr/local/bin/pkpgcounter)...
Dec 6 11:47:54 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Código de erro para contador lógico /usr/local/bin/pkpgcounter : 0
Dec 6 11:47:54 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Início da contagem da tarefa.
Dec 6 11:47:56 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => CUPS backend /usr/local/libexec/cups/backend/socket returned 0.
Dec 6 11:47:56 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Fim da contagem da tarefa.
Dec 6 11:47:56 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Tamanho da tarefa : 1
Dec 6 11:47:56 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Atualizando cota do usuário root para a impressora PRINTER01-tutorial-cups-pykota
Dec 6 11:47:56 pykota-tuto PyKota: (PID 1974) : root@PRINTER01-tutorial-cups-pykota(12) => Tarefa adicionada ao histórico


Se for mandar listar a cota do usuário, ela será listada de acordo com a quantidades de páginas já impressas. Observe:

Page counter : 1
Lifetime page counter : 1
Soft limit : 4
Hard limit : 5
Date limit : None
Maximum job size : Unlimited (Not supported yet)
Warning banners printed : 0

Observe o log de quando a cota do usuário chegou ao fim, perceba que a impressão foi negada:

# tail -f /var/log/messages
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Tentando identificação lógica (/usr/local/bin/pkpgcounter)...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Código de erro para contador lógico /usr/local/bin/pkpgcounter : 0
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Quota de impressão excedida para o usuario root na impressora PRINTER01-tutorial-cups-pykota
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Job denied, no accounting will be done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Banner won't be printed : maximum number of deny banners reached.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Banner won't be printed : maximum number of deny banners reached.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Job denied, no accounting has been done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Tamanho da tarefa zerado porque a impressão foi negada
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Tamanho da tarefa : 0
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Tarefa adicionada ao histórico


Observe a listagem com o comando "edpykota", perceba que ele já mostra a data e a hora na qual o usuário atingiu o limite de impressões:

Page counter : 4
Lifetime page counter : 4
Soft limit : 4
Hard limit : 5
Date limit : 2018-12-13 11:56:12
Maximum job size : Unlimited (Not supported yet)
Warning banners printed : 0

ATENÇÃO: como se pode observar abaixo, é gerado um log de todos os comandos digitados e alterações feitas no arquivo "/var/log/debug.log".

Log do comando para adicionar usuários:

Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Command line arguments : "/usr/local/bin/pkusers" "-a" "root"
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Trying to open database (host=IP, port=5432, dbname=pykota, user=pykotaadmin)...
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Database opened (host=IP, port=5432, dbname=pykota, user=pykotaadmin)
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Beware : running as a PyKota administrator !
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Transaction begins...
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : QUERY : SELECT * FROM users WHERE username='root' LIMIT 1;
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : QUERY : INSERT INTO users (username, limitby, balance, lifetimepaid, email, overcharge, description) VALUES ('root', 'quota', 0.0, 0.0, NULL, 1.0, NULL);
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Transaction committed.
Dec 6 10:32:24 pykota-tuto PyKota: (PID 1156) : Database closed.



Log do comando para listar usuários:

Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : Command line arguments : "/usr/local/bin/pkusers" "-L"
Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : Trying to open database (host=IP, port=5432, dbname=pykota, user=pykotaadmin)...
Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : Database opened (host=IP, port=5432, dbname=pykota, user=pykotaadmin)
Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : Beware : running as a PyKota administrator !
Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : QUERY : SELECT * FROM users;
Dec 6 10:32:43 pykota-tuto PyKota: (PID 1169) : Database closed.


Log da impressão:

Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Command line arguments : "/usr/local/libexec/cups/backend/cupspykota" "16" "root" "Test Page" "1" "job-uuid=urn:uuid:... job-originating-host-name=localhos
Dec 6 11:57:33 pykota-tuto hpcups[2118]: prnt/hpcups/Hbpl1.cpp 52: Hbpl1 constructor : m_szLanguage = HBPL1
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Trying to open database (host=IP, port=5432, dbname=pykota, user=pykotaadmin)...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Database opened (host=IP, port=5432, dbname=pykota, user=pykotaadmin)
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Beware : running as a PyKota administrator !
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Disabling SIGINT...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : SIGINT disabled.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Installing SIGTERM handler...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : SIGTERM handler installed.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : Initializing backend...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Querying CUPS server...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => CUPS server answered without error.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Backend : socket
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => DeviceURI : socket://IP.da.Impressora:9100
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Printername : PRINTER01-tutorial-cups-pykota
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Username : root
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => JobId : 16
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Title : Test Page
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Filename : None
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Copies : 1
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Options : job-uuid=urn:uuid:... job-originating-host-name=localhost date-time-at-creation= date-time-at-processi
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Directory : /tmp
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => DataFile : /tmp/cupspykota-PRINTER01-tutorial-cups-pykota-root-16
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => ControlFile : NotUsedAnymore
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => JobBillingCode : None
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => JobOriginatingHostName : localhost
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Enabling SIGINT...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => SIGINT enabled.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Backend initialized.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Waiting for lock /tmp/cupspykota-socket...IP.da.Impressora.9100..LCK to become available...
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Lock /tmp/cupspykota-socket...IP.da.Impressora.9100..LCK acquired.
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Duplicating data stream into /tmp/cupspykota-PRINTER01-tutorial-cups-pykota-root-16
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Reading input datas from stdin
Dec 6 11:57:33 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => 65536 bytes saved...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => JobSizeBytes : 909983
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => JobMD5Sum : 2ca2b282fb9ba209b1d8839e574943f3
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Data stream duplicated into /tmp/cupspykota-PRINTER01-tutorial-cups-pykota-root-16
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting job information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Precomputing job's size...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Using external script /usr/local/bin/pkpgcounter to compute job's size.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Software accounter /usr/local/bin/pkpgcounter said job is 1 pages long.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Precomputed job's size is 1 pages.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting job information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Sanitizing job's attributes...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Checking if we need to overwrite the job ticket...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Job ticket overwriting done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Username : root
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => BillingCode : None
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Title : Test Page
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Job's attributes sanitizing done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting job information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Retrieving printer, user, and user print quota entry from database...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT * FROM printers WHERE printername='PRINTER01-tutorial-cups-pykota' LIMIT 1;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT * FROM users WHERE username='root' LIMIT 1;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT * FROM userpquota WHERE userid=2 AND printerid=2;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Retrieval of printer, user and user print quota entry done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Precomputing job's price...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=2;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Precomputed job's price is 0.000 credits.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting user information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting printer information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=2;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting phase information [BEFORE] to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Retrieving billing code information from the database...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Retrieval of billing code information done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Checking if the job is a duplicate...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => We don't care about duplicate jobs after all.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Checking if the job is a duplicate done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Checking user root print quota entry on printer PRINTER01-tutorial-cups-pykota
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : SELECT groupname FROM groupsmembers JOIN groups ON groupsmembers.groupid=groups.id WHERE userid=2;
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Checking user root's quota on printer PRINTER01-tutorial-cups-pykota
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting job's action status...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Sending some feedback to user root...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Feedback sent to user root.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Handling starting banner with accounting...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Starting banner done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting phase information [AFTER] to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Handling ending banner with accounting...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Ending banner done.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Transaction begins...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => QUERY : INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, hostname, job
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Transaction committed.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting job's size and price information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Exporting user information to the environment...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Environment updated.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Cleaning up...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Regained priviledges. Now running as root.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Deinstalling SIGTERM handler...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => SIGTERM handler deinstalled.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Work file /tmp/cupspykota-PRINTER01-tutorial-cups-pykota-root-16 will be deleted.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Work file /tmp/cupspykota-PRINTER01-tutorial-cups-pykota-root-16 has been deleted.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Database closed.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Unlocking /tmp/cupspykota-socket...IP.da.Impressora.9100..LCK...
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => /tmp/cupspykota-socket...IP.da.Impressora.9100..LCK unlocked.
Dec 6 11:57:35 pykota-tuto PyKota: (PID 2120) : root@PRINTER01-tutorial-cups-pykota(16) => Clean.


INFORMAÇÕES ADICIONAIS

O PyKota gera um arquivo com a extensão "*.LCK" dentro do diretório "/tmp". Às vezes pode acontecer do backend do PyKota travar, com isso ele nem ao menos aparece dentre as opções de backend na página de administração do PyKota em seu frontend. Para resolver isto, basta apenas deletar esse arquivo que ele volta a funcionar normalmente.

Os logs do CUPS podem ser encontrados no diretório "/var/log/cups/".

Pronto!!! Com todas essas configurações já é possível ter um servidor de impressão com cotas funcional e gratuito.

END OF FILE - Graças a Deus tudo certo!!!

Feito, escrito e testado por Ricardo Xerfan. Macapá-AP.

Página anterior    

Páginas do artigo
   1. Introdução
   2. Instalar e configurar o CUPS
   3. Instalar e realizar a configuração básica do PostgreSQL
   4. Instalar e realizar a configuração básica do PyKota
Outros artigos deste autor

Configurando o FreeBSD e PyKota para receber o JPyKotaGUI

Leitura recomendada

Acentuação gráfica no console FreeBSD/FreeNAS e montagem de pastas de compartilhamento Windows com acentuação

Instalação de Aplicativos no FreeBSD

Introdução ao FreeBSD

Configurando rede wireless com wpa_supplicant

O Mascote do FreeBSD é um demônio?

  
Comentários
[1] Comentário enviado por xerxeslins em 12/12/2018 - 15:33h

Artigo gigante! Bem, vou favoritar, para consultar um dia quando for usar FreeBSD. ;-]

--
"There are lots of Linux users who don't care how the kernel works, but only want to use it. That is a tribute to how good Linux is." - Linus Torvalds

[2] Comentário enviado por pbonfanti em 04/01/2019 - 08:13h

Excelente artigo, pretendo testar o sistema ,mas acho importante informar logo no início do artigo com qual Release do FreeBSD você testou.
Na linha Logo abaixo "Testes restantes", após instalar o postgresql, o comando
$ pgsql dbteste
Retorna comando não encontrado, mas responde a:
$ psql dbteste
dbteste# \list

[3] Comentário enviado por ricardo-xerfan em 07/01/2019 - 23:05h


[1] Comentário enviado por xerxeslins em 12/12/2018 - 15:33h

Artigo gigante! Bem, vou favoritar, para consultar um dia quando for usar FreeBSD. ;-]

--
"There are lots of Linux users who don't care how the kernel works, but only want to use it. That is a tribute to how good Linux is." - Linus Torvalds



Tamo junto meu nobre!!

[4] Comentário enviado por ricardo-xerfan em 07/01/2019 - 23:20h


[2] Comentário enviado por pbonfanti em 04/01/2019 - 08:13h

Excelente artigo, pretendo testar o sistema ,mas acho importante informar logo no início do artigo com qual Release do FreeBSD você testou.
Na linha Logo abaixo "Testes restantes", após instalar o postgresql, o comando
$ pgsql dbteste
Retorna comando não encontrado, mas responde a:
$ psql dbteste
dbteste# \list


Fale meu nobre!!

Obrigado pelo retorno!! O comando certo é "psql dbteste".

Percebi, também, que após a publicação, não ficou boa a "identação" deste exemplo do código no arquivo "usr/local/lib/python2.7/site-packages/pykota/storages/pgstorage.py " na linha 149:

return self.database.adapter.adapt_inline(field)

Então, pode ser que apresente erro de "identação". Caso ocorra, basta "identar" o código de acordo com as outras linhas do bloco em questão.

Qualquer dúvida ou observação, basta chamar!

Grande abraço!

[5] Comentário enviado por ricardo-xerfan em 10/01/2019 - 11:41h

Comentários relevantes ao tutorial: LEIA COM ATENÇÃO:

Para adicionar impressoras em compartilhamentos Windows, vc pode fazer da seguinte forma:

01. Configurar, no servidor onde está o CUPS, o arquivo "smb4.conf" (/usr/local/etc/smb4.conf) de acordo com seu ambiente;

02. Adicionar a impressora com a opção "PyKota managed Windows Printer via SAMBA (PyKota+Unknown)";

03. Configurar a conexão da seguinte forma:

cupspykota:smb://username:password@domain/hostname_or_IP/printer_name

Exemplo:

cupspykota:smb://ricardo:12345@dominio.local/192.168.1.5/Lexmark%20PROTOCOLO

OBS.: Se o nome da impressora contiver espaço, no lugar do espaço, coloque "%20" (sem aspas). Exemplo:

Nome real da impressora: Lexmark PROTOCOLO

Como deve ser colocado na conexão: Lexmark%20PROTOCOLO

ATENÇÃO: Por padrão o CUPS não permite que os usuários remotos façam requisições de impressões ou gerenciamento nas impressoras que estão configuradas nele. Portanto, para que qualquer usuário remoto, "dentro de sua rede", consiga realizar tais tarefas, é necessário que vc habilite isso no CUPS através de linha de comando. Basta digitar no terminal o seguinte:

cupsctl --share-printers

OBS.1: Se vc não fizer o comando acima, os usuários remotos não vão conseguir fazer nada na impressora.
OBS.2: Para que vc possa instalar a impressora em um host de sua rede, é necessário ter privilégios administrativos. Basta adicionar a impressora com uma conta de administrador que os outros usuários terão acesso a mesma.
OBS.3: Para adicionar a impressora a um host Windows, faça da seguinte forma:
OBS.3.1: Abrir o frontend de gerenciamento do CUPS;
OBS.3.2: Ir no menu impressoras;
OBS.3.3: Selecionar, da sua lista de impressoras que já foram adicionadas ao CUPS, a impressora que vc deseja;
OBS.3.4: Copiar a URL da impressora. Exemplo:
https://IP-Servidor-CUPS:631/printers/Printer-PROTOCOLO01
OBS.3.5: Ir no painel de controle do Windows, em "Dispositivos e Impressoras" e depois em "Adicionar uma impressora". Clicar em "A impressora que eu quero não está na lista". Na tela que vai abrir, selecionar a opção "Selecionar uma impressora compartilhada pelo nome". Colar no espaço indicado a URL que foi copiada. Depois clicar em "Avançar" e proceder normalmente com as outras opções. Lembrando mais uma vez que É NECESSÁRIO TER PRIVILÉGIOS ADMINISTRATIVOS para adicionar a impressora no host Windows;
OBS.3.6: Não esquecer de configurar as permissões dentro do PyKota em linha de comando (adicionar impressora, usuário e atrelar a impressora ao usuário), como foi mostrado no tutorial.

Grande abraço!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts