2006-03-22

Linux: Apt friend


UPDATE For now the tool placed here is not fully compatible with Ubuntu Edgy. Nevertheless 3,4 person a month downloads it. I have fixed it long time ago and successfully continue using it, but I'm just lazy to share the new version. If you really need it please leave a comment or mail me kmmbvnr _at_ inbox.ru.


Gosh, I've carried to an acceptable level a script so that I'm not ashamed to share it.

I've brought the freebie Ubuntu spreading upon myself and the problem arise:

Some day my friend visited me and said: «Oh, you are watching video with such a funny player, share it with me!»

Yes, indeed, in theory nothing prevents me from the copying a deb file to a flash drive, but there is one trouble with the dependencies. The banal mplayer pulls a lot of stuff. Well, it is possible to rummage in deb file and get whatever it needs but it is very ungraceful.

Yes, if there is fast Internet on a computer and the required repositories are registered the trouble is fall away though it leaves a bad taste - one more downloading is not nice.

So, the problem is: There is a computer A with Ubuntu on board to which we desire to install some packages. There is a computer B where these packages are already installed or the Internet is faster/cheaper/freebie. The connection between the two computers is established in the very democratic way — by Winchester or flash drive. It is required to gather packages and missing dependencies in one folder.

Existing solutions for now:

1) apt-get --print-uris
1a) debget
2) a little bit magic with status file
3) my variant is apt-dist


1) The easiest and flexiblest way of getting all required packages is to emulate their installation at the initial computer, to see what is required and after that just download it on the computer 2. For this purpose computer 1 should have good or bad access to the Internet.

Set up sources.list at the computer 1, connect to the Internet and execute apt-get update. By this command we get packages list located in remote repositories. Now we can use synaptic, aptitude or even dselect for searching names of packages with the required functionality. Instead of the installation packages by means of these programs execute the command apt-get -qq --print-uris install package_name_1 package_name_2 and so on. --print-uris option forces apt-get just print packages location urls instead of the downloading and installation. And --qq option turns off the redundant screen output. Copy these urls to a file and go to the computer 2.

At the computer 2 we can download packages from the just received file by executing the following commands:

cat our_file | awk 'print "wget -O " $2 " " $1}' > wget-script
sh -x ./wget-script

By the first command we create script file that contains sequence of calls of the console downloader wget for the each package downloading. By the second command we run this script for the execution.

The main disadvantage of the first variant is that the packages regardless of their presence in the local repository will be downloaded over again. If in a net/at a local computer there is a proxy cashing deb packages (apt-cacher or apt-proxy) it is possible to force wget to download through it (by some additional tricks with url) but there is more easy way:

1a) The package debian-goodies among other things offers debget command, which download deb file by using the local base of apt-get. Packages downloading from local mirrors can be easily realized by means of it.

The disadvantages of debget are impossibility to set the required package version, need root rights and errors that appear while trying to download deb from cdrom. The key to these problems solution is described in the 2nd variant.

2) From the computer 1 take file /var/lib/dpkg/status containing information about the installed packages. This file is the only thing we need to create a configuration on the machine 2, which is indistinguishable from the computer 1 for apt. The creation of the own configuration makes needless writing rights to /var/cache/apt, hence we do not need root rights.

First of all in some folder, e. g. /tmp/dist create the following folder structure:

/tmp/dist/
archives/
partial/
lists/
partial/
status
sources.list
apt.conf

where status file is just that file from the computer 1, sources.list file should contain the list of repositories from where you'd like to take packages (you can just copy /etc/apt/sources.list).

And apt.conf file should have the following contents:

APT {
Architecture "i386"; //Use here computer 1 architecture name ( most likely, it is i386 or x64)
Get::Download-Only "true" //We'll only download packages on computer 2
};
Dir {
//The locations of file with the information about the installed packages
State "/tmp/dist";
State::status "status";

//Folder for deb files storying
Cache::archives "/tmp/dist/archives";
Cache "/tmp/dist"

//sources.list location
Etc "/tmp/dist"
}

Do not forget to change /tmp/dist to the path to a folder with your configuration. Experience has shown that in apt.conf it is possible to use relative paths everywhere except Cache::archives parameter.

Execute:

export APT_CONFIG="/tmp/dist/apt.conf"
apt-get update
apt-get install package_name

Since in apt.conf file the option APT::Get::Download-Only is set to true the installation will not occur, but the needed packages will be downloaded. But packages will be downloaded not from the local repositories since apt does not download anything from local repositories at all but immediately use the packages from the given location. Cd-roms and snapshots on hard drives are out in the cold again.

It's just the right time to remember that apt is responsible only for downloading packages of needed version and command dpkg unpacks and configures the packages in the debian-based distributions.Apt-get addresses exactly to it when installing a package. Immediately the action plan has become clearer — disable option APT:: Get:: Download-Only, then apt will make an attempt to install packages, but if instead of the original dpkg substitute script wrapping around the command cp (copy) the packages will not be installed but just copied in the right place. Actually, it is the core of the 3d method.

3) The common disadvantage of all the methods mentioned above is the necessity of any preliminary actions on the computer 1. Although the need of passing packages happens rather by accident. About computer 1 is usually known just what kind of distributive is installed on it, and that its owner has an official CD release of this distribution. In principle, this information is quite enough to form and copy to a flash drive all the missing packages and their dependencies. But if a couple or triple of them are already installed in the computer, it's nothing. The first step is to create status file of pseudo machine on which would be installed all packages from official cd / dvd. Since cd / dvd could potentially contain packages conflicting between each other, we will not record information about possible conflicts to the status file then apt will believe that everything is fine. And when you try to complete installation only packages missing on the official Cds will be downloaded and installed only.

In general, all these routine steps, I realized once and for all in a small script. For whom is interested in the details - I recommend to look at the source (28Kb) I do not tell how to use this script for purpose, because ANY script gotten from strange places (some blog on the side, freebie hosting) you have to CHECK WITH EYES. Anything may happen.

I like the result. No pre-shamanistic dances on a softless computer, the computer may not be connected to Internet at all, and purely theoretically it could be any debian-based system.

Root rights are not necessary on donor computer.

P.S. NO WARRANTY
P.P.S Big thanks to Jason Gunthorpe <jgg@debian.org> author of the APT Offline HOWTO.

2006-03-15

The programming: Lisp

Gosh, I've passed a study course «The basis of the functional programming».
Though I don't know why. Well, since I started, I had to finish. But now I can boast the diploma numbered Nine Thousand Six Hundred And Sixty Six.

The general impressions are somewhat mixed. IMHO the course tries to include everything but as a result it comes out superficial enough. If only I have not an idea about Lisp before, I doubt whether I could understand some subjects given casually.

But after all it was interesting, the description of the basis of the realization LISP interpreter and compiler in Russian I have not met before in the Internet.

But the test questions of the course are definitely rotten. Still nobody manage to finish the course with the highest mark (5).

2006-03-04

The programming: 99 bottles in Drools

I've posted to www.99-bottles-of-beer.net my solution in Drools. It was accepted.
You can see it here

The programming: 99 bottles

Oh, amazing site - www.99-bottles-of-beer.net It collects a great many programs in different languages printing plain and simple song:


99 bottles of beer on the wall, 99 bottle of beer!
Take one down, and pass it around. 98 bottles of beer on the wall.

98 bottles of beer on the wall, 99 bottle of beer!
Take one down, and pass it around. 97 bottles of beer on the wall.

...


What languages there are not here: ANT, J, K, CLIPS, Erang, Ocaml, 1C, naturally there are C/C++, Java, Perl.

Some exoteric languages made me smile - Ook! (This is for those who read Pratchett),
Shakespeare Programming Language (at least a brief acquaintance with works of the author with the same name is also recommended), Multithreaded Brainf * ck, procmail.

But as the most beautiful solution I unexpectedly chose a program in Refal.

With the printing the beginning of the song all languages cope pretty enough. The simple end spoils everything:

...

2 bottles of beer on the wall, 2 bottle of beer!
Take one down, and pass it around. 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer!
Take one down, and pass it around. No more bottles of beer on the wall.

No more bottles bottles of beer on the wall, No more bottles bottles of beer!
Go to store and buy some more. 99 of beer on the wall.


In some languages code is short, simple and clear but either incorrectly declines «1 bottles», or gladly reports in the end «0 bottles of beer on the wall». After fixing it becomes huge and confusing.

ANT by using the extensions package ant-contrib demonstrates the all ugliness of XML for recording consecutive actions.

But 1C code looks rather good due to the presence of operator ? in the language. If there is no petty operator + it would be not so bad illustration of imperative approach for solving this problem.

Excel VBA wonderfully demonstrates what terror can come out of it if do not separate logic from visual appearance.

Common Lisp code made me smile — the only program, which actually does what was requested — printing the song. In the language standard there is 'format' function (highly advanced analogue of C printf) its abilities are pretty enough for this song :).

Program in Scheme generates the required string in compile time. There there is a terrifying realization and quite good one.

C++ solution with using templates amazes by its laconism and demonstrates a simple rule-based approach in compile time.

Rule-based forward chaining language CLIPS fits successfully. It's a little bit verbose, but then easy extended.

For some reason neither JESS nor Drools solutions are present. Aren't they unpopular?

Java Exception oriented programming is the joke of the month! throw new BottleExeption(1), and redefine printStackTrace() method %)

Refal is great! Pattern matching is a wonderful tool for the decomposition.

I expected to see something similar in OCalm, but in the beginning they build recursive variant type isomorphic to the song verses and after that the substitution is going on. I have not understood yet either it is an awfully overhead, or a remarkable approach, using effectively the advantages of compile time and run time.

At the same site there is a lot of programs written in different Assembler dialects, Basic and SQL, but they are not so interesting for me.