Skip to content

Cuttlefish for non node_package users

Joe DeVivo edited this page May 14, 2014 · 9 revisions

Basically you've to follow the steps outlined in the Cuttlefish for node_package users guide, but there are some additions since you don't get the free changes to your startup scripts.

First of you need to make sure the cuttlefish binary (aka escript) gets copied over to your release, you can do this by adding this line to your reltool.config in overlay section:

{copy, "../deps/cuttlefish/cuttlefish", "bin/cuttlefish"},

If you want to have a custom named .conf file you also need to put a rebar.config into the rel/ folder containing the like:

{cuttlefish_filename, "sniffle.conf"}.

Then what you have to do is to adjust your startup scripts to honor the configuration options of cuttlefish and make the fish generate your configs. If you're using rebar generated releases the file should be in rel/files/<your app>

So lets look at the parts that need to change. (extra from the node_package code for cuttlefish)

The code extracting the node name, since at this point cuttlefish has not generated a vm.args file the original code would fail. To handle it gracefully it checks first for the old stile vm.args then proceeds to use the cuttlefish config.

# Extract the target node name from node.args
NAME_ARG=`grep -e '-[s]*name' $RUNNER_ETC_DIR/vm.args`
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

has to change to:

# Extract the target node name from node.args
NAME_ARG=`egrep '^\-name' $RUNNER_ETC_DIR/vm.args 2> /dev/null`
if [ -z "$NAME_ARG" ]; then
    NODENAME=`egrep '^[ \t]*nodename[ \t]*=[ \t]*' $RUNNER_ETC_DIR/{{cuttlefish_conf}} 2> /dev/null | tail -n 1 | cut -d = -f 2`
    if [ -z "$NODENAME" ]; then
        echo "vm.args needs to have a -name parameter."
        echo "  -sname is not supported."
        exit 1
    else
        NAME_ARG="-name ${NODENAME# *}"
    fi
fi

Same goes for the code that extracts the cookie:

# Extract the target cookie
COOKIE_ARG=`grep -e '-setcookie' $RUNNER_ETC_DIR/vm.args`
if [ -z "$COOKIE_ARG" ]; then
    echo "vm.args needs to have a -setcookie parameter."
    exit 1
fi

becomes

# Extract the target cookie
COOKIE_ARG=`grep -e '-setcookie' $RUNNER_ETC_DIR/vm.args`
if [ -z "$COOKIE_ARG" ]; then
#TODO: change {{cuttlefish_conf}} to something more senisble!
    COOKIE=`egrep '^[ \t]*distributed_cookie[ \t]*=[ \t]*' $RUNNER_ETC_DIR/{{cuttlefish_conf}} 2> /dev/null | cut -d = -f 2`
    if [ -z "$COOKIE" ]; then
        echo "vm.args needs to have a -setcookie parameter."
        exit 1
    else
        COOKIE_ARG="-setcookie $COOKIE"
    fi
fi

That's it for the preconfiguration, now one thing is left: make cuttlefish generate your files and properly pass them to the VM when started. For this we look at the console section where you find something like this to create the erlexec command line.

        CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -embedded -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"

Since we don't have a app.conf and vm.args when using cuttlefish we need to change this a bit around and add some code to generate our files.

        if CUTTLEFISH_CONFIG=$($RUNNER_BASE_DIR/bin/cuttlefish -e $RUNNER_ETC_DIR -d {{db_path}}/generated.configs -s $RUNNER_BASE_DIR/share/schema/ -c $RUNNER_ETC_DIR/{{cuttlefish_conf}})
        then
            CONFIG_FILES="$CUTTLEFISH_CONFIG"
        else
            echo "Cuttlefish failed! Oh no!: $CUTTLEFISH_CONFIG"
            CONFIG_FILES="-config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/vm.args"
        fi
        CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -embedded $CONFIG_FILES -- ${1+"$@"}"

Please note that your schema folder might be different, so you might need to replace $RUNNER_BASE_DIR/share/schema/ with whatever place you specified in the reltool.conf as a destination for the .schema files.

That's it, happy cuttling!

Note: distributed_cookie and nodename in the snippets above are defined as mappings in your schema files and should be adjusted for your desired naming scheme.

Generating a default conf file

You can manually generate a default .conf file from your schemas at any time with the following snippet.

{_, Mappings, _} = cuttlefish_schema:files(filelib:wildcard("path/to/*.schema")).
ok = cuttlefish_conf:generate_file(Mappings, "path/to/generated.conf").

This is usually handled by the cuttlefish_rebar_plugin, but if you're not using that then this will help.