[rabbitmq-discuss] Packaging

Edwin Fine rabbitmq-discuss_efine at usa.net
Mon Nov 10 16:46:31 GMT 2008


On Mon, Nov 10, 2008 at 10:48 AM, Ben Hood <0x6e6562 at gmail.com> wrote:

> Edwin,
>
> On Sat, Nov 8, 2008 at 6:09 PM, Edwin Fine
> <rabbitmq-discuss_efine at usa.net> wrote:
> > In terms of an earlier email about how to package the clients and server,
> I
> > see it like this: repackage (and optionally refactor) the server into
> > server-specific components and common components. Make the common
> components
> > a separate Erlang app; ditto for client and server, and have the server
> and
> > client depend on this app. Put in checks on both server and client side
> that
> > they are running with a suitable version of the common app, and fail with
> a
> > clear warning message if this is not the case. Make it easy for users to
> > know which version of the common app the client or server depend on,
> > preferably a simple script that invokes Erlang to delve into the guts and
> > bring out the answer.
>
> I for one would be interested to see if there is any value in turning
> Rabbit into a proper Erlang release. My knowledge on the subject is
> surface deep at best but it seems that there may be some nice to haves
> (e.g. code upgrades). At the end of the day, I shouldn't imagine that
> most users mind where the binaries sit and where the log file goes,
> just as long as there's an easy way to start and stop it, run
> rabbitmqctl and have the server boot on startup. Given the work that
> you've done in this context, could you map out in more concrete terms
> what this would look like?
>

I use Erlware's sinan and faxien for packaging and distribution. They create
"proper" Erlang releases, and make the whole thing much easier than trying
to do it just with OTP. However, like any evolving open-source product,
there are some rough edges and glitches, and less than perfect
documentation, but overall I couldn't live without them. One downside is
that I don't think it supports building on Windows - or is that an upside?
;)

Currently, I have two packaged applications that are rabbit-related, plus
the off-the-shelf Rabbit server/broker itself, which runs on a different
Erlang node. I've done nothing to the broker, which is installed and built
the usual way.

Here's part of the output of my application:which_applications() - slightly
enchanced to include the compile times of all apps - showing the two
"home-grown" rabbit modules. The version numbers are added by me, based on
1.4.0, with any local modifications I have done bumping them up.

[{kernel,"ERTS  CXC 138 10  2008-06-13 02:44:58 UTC",  "2.12.3"},
 {mnesia,"MNESIA  CXC 138 12  2008-06-10 18:33:37 UTC",  "4.4.3"},
 {eunit,"EUnit  2008-07-15 04:40:42 UTC","2.0"},
 {ibrowse,"HTTP client application  2008-11-07 22:48:03 UTC", "1.4"},
 {stdlib,"ERTS  CXC 138 10  2008-06-10 18:29:39 UTC", "1.15.3"},
... snip ...
* {erlang_client,"RabbitMQ Erlang Client.  2008-11-07 22:48:03 UTC", "
1.4.0.2"},
 {rabbitmq_common,"RabbitMQ modules common to client and server  2008-09-09
09:20:25 UTC",  "1.4.0"},
* {yaws,"yaws WWW server  2008-11-07 22:47:59 UTC","1.77"},
 {sasl,"SASL  CXC 138 11  2008-06-10 18:27:34 UTC", "2.1.5.3"}]

The contents of the rabbitmq_common directory are as follows:

./lib
./lib/rabbitmq_common
./lib/rabbitmq_common/include
./lib/rabbitmq_common/include/rabbit_framing_spec.hrl
./lib/rabbitmq_common/include/rabbit.hrl
./lib/rabbitmq_common/include/rabbit_framing.hrl
./lib/rabbitmq_common/src
./lib/rabbitmq_common/src/rabbit_framing_channel.erl
./lib/rabbitmq_common/src/rabbit_misc.erl
./lib/rabbitmq_common/src/rabbit_writer.erl
./lib/rabbitmq_common/src/rabbit_heartbeat.erl
./lib/rabbitmq_common/src/rabbit_binary_parser.erl
./lib/rabbitmq_common/src/rabbit_reader.erl
./lib/rabbitmq_common/src/rabbit_amqqueue.erl
./lib/rabbitmq_common/src/rabbit_framing.erl
./lib/rabbitmq_common/src/rabbit_channel.erl
./lib/rabbitmq_common/src/rabbit_binary_generator.erl
./lib/rabbitmq_common/ebin
./lib/rabbitmq_common/ebin/rabbitmq_common.app ---> I had to write this one,
but it's very simple
./_build.cfg
./control

The _build.cfg is for the Sinan Erlang build application and looks like
this:

project : {
   name : rabbitmq_common,
   vsn  : "1.4.0"
},
repositories : ["http://0.0.0.0/erlware", "http://repo.erlware.org/pub"],
build_dir : _build,
ignore_dirs : ["_", "."],
ignore_apps : [],
default_task :  build

To build, I type in:

$ sinan
Starting run
[check_depends] start
[depends] Pulling eunit-2.0 from repository if non-local
[depends] Pulling stdlib-1.15.3 from repository if non-local
[depends] Pulling kernel-2.12.3 from repository if non-local
[check_depends] stop
[build] start
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_writer.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_reader.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_misc.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_heartbeat.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_framing.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_framing_channel.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_channel.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_binary_parser.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_binary_generator.erl
[build] Building
/home/efine/work/integrat/rabbitmq_common/otp/lib/rabbitmq_common/src/rabbit_amqqueue.erl
[build] stop
run complete

To create a distribution package, I type in

$ sinan dist

To publish the package to the repository servers (which are WebDAV-enabled
Web servers), I just enter

$ faxien publish

To pull down the latest release from the repository servers on a server
somewhere else in the world:

$ faxien install rabbitmq_common

The same goes for the erlang client.

One thing that must be mentioned is that sinan and faxien detect exactly
which Erlang/OTP modules are being used and package only those modules with
the application. That means that the application (e.g. rabbitmq_common)
becomes completely standalone (embedded, really) and does not rely on
whichever version of Erlang is actually installed on the target server.

Then, in my main application, my app file includes the following:

... snip ...
        {applications,
            [
                kernel,
                stdlib,
                sasl,
                mnesia,
                yaws,
                erlang_client, % RabbitMQ client
                rabbitmq_common, % Needed by above client!
                hglib,
                ibrowse
            ]},

I could send you the contents of the directories of the rabbit_common and
erlang_client (after all, it IS your code, just massaged a bit) if you want.

More later, gotta run.

Regards,
Ed

>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20081110/4680ab0e/attachment.htm 


More information about the rabbitmq-discuss mailing list