Showing posts with label package. Show all posts
Showing posts with label package. Show all posts

16 July, 2010

Easing System Setup with Debian Packages

Seems like every 6 months or so I feel like reinstalling Linux on my workstation. Not because I need to, but more because I want to.

Seems as my interests wander I find the need to install loads of packages for temporary tasks, once accomplished I want to remove them. Unfortunately, I don't keep track of the packages and as a result start a-fresh periodically.

I do it often enough that it doesn't take too much time. Much of it is just the identification and reinstallation of packages I regularly use.

Authoring a system installation package that identifies all my essential packages as a dependency seems as it would minimize this effort dramatically. Since packages can define dependencies and installing it can auto-resolve and install the required dependencies seems like if we authored a faux package with dependencies on the packages I want installed we'd be right on mark.

Let's start;

Start by creating a directory.

$ mkdir ~/myPackage


Next, create the necessary control file which will identify the dependencies.

$ mkdir ~/myPackage/DEBIAN
$ edit ~/myPackage/DEBIAN/control

Populate ~/myPackage/DEBIAN/control with the following:
Package: MyPackage
Version: 1.0
Section: web
Priority: optional
Architecture: all
Essential: no
Depends: gnuplot, tcl
Pre-Depends: gnuplot
Recommends:
Suggests:
Installed-Size: 1024
Maintainer: Joe Brockmeier [jzb@dissociatedpress.net]
Conflicts: wile-e-coyote
Replaces: sam-sheepdog
Provides: acme
Description: The description can contain free-form text
describing the function of the program, what
kind of features it has, and so on.

Pay special attention to the Depends: field, it's populated with tcl and gnuplot. That means, when we install this package we ask that these dependencies are installed as well.

Next, create the package by executing the following command:

$ dpkg -b ~/myPackage /tmp/myPackage.deb


All set, now just install the package as root and you'll achieve an indirect installation of the dependencies.


# gdebi /tmp/myPackage.deb


Cheers.

09 February, 2009

Creating Debian Packages

I have to admit, one of the most appealing features of Debian is the ease of package management. While we've authored many tool suites to be used in analysis, field testing, or development I've yet to package them into a distribution package. While I've always wanted to, I've never taken the initiative to investigate how to do it. Today I'll be documenting my journey into authoring my first Debian distribution package.

Debian Packages
A package is a simple collection of files with instructions of what to do with them. While most often packages consist of executables, they may instead contain source code, window themes, or other file collections. Since I'm interested in maintaining executables I'll focus on the binary distribution package. I start my journey by issuing the command 'man deb'.

File Contents
All binary Debian packages consist of 3 basic files: 1 text file, and 2 compressed tarballs. You can examine the contents of a Debian package yourself by using the archive command to list the file contents. For example,


$ ar -t /var/cache/apt/archives/telnet_0.17-34_amd64.deb
debian-binary
control.tar.gz
data.tar.gz


You can examine the content of each file by extracting them from the archive, done by issuing the following command:

$ ar -x /var/cache/apt/archives/telnet_0.17-34_amd64.deb


debian-binary
This file contains the version number for the binary package, which should be 2.0.

control.tar.gz
This gzipped archive contains the control file, a postinst file, a prerm file and may optionally contain info about configuration files for the package and a MD5 checksums for the package. You can examine the contents of this archive by issuing:

$ tar -ztf ./control.tar.gz
./
./postinst
./prerm
./postrm
./md5sums
./control

The only mandatory file in this archive is the control file which contains the core control info for the package.
control
Issuing the command 'man deb-control' documents the contents of the mandatory and optional fields for the control file. The file consists of mandatory and optional fields. The mandatory fields are listed with brief descriptions of each.
Package: This value identifies the name of the package.
Version: This field identifies the version number. The use of a hyphen identifies the Debian revision number so the package author is restricted from using the hyphen the version number.
Maintainer: This should be defined in the format of full name followed by e-mail address 'Joe Bloggs '.
Description: This field should provide a brief description of the package as the first line. This should be followed by a more detailed package description where each line begins with a space.

data.tar.gz
This file contains the actual “payload” of the package. This means that it contains a filesystem with all the relevant files for the program that when installed will be placed in the appropriate spots on the destination systems file system.


$ tar -ztf ./data.tar.gz
./
./usr/
./usr/bin/
./usr/bin/telnet.netkit
./usr/share/
./usr/share/doc/
./usr/share/doc/telnet/
./usr/share/doc/telnet/README.telnet
./usr/share/doc/telnet/README.gz
./usr/share/doc/telnet/BUGS
./usr/share/doc/telnet/copyright
./usr/share/doc/telnet/changelog.gz
./usr/share/doc/telnet/README.telnet.old.gz
./usr/share/doc/telnet/changelog.Debian.gz
./usr/share/man/
./usr/share/man/man1/
./usr/share/man/man1/telnet.netkit.1.gz
./usr/share/menu/
./usr/share/menu/telnet


Building a Package
Now that you know what's in a Debian package building one is pretty simple. Start by creating a working directory where you'll store the contents of the package.

$ mkdir /var/tmp/deb

Next, create a subdirectory where the contents of the control file will be stored.

$ mkdir /var/tmp/deb/DEBIAN


Author the control file and locate it in the DEBIAN directory.

$ cat DEBIAN/control
Package: MyPackage
Version: 1.0
Maintainer: Fat Slow Kid
Description: A brief description.
A more thorough description with lines and charts
pictures and graphs with a 8x10 glossy photo
with descriptions and notations.


Next, create the directory structure of the binary file contents. In our example, we intend on installing a new script foo.sh in /usr/local/bin.

$ mkdir -p usr/local/bin


Create a foo.sh script in this directory, our contents are as follows:

$ cat usr/local/bin/foo.sh
#!/bin/sh

echo "running 'My Script'"

Lastly, move out of this working directory and build it with the Debian provided package utilities.

$ dpkg -b /var/tmp/deb MyPackage.deb


After this, a new MyPackage.deb file will exist in the present working directory. You can examine the intended installed files by issuing the command as follows:

$ dpkg --contents MyPackage.deb
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./usr/
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./usr/local/
drwxr-xr-x fsk/fsk 0 2009-02-08 23:12 ./usr/local/bin/
-rwxr-xr-x fsk/fsk 38 2009-02-08 23:12 ./usr/local/bin/foo.sh


Installing this package will now recreate the file system structure starting at the destination systems root file directory. Namely, foo.sh will be located in /usr/local/bin when installed.

# dpkg -i MyPackage.deb
Selecting previously deselected package mypackage.
(Reading database ... 79280 files and directories currently installed.)
Unpacking mypackage (from MyPackage.deb) ...
Setting up mypackage (1.0) ...
xion:/home/fsk#
xion:/home/fsk# which foo.sh
/usr/local/bin/foo.sh
xion:/home/fsk# foo.sh
running 'My Script'
xion:/home/fsk#

Granted the removal procedures aren't defined, but you've got the start of your very own Debian package.

You've achieved your Debian package yellow-belt.

16 September, 2008

Tcl Package Example

I often struggle setting up a Tcl script that utilizes packages. For convenience I'm publishing a template for scripts that capitalize on packages.


::::::::::::::
process
::::::::::::::
#!/usr/bin/tclsh


proc log { msg } {
set lvl [expr [info level] -2]
set indent [string repeat " " $lvl]
tclLog "$indent\___$msg"
}

proc traceLog { } {
set uplevel [expr [info level] -1]
set callSig [info level $uplevel]
set el [split $callSig]
log "call trace: [namespace current][lindex $el 0]([lrange $el 1 end])"

}

proc packageInit { } {
upvar #0 auto_path auto_path

log "initializing system"
set pathName [file dirname [info script]]
log "discovered path name '$pathName'"
pkg_mkIndex $pathName tcl/*.tcl
lappend auto_path $pathName
log "done initializing system"
}

proc proc01 { a b c d } {
traceLog
}

proc proc02 { } {
traceLog
proc01 2 4 6 8
}

#-----main-----
packageInit
package require package01
package01::function01

log "main thread initializing"
proc01 1 2 3 4
proc02
log "main thread terminating"


::::::::::::::
tcl/package01.tcl
::::::::::::::
package provide package01 1.0

namespace eval package01 {
proc function01 { } {
puts "...function01() method entry"
puts "...function01() method exit"
}
}