Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a debian package for a war file for Ubuntu

Tags:

war

debian

We have a war file, liquibase xml files, and sha1 checksums we want to package as a Debian script for deployment to one platform: ubuntu 14.1 64bit with tomcat 7 and java 7.

We have trawled through a large number of incomprehensible (for us as java developers) Debian packaging guides, most of which require an "upstream source tar ball" (e.g. this one: https://wiki.debian.org/IntroDebianPackaging ) and/or something generated from doing a make/install.

We have neither, which is the crux of our problem.

We have two phases:

  1. Initial installation (done once)
  2. Update (done many times)

The guides don't mention how to manage these two phases.

Initial installation (what we do now by hand on every server):

  1. install java, tomcat7 using apt-get as root. Presumably, this can be automated through dependencies
  2. heavily edit the var/lib/tomcat7/conf/context.xml with target database connection string/password etc. Presumably, this has to still be done by hand after the install.
  3. create a new user and group for our app, e.g. "foo".
  4. login as foo
  5. In foos home dir, install the base app: 4.1 create a scripts directory and copy an install.sh file 4.2 edit the install.sh file and change the Database connection string, top secret user and pass to match the target db (on another server) 4.3 copy the liquibase binary distribution of jars and scripts into a liquibase sub dir.

The app itself we distribute via a tar file built with Jenkins. In the tar is the following:

  1. app.sha1
  2. migration/changelog.xml (and a bunch of liquibase xml files)
  3. app.war
  4. classes.sha1

We scp the tar file into the /home/foo dir, and run /home/foo/scripts/install.sh which does the following:

  1. deletes old tar and untared stuff from /home/foo
  2. untars the new tar file.
  3. stops tomcat
  4. runs the liquibase jar command with the untarred migrations dir to create/update the db
  5. deletes /var/lib/tomcat7/webapps/*
  6. copies the new war to var/lib/tomcat7/webapps/
  7. starts tomcat
  8. waits a bit
  9. uses sha1sum to make sure the classes are correct (this serves no purpose other than it is a requirement from the customer)

The questions we have are:

  1. Where and how is the user created? E.g. foo in our case, or tomcat7 in tomcats case.
  2. Does the package "install itself"? Or does it only put files in the file system (and thus require an admin to later run one or more scripts to do the work? Is there some standard for the scripts which do the work, e.g.standard names?
  3. There are many packaging tools out there, e,g, Jenkins plugins, dpkg, fpm, debuild, dpkg-buildpackage. Which should we use? We looked at fpm, but it assumes you have a dir built from a source install with make files etc, we don't.
  4. Where are packages installed to? Will it end up in say /var/lib/foo, or var/lib/foo-0.3.4? If the latter, we are in trouble, as other parts of the system need to access the .sha1 files, and thus need one fixed place to put the install.
  5. Is there a better way than manually editing each servers context.xml and install.sh for making each customer have the correct db connection details? E.g do people use awk/sed for such things from a script, or is there some sort of mysql password and connection string repository?
  6. How are the target files ownership and permissions set?
  7. Has anyone come across a "hello world" type packaging tutorial which does not rely on an existing "source tar + make +install", and shows the relationship between files in the package and files in the target server after the install, and the package lifecycle including how updates work?
  8. How does the system manage only sending the updated files, e.g not the liquibase binaries in this case? I assume we would need two packages, one for the base install, and one for the tar, to avoid duplication?

    We understand that we need to put artifacts in a special directory structure and that this somehow maps onto the target servers file structure, and we need to build various control files, but not how it gets glued together at the various phases, and what scripts are required.

    We have attempted to read the Debian policy manual ( https://www.debian.org/doc/debian-policy/), but this is a reference tome for experience linux package developers. We are sure the answers are in there, but we cant figure out where.

This post: https://help.ubuntu.com/community/Tomcat/PackagingWebapps Has two other options (we opted for "beating the system-wide instance into submission") but gives no clues on how to actually build the packages.

like image 356
John Little Avatar asked Jan 14 '16 21:01

John Little


People also ask

Do Debian packages work on Ubuntu?

Deb is the installation package format used by all Debian based distributions. The Ubuntu repositories contain thousands of deb packages that can be installed either from the Ubuntu Software Center or from the command line using the apt and apt-get utilities.


1 Answers

The easiest way is to install dh-make and use that to generate a skeleton debian/ directory to get you started. You can delete the files that are irrelevant (e.g. if you don't provide a man page).

You'll need to edit debian/control to specify the necessary packages in Depends: - probably tomcat7 and tomcat7-java; you don't need to mention sha1sum because it's in coreutils, which is an Essential package.

Add the necessary modifications to context.xml to the postinst script, if (and only if) you can't override the existing settings by simply adding a file somewhere.

Add a Makefile with an install target that puts the necessary files into subdirectories of $DESTDIR:

install:
        install -d $(DESTDIR)/var/lib/tomcat7/webapps
        install -m 644 app.war $(DESTDIR)/var/lib/tomcat7/webapps

I would hope that Tomcat can be triggered to reload when dependent packages are updated (by mentioning it in debian/triggers), but if not, you'll need to restart it (using invoke-rc.d or systemctl, depending on the target init system) in the postinst and postrm scripts.

To answer the specific questions:

  1. If you need to create a new user, do that in the preinst script (crib from another package, or read the manual). Do you really need another user, or is the tomcat user appropriate?

  2. Package manager installs and uninstalls all the files provided, and runs the preinst, postinst, prerm and postrm scripts provided.

  3. That list isn't comparing like with like - e.g. dpkg is for managing packages on a system, not for creating packages. With a suitable debian directory, building can be as simple as

     fakeroot debian/rules binary
    

    Tools such as pbuilder are useful for ensuring dependencies such as libraries are installed on the build system, rather than arranging this by hand, which gets tedious if you're building a distribution. You shouldn't need that level of automation.

  4. Packages' files are installed to whichever directory under $DESTDIR that make install puts them.

  5. There may be a better way to configure Tomcat than editing files in /etc. I don't know that server well enough to know that myself.

  6. Target files' permissions and ownership are exactly as make install sets.

  7. There's a lot to read in the Debian Packaging Manual; I recommend you refer back to that frequently as the mechanism starts to make sense.

  8. I'm not sure what you mean by "sending files". And the package shouldn't need to include the tarball you unpacked from - that would just be duplication.

like image 158
Toby Speight Avatar answered Oct 19 '22 05:10

Toby Speight