Unix Maven Plug
Unix Maven Plug
Unix Maven Plug
Trygve Laugstl
Arktekk AS <[email protected]>
Acknowledgements
Trygve Laugstl would like to thank the following persons and companies in no particular order for their effort in helping with the development of the Unix Maven Plugin Erik Drolshammer, Objectware for providing me with RPM related use cases and being helpful with testing new features. Conax for providing use cases and allowing me to work on the plugin while on the clock. Arktekk for sponsoring me to work on the plugin.
Preface I. Guide 1. Introduction 1.1. Scope 1.2. About the plugin 1.3. How the Plugin Work 1.3.1. Meta Data Generation 1.3.2. Assembly Operation Execution 1.4. About the Alternatives to the Unix Maven Plugin 2. Concepts 2.1. Operation Modes 2.2. Package Formats 2.3. Platform 2.4. Package File System and File System Objects 3. Default Values 3.1. Default Assembly Operations II. Example of Usage Introduction to the Examples 4. Single, Standalone Application 4.1. The Deb version 4.1.1. pom.xml for the deb version
4.1.2. Resulting Deb 4.2. The Pkg version 4.2.1. pom.xml for the pkg version 4.2.2. Resulting PKG 4.3. The RPM version 4.3.1. pom.xml for RPM version 4.3.2. Resulting RPM 4.4. The Zip version 4.4.1. pom.xml for the zip version 4.4.2. Resulting ZIP 5. Other III. Reference 6. Unix Package Definition 6.1. Deb 6.2. Pkg 6.3. Rpm 6.4. Version Calculation 6.4.1. Version Calculation for Snapshot Versions 6.4.2. Version Calculation for Release Versions 6.5. Mapping to Native Formats 6.5.1. Deb Specific Mappings 6.5.2. Pkg Specific Mappings 6.5.3. Rpm Specific Mappings 7. Action Scripts 7.1. Action Scripts in Primary Artifact Mode 7.2. Action Scripts in Attached Artifact Mode 8. Operating Requirements 9. Assembly Operations 9.1. Common Settings and Behaviour 9.1.1. Artifact Naming and Identification 9.1.2. File renaming 9.1.3. Includes and Excludes 9.1.4. File Attributes 9.2. Copy File 9.3. Copy Artifact 9.4. Make Directory 9.5. Set Attributes 9.6. Symlink 9.7. Copy Directory, Extract Artifact and Extract File 9.7.1. Copy Directory 9.7.2. Extract Artifact 9.7.3. Extract File 10. Creating Native Package Repositories 10.1. Creating Debian/APT Repositories 10.2. Creating RPM/Yum Repositories 10.3. Creating pkg-get/pkgutil Repositories 11. Troubleshooting 11.1. Debugging IV. Useful Tips For Making Useful Packages 12. Package Command Reference 12.1. dpkg Commands 12.1.1. Listing All Files In a Package
12.2. rpm Commands 12.2.1. List All Files In a Package 12.2.2. List All Files In a Package With File Permissions 12.2.3. Listing All Available Software Groups 12.3. zip Commands 13. Snippets for Scripts 13.1. RedHat/Fedora 13.1.1. Making your server start on boot V. Version History and Upgrading Preface to Part IV 14. 1.0-alpha-4 14.1. Change Log 14.2. Upgrading from 1.0-alpha-3
Preface
This handbook is the complete documentation of the Unix Maven Plugin. It has four major parts: Part I - Guide: An introduction and overview over the plugin. This part is the first you should read if you're looking into using the plugin or is getting started. Part II - Examples: This part is contains a set of practical examples showing different aspects of the plugin. Part III - Reference: This is the reference manual for the plugin. Documents all available options and assembly operations. Part IV - Package Command Reference: A list of commands useful for looking into and debugging assembled packages. Part V - Version History and Upgrading: This part contains a list of all major features added in the different versions and explanations on how to upgrade between the different versions. The book is under continous development and is written in parallel with the plugin. It will only document the current version until a stable release is done. See Part V, Version History and Upgrading on how to upgrade from one version to the next version. Currently there are chapters and sections that serve as placeholders and there are warnings which serve as TODO entries. These will be filled in and resolved before a final 1.0 release.
Part I. Guide
removed. The plugin will pick up as much meta data as possible from the Maven POM as possible, but there are certain options that might have to be filled in, depending on the package format. Assembly operation execution: For each package that is to be created, a virtual package file system is created with pointers to the original file or which file in and archive the file came from. The assembled file system will be used when the physical package is created.
[1]
Development chain here refers to all the step that's between writing the code in an IDE to having it run in production or a production-like environment.
The plugin is running in primary mode when the project has set a <packaging> to one of the packaging that the plugin support. The plugin will install an artifact as the primary artifact into the repository
Attached artifact mode
The plugin is running in attached mode when the project is executing the one of the package-FOO-attached goals. The plugin will install a package in addition to the primary artifact which will be delivered by another plugin.
2.3. Platform
A platform is a specific operating system, for example Debian or Solaris. Each platform has its own native package format while some platforms support multiple formats.
A package file system is a virtual file system created while the plugin executes all the assembly operations. It consist of file objects that represent regular files, directories and symbolic links. Each file system object has a set of attributes similar to a normal Unix file system:
User and group
These two attributes control the user and group that own the file.
Mode
Each file object can have a set of tags which are plain text labels that each package format can use as an extension method. Example 2.1. Example of file mode specifications becomes -rw-r--r-0744 becomes -rwxr--r-0644
Note
Not all file objects support all attributes.
<groupId>org.codehaus.mojo.unix.example</groupId> <artifactId>basic</artifactId> <version>1.0-SNAPSHOT</version> <packaging>deb</packaging> <name>Hudson</name> <repositories> <repository> <id>java.net</id> <url>http://download.java.net/maven/2</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.jvnet.hudson.main</groupId> <artifactId>hudson-war</artifactId> <version>1.255</version> <type>war</type> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>unix-maven-plugin</artifactId> <version>1.0-alpha-5</version> <extensions>true</extensions> <configuration>
<contact>Acme</contact> <contactEmail>[email protected]</contactEmail> <deb> <section>devel</section> </deb> <assembly> <copyArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <toFile>/opt/hudson/hudson.war</toFile> <attributes> <user>hudson</user> <group>hudson</group> <mode>0666</mode> </attributes> </copyArtifact> <extractArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <to>/opt/hudson/doc</to> <includes> <include>**/*license.txt</include> </includes> <pattern>.*/(.*.txt)</pattern> <replacement>$1</replacement> </extractArtifact> <symlink> <path>/var/log/hudson</path> <value>/var/opt/hudson/log</value>
$ dpkg-deb -f target/*.deb Package: basic Section: devel Priority: standard Maintainer: Acme Version: 1.0-20110708.151032 Architecture: all Description: Hudson Solaris Package
<dependency> <groupId>org.jvnet.hudson.main</groupId> <artifactId>hudson-war</artifactId> <version>1.255</version> <type>war</type> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>unix-maven-plugin</artifactId> <version>1.0-alpha-5</version> <extensions>true</extensions> <configuration> <contact>Acme</contact> <contactEmail>[email protected]</contactEmail> <assembly> <copyArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <toFile>/opt/hudson/hudson.war</toFile> <attributes> <user>hudson</user> <group>hudson</group> <mode>0666</mode> </attributes> </copyArtifact>
<extractArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <to>/opt/hudson/doc</to> <includes> <include>**/*license.txt</include> </includes> <pattern>.*/(.*.txt)</pattern> <replacement>$1</replacement> </extractArtifact> <symlink> <path>/var/log/hudson</path> <value>/var/opt/hudson/log</value> </symlink> </assembly> </configuration> </plugin> </plugins> </build> </project>
Hudson application all 1.0-20090513.193125 20090513.193125 [email protected] spooled 11 spooled pathnames 5 directories 2 setuid/setgid executables 2 package information files 40286 blocks used (approx)
Notice that the SNAPSHOT part of the version string has been replaced with the a timestamp. To see verify the paths and their attributes, run this:
$ pkgchk -l -d target/basic-*.pkg all Checking uninstalled stream format package <basic> fromn <../target/basic1.0-SNAPSHOT.pkg> ## Checking control scripts. ## Checking package objects. Pathname: /opt Type: directory Expected mode: 17777777777 Expected owner: ? Expected group: ? Current status: installed
Pathname: /opt/hudson Type: directory Expected mode: 0755 Expected owner: nobody Expected group: nogroup Current status: installed
Pathname: /opt/hudson/doc Type: directory Expected mode: 0755 Expected owner: nobody Expected group: nogroup Current status: installed
Pathname: /opt/hudson/doc/atom-license.txt Type: regular file Expected mode: 0644 Expected owner: nobody Expected group: nogroup Expected file size (bytes): 49 Expected sum(1) of contents: 4473 Expected last modification: Oct 02 02:07:36 2008 Current status: installed
Expected mode: 0644 Expected owner: nobody Expected group: nogroup Expected file size (bytes): 1544 Expected sum(1) of contents: 59072 Expected last modification: Oct 02 02:07:36 2008 Current status: installed
Pathname: /opt/hudson/hudson.war Type: regular file Expected mode: 0666 Expected owner: hudson Expected group: hudson Expected file size (bytes): 20623413 Expected sum(1) of contents: 3301 Expected last modification: Oct 24 23:08:16 2008 Current status: installed
Pathname: /var Type: directory Expected mode: 17777777777 Expected owner: ? Expected group: ? Current status: installed
Expected mode: 0755 Expected owner: nobody Expected group: nogroup Current status: installed
Pathname: /var/log/hudson Type: symbolic link Source of link: /var/opt/hudson/log Current status: installed
Pathname: pkginfo Type: installation file Expected file size (bytes): 161 Expected sum(1) of contents: 12122 Expected last modification: May 13 21:31:26 2009
## Checking is complete.
<packaging>pkg</packaging> <name>Hudson</name> <repositories> <repository> <id>java.net</id> <url>http://download.java.net/maven/2</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.jvnet.hudson.main</groupId> <artifactId>hudson-war</artifactId> <version>1.255</version> <type>war</type> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>unix-maven-plugin</artifactId> <version>1.0-alpha-5</version> <extensions>true</extensions> <configuration> <contact>Acme</contact> <contactEmail>[email protected]</contactEmail> <assembly>
<copyArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <toFile>/opt/hudson/hudson.war</toFile> <attributes> <user>hudson</user> <group>hudson</group> <mode>0666</mode> </attributes> </copyArtifact> <extractArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <to>/opt/hudson/doc</to> <includes> <include>**/*license.txt</include> </includes> <pattern>.*/(.*.txt)</pattern> <replacement>$1</replacement> </extractArtifact> <symlink> <path>/var/log/hudson</path> <value>/var/opt/hudson/log</value> </symlink> </assembly> </configuration> </plugin> </plugins> </build>
</project>
<packaging>pkg</packaging> <name>Hudson</name> <repositories> <repository> <id>java.net</id> <url>http://download.java.net/maven/2</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.jvnet.hudson.main</groupId> <artifactId>hudson-war</artifactId> <version>1.255</version> <type>war</type> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>unix-maven-plugin</artifactId> <version>1.0-alpha-5</version> <extensions>true</extensions> <configuration> <contact>Acme</contact> <contactEmail>[email protected]</contactEmail> <assembly>
<copyArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <toFile>/opt/hudson/hudson.war</toFile> <attributes> <user>hudson</user> <group>hudson</group> <mode>0666</mode> </attributes> </copyArtifact> <extractArtifact> <artifact>org.jvnet.hudson.main:hudson-war:war</artifact> <to>/opt/hudson/doc</to> <includes> <include>**/*license.txt</include> </includes> <pattern>.*/(.*.txt)</pattern> <replacement>$1</replacement> </extractArtifact> <symlink> <path>/var/log/hudson</path> <value>/var/opt/hudson/log</value> </symlink> </assembly> </configuration> </plugin> </plugins> </build>
</project>
Chapter 5. Other
Other examples to write
Package Attached to a WAR
Show a normal "hello world" web application (generated from the webapp archetype perhaps) which creates an attached package
Show a complete standalone application with appassembler and docx plugin to generate man pages
Useful to show how to interact with other plugins. Should also show of default values if possible
Package for multple platforms
When the plugin is collecting all relevant data for a package it collects all the information in a generic object called "package parameters". This object is used as the basis when the package is created. See Section 6.5, Mapping to Native Formats on how the package parameters map to the format specific fields.
Note
Parameters that reference mojo refers to parameters configured in a <configuration> block. When multiple values are are available, the first one is selected. Field
groupId artifactId version
Required
Y Y N/A
Source(s)
project.groupId project.artifactId Calculated
Description
This field is calculated from different sources. SeeSection 6.4, Version Calculation for details. This field is calculated from different sources unless specified. See Section 6.4, Version Calculation for details. The default value is the lower case version of the artifact id. Maven will supply a default name if none is given.
revison
mojo.revision
id
package.id
name
description
N N N
The first license listed in the POM will be used. A default value indicating that the package is architecture independent is used if applicable.
architecture
1. mojo.architecture 2. format.architecture
Warning
Particular formats might add additional requirements.
Tip
For more information see the class org.codehaus.mojo.unix.PackageParameters. In addition to the generic object, additional information is collected for each type of package.
6.1. Deb
Field
priority section
Required
Y Y
Source(s)
deb.priority deb.section
Description
For the allowed values for the priority field, see priorities and sections sections in the Debian Policy Manual.
6.2. Pkg
The pkg format does not have any specific settings. All settings is derived from the generic settings.
6.3. Rpm
Additional requirements for the RPM format: At least one license is specified in the POM. Field Required Source(s) Description
group Y rpm.group
The "main" part of the version configured in the POM. The main part is everything before the last dash in the version string.
Revision
The timestamp of the build. This is the same timestamp as the one used for installing the artifacts in the repository. The overall strategy for SNAPSHOT versions is to make the version field in the package as specific as possible. This means that the build timestamp will be appended to the version string where applicable.
Result
1.2-20090423095107 1.2-20090423095107 1.2_20090423095107, rev: 1 1.2-3-20090423095107 1.2-3-20090423095107 1.2_20090423095107, rev: 3 1.2-3-20090423095107 1.2-3-20090423095107
Version
Revision Format
Rpm Deb 3 Pkg Pkg
Result
1.2_20090423095107, rev: 3 1.2-3-3-20090423095107 1.2-3-3-20090423095107 1.2_3_20090423095107, rev: 3
Result
Deb
Version Package
Pkg
VERS PKG
Rpm
Version Release Name
Unix Package
name description contact contactEmail license
Deb
Description Maintainer
Pkg
NAME DESC EMAIL
Rpm
Summary Description
License
In the primary artifact mode the scripts are named using the naming convention of the current format: Table 7.1. Naming convention for action scripts per format Action
After installation Before removal After removal
Deb
Pkg
preinstall preremove postremove
Rpm
pre preun postun
Using the "after installation" script for the Deb format as an example, the plugin will generate a postinst file based on the concatination of these two files:
src/main/unix/scripts/postinst src/main/unix/scripts/postinst-<package id>
Generic
post-install pre-remove post-remove
Againg using the "after installation" for the deb format as an example, the plugin will generate a postinst file based on the concatination of these files:
src/main/unix/scripts/post-install src/main/unix/scripts/post-install-<package id> src/main/unix/scripts/post-install-<package id>-deb
Extract artifact Extracts an artifact from the repository Make directory Creates one or more directories Set attributes Symlink Sets file attribues on a file set Creates a symlink
Warning
Explain "file object" somewhere
Tip
If the plugin can't find the artifact that's referred to it will list all available artifacts.
A regular expression that selects the files to be renamed. The regular expression may contain groups to pick out parts of the string. The syntax used is the standard Java syntax. See the reference documentation on Pattern.
replacement
The new name of the file. May contain references to groups matched in the pattern.
Warning
Document the effect on the matched files vs those that doesn't match Example 9.2. Removing the first directory by renaming the files
<extract-artifact> <artifact>org.mortbay.jetty:jetty-assembly:zip</artifact> <to>/opt/jetty</to> <pattern>/jetty-${jetty.version}(.*)</pattern> <replacement>$1</replacement> </extract-artifact>
This example will match all files in the jetty-assembly artifact, put the entire path except the first part into group number one. The replacement value will be the value of the first group.
Warning
The order of includes vs excludes
Warning
Explain the effect of having a basedir-like parameter set when calculating matches. (the include/exclude expressions can't contain the basedir part). Applies only to set attributes for now.
Note
Some assembly operations support both per-directory and per-file attributes. If so the outer tag will be named <fileAttributes> and <directoryAttributes>, but they contain exactly the same set of elements. Table 9.2. Available attributes
user
Specifies the read/write/executable bits on the file. The value has to be be in octal notation
Mode examples:
0644 0744
See Section 2.4, Package File System and File System Objects for more details. Example 9.3. Example usage of <attributes>
<attributes> <user>myapp</user> <group>myapp</group> <mode>0644</mode> </attributes>
The destination file or directory. Only one of the two parameters may be toFile or toDir specified. If toDir is used, a file with be created in the specified directory with the same name as the source file. attributes The attributes to set on the copied file. See Section 9.1.4, File Attributes.
The destination file or directory. Only one of the two parameters may be toFile or toDir specified. If toDir is used, a file with be created in the specified directory with the same name as the source file. attributes The attributes to set on the copied file. See Section 9.1.4, File Attributes.
9.6. Symlink
Purpose: to create symbolic links. Table 9.7. Supported parameters <symlink>
path
This will create a symbolink link under /var/log/myapp that points to /var/opt/myapp/log.
Purpose: to copy a directory structure. Table 9.9. Additional parameters for <copyDirectory>
from The directory to copy from.
Warning
document the supported archive types. (at least zip, jar and war are supported). Example 9.10. Example usage of <extractArtifact>
<extractArtifact> <artifact>org.mortbay.jetty:jetty-assembly:zip</artifact> <to>/opt/jetty</to>
</extractArtifact>
Warning
document the supported archive types. (at least zip, jar and war are supported). Table 9.11. Additional parameters for <extractDile>
archive The path to an archive to extract. See Section 9.1.1, Artifact Naming and Identification on how to identify the artifact to copy.
Chapter 10. Creating Native Package Repositories 10.1. Creating Debian/APT Repositories
10.2. Creating RPM/Yum Repositories 10.3. Creating pkg-get/pkgutil Repositories Chapter 11. Troubleshooting 11.1. Debugging
The plugin has its own mechanism to be more verbose to make it easier to just debug the plugin. By running Maven with the Dmaven.unix.debug=trueflag you will get a lot of extra debugging information. In particular you will get information about all the assembly operations it has collected per package and all output from any external command it will use while building the package.
Part IV. Useful Tips For Making Useful Packages Chapter 12. Package Command Reference
This part describes a set of commands that are useful for looking into and disassembling packages.
12.1.
dpkg
Commands
12.2.
rpm
Commands
/var/log/hudson
-rw-r--r-1 nobody nogroup /opt/hudson/doc/atom-license.txt -rw-r--r-1 nobody nogroup /opt/hudson/doc/dc-license.txt -rw-rw-rw1 hudson /opt/hudson/hudson.war drwxr-xr-x drwxr-xr-x 2 nobody 2 nobody hudson nogroup nogroup nogroup
20623413 Oct 24
Amusements/Games Amusements/Graphics Applications/Archiving Applications/Communications Applications/Databases Applications/Editors Applications/Emulators Applications/Engineering Applications/File Applications/Internet Applications/Multimedia Applications/Productivity Applications/Publishing Applications/System Applications/Text Development/Debuggers Development/Languages Development/Libraries Development/System Development/Tools Documentation System Environment/Base System Environment/Daemons System Environment/Kernel System Environment/Libraries System Environment/Shells User Interface/Desktops
12.3.
zip
Commands
Note that there are no standard for the utilities used to handle zip files. However, most platforms support this command. Example 12.5. Listing all files in a ZIP file
$ unzip -l target/basic-*.zip Archive: Length -------0 0 0 49 1544 20623413 -------20625006 target/basic-1.0-SNAPSHOT.zip Date ---Time ---Name ---./opt/ ./opt/hudson/ ./opt/hudson/doc/ ./opt/hudson/doc/atom-license.txt ./opt/hudson/doc/dc-license.txt ./opt/hudson/hudson.war ------6 files
04-07-11 13:33 04-07-11 13:33 04-07-11 13:33 10-02-08 02:07 10-02-08 02:07 09-30-10 10:12
This will make the system start the application in runlevels 3, 4 and 6 with the priority 10 and 90 at shutdown and start, respectively. To install such a script, simply run
chkconfig --add foo
Similary, if you want to remove it when the package is uninstalled simply run:
chkconfig --del foo
Once the plugin stabilizes expect the upgrade instructions to be removed as the pre releases will be unsupported.
All examples use hyphened elements instead of camel casing to be more consistent with how Maven POMs normally are written. This will not break any builds as Maven interpret both version the same way. For example <fileAttributes> is now used instead of <fileattribues>.