Skip to content
This repository has been archived by the owner on Aug 4, 2020. It is now read-only.

Latest commit

 

History

History
166 lines (103 loc) · 6.01 KB

README.md

File metadata and controls

166 lines (103 loc) · 6.01 KB

copkg

copkg is an extremely simple way to package software artifacts in a ZIP file and does not attempt to be a complete package management system. Rather, it represents the simplest possible way to package code, some config and a few scripts to start and stop the package in a standardized manner so that automation becomes easier.

An important motivation for copkg is that it should be usable on developer workstations as well. This will help get iteration times down as it is very important that developers be able to install components from other projects (everyone knows how to install and run their own components -- this isn't necessarily true for other projects components).

It does not, and will never, deal with dependencies. copkg packages have to include whatever dependencies they have in the package. A copkg should be self-contained.

Installing the copkg utility

  • Brew install: brew install https://raw.github.com/borud/homebrew/master/copkg.rb
  • Debian package

Configuring copkg

You can put config in ~/.copkg/config.json or /etc/copkg/config.json. Here is a sample configuration:

{
  "packageDir" : "/path/to/your/package/dir",
  "packageBaseUrl" : "http://your.repository/",
  "username" : "the username",
  "password" : "the password"
}

Installing copkg packages

You can install a copkg by issuing the following command:

copkg install <coordinate>

This will download and install the package if it is available. It will not start the service in question.

Removing copkg packages

copkg uninstall <coordinate>

Resolving

When you are playing around with copkg packages you sometimes need to figure out what URLs you end up downloading from, what directories you have configured etc. The resolve command takes care of this:

copkg resolve <coordinate>

How copkg works

A copkg is identified by a package coordinate. The copkg package coordinates are loosely based on Maven coordinates and have three parts: groupId, artifactId and version. Their canonical form is the three fields separated by ":" (colon) character. Here are a few examples of valid copkg package coordinates:

com.comoyo:james:1.2.1
org.mongodb:mongodb:2.3.0

Structure of a copkg package

A valid copkg package has the following directory structure.

bin/

This directory will contain the binaries. Some projects have a single binary while other projects require multiple binaries. The binaries may be anything from Java binaries, Python scripts, ELF binaries. At this point we do not suggest or impose any platform support.

Includes: target/.jar*

etc/

Any static configuration goes into this directory. Static configuration is the sort of configuration that will not vary between multiple instances.

Includes: src/main/copkg/etc

lib/

Anything that does not fit in bin/ or etc/ should go into lib.

Includes: src/main/copkg/lib

script.d/

This directory will contain the scripts for starting and stopping the software. Currently a valid copkg package requires two scripts:

  • start.py
  • stop.py

Includes: src/main/copkg/script.d

Distributing packages

Can use any facility capable of serving static HTTP resources as long as directory structure can be achieved.

Package directory and runtime directory

copkg packages are downloaded and unpacked into a package directory. The package directory is a path somewhere on the filesystem into which packages are installed -- for instance /usr/share/copkg.

So when the package example.org:myservice:1.2.3 is installed it would be installed under /usr/share/copkg/org/example/myservice/1.2.3.

Runtime directory

In order to run myservice in the above example we need a runtime directory. This allows us to de-couple the runtime state of the service from the software artifact. It makes sense to name the runtime directory after something that identifies the service instance.

We can imagine that our runtime directories are rooted at /usr/local/services. Let's imagine we identify my service as 1.myservice.borud.trd. Then its runtime directory would be /usr/local/services/1.myservice.borud.trd.

Runtime directory structure

logs/

Directory used for all logs.

data/

The main directory for where the service will store its runtime state. For instance, if the service has a on-disk database, this is where the database would go. (Lifecycle management of ephemeral state is a future concern).

run/

Various runtime metadata such as a service.pid file which contains the PID(s) of the process (if multiple PIDs then one on each line). Also where we store the start.json file.

etc/

Per instance configuration. This is where configuration files that are specific to the instance go.

Building copkg packages

When a copkg is unpacked, the resulting directory structure is meant to be immutable. Meaning that when the software is started any runtime state will need to live in a runtime directory. The main motivation for this is to keep software management simple.

Usage

In order to use the copkg assembly descriptor you need to make sure that you have added the appropriate directories under src/main/copkg/ (see further down) in your project and you add the following to your pom.xml file:

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
    <dependencies>
      <dependency>
        <groupId>org.cloudname</groupId>
        <artifactId>copkg-assembly</artifactId>
        <version>1.0.0</version>
      </dependency>
    </dependencies>
    <executions>
      <execution>
        <id>assemble</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
        <configuration>
          <descriptorRefs>
            <descriptorRef>copkg</descriptorRef>
          </descriptorRefs>
          <includeEmptyDirs>true</includeEmptyDirs>
        </configuration>
      </execution>
    </executions>
  </plugin>