Backport de drivers de impresora en ubuntu

2018/03/12

Se necesita imprimir a una impresora Datamax-O’Neil E-4205A desde ubuntu 14.04.

El problema es que el soporte para esta impresora recién está agregado a partir de la release 5.2.12 de Gutenprint y en ubuntu 14.04, de la página correspondiente al paquete gutenprint se obtiene que la versión disponible es la 5.2.10~pre2-0ubuntu2.

De lo anterior se ve que es necesario realizar un backport del paquete.

Navegando en la página del paquete de ubuntu, https://packages.ubuntu.com/source/trusty/gutenprint se encuentra que recién para artful la versión es la 5.2.13-1, la cual utilizaremos como base para realizar el backport.

Setup del ambiente de trabajo

Como ambiente de trabajo se utilizará vagrant con una imagen de ubuntu trusty 32bits a la que se le instalarán los paquetes necesarios para realizar el backport.

A continuación el contenido de los archivos utilizados con vagrant:

Vagrantfile

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty32"
  config.vm.define "backport-gutenprint"
  config.vm.synced_folder ".", "/vagrant", type: "sshfs"

  config.vm.provider :virtualbox do |v|
    v.customize ["modifyvm", :id, "--memory", 2048]
    v.customize ["modifyvm", :id, "--cpus", 2]
  end

  config.vm.provision "shell", path: "provision.sh"
end

.vagrantplugins

# See: https://github.com/hashicorp/vagrant/issues/4347

required_plugins = {
  'vagrant-sshfs' => '~>1.3.0',
}

needs_restart = false
required_plugins.each do |name, version|
  unless Vagrant.has_plugin? name, version
    system "vagrant plugin install #{name} --plugin-version=\"#{version}\""
    needs_restart = true
  end
end

if needs_restart
  exec "vagrant #{ARGV.join' '}"
end

provision.sh

#!/bin/bash -x
set -e

# install packages needed for create the backports
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -qVy packaging-dev devscripts equivs

Creación del entorno (vm) y conexión a este

Con los archivos anteriores en el mismo directorio creamos la vm con vagrant utilizando vagrant up. Para conectarnos luego de creada la vm se utiliza vagrant ssh.

Ya en la vm, nos aseguramos de que estamos en el directorio $HOME, y que están definidas las variables de entorno DEBFULLNAME y DEBEMAIL:

$ cd ~
$ export DEBFULLNAME="Juan Picca"
$ export DEBEMAIL="jumapico@gmail.com"

NOTA:

Como directorio de trabajo no puede elegirse el directorio /vagrant, ya que este está montado mediante sshfs, y ello impide cambiar al dueño de los archivos a partir del punto de montaje, operación necesaria para la construcción de paquetes.

Por ejemplo, en caso de utilizar mk-build-deps en el directorio /vagrant se obtiene el siguiente error:

/vagrant$ mk-build-deps gutenprint
Use of uninitialized value $fullname in concatenation (.) or string at /usr/bin/equivs-build line 210.
dh_testdir
dh_testroot
dh_prep
dh_testdir
dh_testroot
dh_install
dh_installdocs
install: cannot change ownership of ‘debian/gutenprint-build-deps/usr/share/doc/gutenprint-build-deps/README.Debian’: Permission denied
dh_installdocs: install -g 0 -o 0 -m 644 -p debian/README.Debian debian/gutenprint-build-deps/usr/share/doc/gutenprint-build-deps/README.Debian returned exit code 1
make: *** [binary-indep] Error 2
Error in the build process: exit status 2

Preparación del backport

Instalación de dependencias

Para realizar el backport se utilizarán como base las indicaciones dadas en https://wiki.debian.org/SimpleBackportCreation.

Primeramente se obtiene el fuente del paquete gutenprint utilizando el enlace al archivo dsc de la página del paquete (source)

$ dget -x http://archive.ubuntu.com/ubuntu/pool/main/g/gutenprint/gutenprint_5.2.13-1.dsc

Luego se utiliza mk-build-deps para crear un paquete trivial de nombre gutenprint-build-deps con las dependencias necesarias para construir el paquete gutenprint. La ventaja de instalar el paquete respecto a utilizar apt-get build-deps es que al eliminarlo todas las dependencias que fueron instaladas quedan marcadas para autoremover en lugar de quedar marcadas como instaladas automáticamente.

Nota: Esto no es estrictamente necesario ya que se está utilizando una máquina virtual, pero se realiza ya que se ve como una buena práctica

$ sudo mk-build-deps --install --remove gutenprint_5.2.13-1.dsc

Actualización del número de versión

Se crea una nueva versión para el backport:

$ cd ~/gutenprint-5.2.13
$ dch --local ~ubuntu14.04. --distribution trusty-backports "Rebuild for trusty-backports."

Como formato de versión del backport se utiliza el indicado en la página del manual del programa backportpackage:

backportpackage  will  always append ~ubuntuDESTINATION.1 to the
original version number

NOTAS:

  1. En la guía de empaquetado de ubuntu http://packaging.ubuntu.com/html/ubuntu-dev-tools.html#backporting-packages se menciona el programa backportpackage para realizar backports.
  2. Se pueden ver las versiones de los paquetes en el repositorio trusty-backports: https://packages.ubuntu.com/trusty-backports/allpackages. De allí se deduce que se utiliza el formato de versión mencionado en la página del manual de backportspackage.
  3. Los detalles del formato de un backport para un paquete en debian se encuentran mucho más facilmente en el sitio https://backports.debian.org/Contribute/, sección Basic Rules.

Generación del paquete

Para generar el paquete se utiliza el comando dpkg-buildpackage:

$ dpkg-buildpackage -us -uc
dpkg-buildpackage: source package gutenprint
dpkg-buildpackage: source version 5.2.13-1~ubuntu14.04.1
dpkg-buildpackage: source distribution trusty-backports
dpkg-buildpackage: source changed by Juan Picca <jumapico@gmail.com>
dpkg-buildpackage: host architecture i386
 dpkg-source --before-build gutenprint-5.2.13
dpkg-checkbuilddeps: Unmet build dependencies: debhelper (>= 10.2.5~)
dpkg-buildpackage: warning: build dependencies/conflicts unsatisfied; aborting
dpkg-buildpackage: warning: (Use -d flag to override.)

El error es debido a que la versión de debhelper disponible en ubuntu 14.04 es la 9 (se puede utilizar apt show debhelper para una descripción del paquete instalado).

Para evitar el problema se prueba de editar el archivo debian/control y bajar la versión de debhelper, de 10 a 9 y se vuelve a intentar:

$ cat debian/control | grep debhelper
 debhelper (>= 10.2.5~),
$ sed -i 's/ debhelper.*$/ debhelper (>= 9),/' debian/control
$ dpkg-buildpackage -us -uc

Esta vez se logró generar los paquetes sin problemas.

Para obtener los paquetes del entorno de trabajo al host se pueden copiar los archivos generados al directorio /vagrant, que está montado al host mediante sshfs.

$ cd ~
$ dcmd cp gutenprint_5.2.13-1~ubuntu14.04.1_i386.changes /vagrant/

Uso de backportpackage

Previamente se siguieron los pasos indicados en https://wiki.debian.org/SimpleBackportCreation para crear el backport, pero en http://packaging.ubuntu.com/html/ubuntu-dev-tools.html#backporting-packages, se sugiere utilizar el programa backportpackage.

A continuación se probará utilizar dicho método.

Creación del entorno

Este paso es idéntico al precedente, ya que en ubuntu el paquete packaging-dev instala como recomendado el paquete ubuntu-dev-tools, el cual contiene el script backportpackage. Se deben definir las variables de entorno DEBFULLNAME y DEBEMAIL como fué hecho anteriormente.

Configuración de pbuilder

El comando backportpackage requiere tener configurado pbuilder para crear el backport del paquete:

$ cat <<'END' | sudo tee /etc/pbuilderrc
MIRRORSITE=http://archive.ubuntu.com/ubuntu
DISTRIBUTION=trusty
export DEBIAN_FRONTEND="noninteractive"
END
$ sudo pbuilder create

Lo anterior configura la distribución utilizada por pbuilder, y crea el archivo base.tgz.

Creación del backport

Siguiendo las indicaciones de la página del manual de backportpackage:

$ backportpackage --build --source artful --destination trusty -w . gutenprint
...
dpkg: pbuilder-satisfydepends-dummy: dependency problems, but configuring anyway as you requested:
 pbuilder-satisfydepends-dummy depends on debhelper (>= 10.2.5~); however:
  Package debhelper is not installed.
...

Y como nos pasó anteriormente encontramos el problema de que la versión de debhelper disponible en el sistema no cumple con las dependencias del paquete. En este caso, a diferencia de realizar los pasos manualmente no hay forma de modificar la versión de debhelper a utilizar, por lo que la alternativa que queda sería realizar un backport de debhelper, y de las dependencias de este a medida que sea necesario, lo cual no es una opción.

De lo anterior, backportpackage es útil en el caso de que pueda realizarse un backport del paquete sin ningún cambio. Si algún cambio es requerido se debe modificar manualmente el paquete.