├── .gitignore ├── priv ├── templates │ ├── deb │ │ ├── changelog │ │ ├── compat │ │ ├── package.manpages │ │ ├── dirs │ │ ├── copyright │ │ ├── Makefile.bootstrap │ │ ├── install │ │ ├── package.service │ │ ├── control │ │ ├── Makefile │ │ ├── vars.config │ │ ├── postinst │ │ ├── deb.template │ │ ├── rules │ │ ├── postrm │ │ └── init.script │ ├── solaris │ │ ├── copyright │ │ ├── depend │ │ ├── pkginfo.tmpl │ │ ├── Makefile.bootstrap │ │ ├── i.preserve │ │ ├── r.preserve │ │ ├── preinstall │ │ ├── vars.config │ │ ├── solaris.template │ │ └── Makefile │ ├── fbsd │ │ ├── +COMMENT │ │ ├── +DESC │ │ ├── Makefile.bootstrap │ │ ├── +DEINSTALL │ │ ├── +DISPLAY │ │ ├── vars.config │ │ ├── fbsd.template │ │ ├── Makefile │ │ └── +MTREE_DIRS │ ├── smartos │ │ ├── +COMMENT │ │ ├── +DESC │ │ ├── +BUILD_INFO │ │ ├── epmd │ │ ├── Makefile.bootstrap │ │ ├── +DEINSTALL │ │ ├── vars.config │ │ ├── epmd-manifest.xml │ │ ├── smartos.template │ │ ├── runner.patch │ │ ├── +DISPLAY │ │ ├── manifest18.xml │ │ ├── manifest131.xml │ │ ├── manifest154.xml │ │ ├── manifest16.xml │ │ ├── +INSTALL │ │ └── Makefile │ ├── osx │ │ ├── Makefile.bootstrap │ │ ├── osx.template │ │ ├── Makefile │ │ └── vars.config │ ├── rpm │ │ ├── Makefile.bootstrap │ │ ├── rpm.template │ │ ├── Makefile │ │ ├── rhel.init.script │ │ ├── suse.init.script │ │ └── specfile │ └── fbsdng │ │ ├── Makefile.bootstrap │ │ ├── rc.d │ │ ├── vars.config │ │ ├── +MANIFEST │ │ ├── fbsdng.template │ │ └── Makefile └── base │ ├── erl │ ├── app_epath.sh │ ├── nodetool │ ├── env.sh │ └── runner ├── src └── node_package.app.src ├── Makefile ├── RELEASE-NOTES.md ├── README.org └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | ebin/ -------------------------------------------------------------------------------- /priv/templates/deb/changelog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /priv/templates/deb/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /priv/templates/solaris/copyright: -------------------------------------------------------------------------------- 1 | {{license_full_text}} -------------------------------------------------------------------------------- /priv/templates/deb/package.manpages: -------------------------------------------------------------------------------- 1 | doc/man/man1/*.1.gz -------------------------------------------------------------------------------- /priv/templates/fbsd/+COMMENT: -------------------------------------------------------------------------------- 1 | {{package_shortdesc}} 2 | -------------------------------------------------------------------------------- /priv/templates/smartos/+COMMENT: -------------------------------------------------------------------------------- 1 | {{package_shortdesc}} 2 | -------------------------------------------------------------------------------- /priv/templates/fbsd/+DESC: -------------------------------------------------------------------------------- 1 | {{package_desc}} 2 | 3 | WWW: {{vendor_url}} 4 | -------------------------------------------------------------------------------- /priv/templates/deb/dirs: -------------------------------------------------------------------------------- 1 | etc/logrotate.d 2 | var/log/{{package_install_name}} 3 | -------------------------------------------------------------------------------- /priv/templates/smartos/+DESC: -------------------------------------------------------------------------------- 1 | {{package_desc}} 2 | 3 | Homepage: 4 | {{vendor_url}} 5 | -------------------------------------------------------------------------------- /priv/templates/smartos/+BUILD_INFO: -------------------------------------------------------------------------------- 1 | ABI=64 2 | MACHINE_ARCH=x86_64 3 | MACHINE_GNU_ARCH=x86_64 4 | OBJECT_FMT=ELF 5 | OPSYS=SunOS 6 | OS_VERSION=5.11 7 | PKGTOOLS_VERSION=20091115 8 | -------------------------------------------------------------------------------- /priv/templates/solaris/depend: -------------------------------------------------------------------------------- 1 | # Same dependencies as Erlang 2 | P SUNWlibmsr Math & Microtasking Libraries (Root) 3 | P SUNWlibms Math & Microtasking Libraries (Usr) 4 | P SUNWopensslr OpenSSL (Root) 5 | P SUNWopenssl-libraries OpenSSL Libraries (Usr) 6 | -------------------------------------------------------------------------------- /priv/templates/deb/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: {{package_name}} 3 | Upstream-Contact: {{vendor_contact_name}} <{{vendor_contact_email}}> 4 | 5 | Files: * 6 | Copyright: {{copyright}} 7 | License: {{license_type}} 8 | {{license_full_text}} 9 | -------------------------------------------------------------------------------- /priv/templates/osx/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | $(REBAR) -v create \ 9 | template_dir=$(PKG_ID)/$(DEPS_DIR)/node_package/priv/templates \ 10 | template_vars=$(PKG_ID)/pkg.vars.config template=osx 11 | make -f Makefile 12 | -------------------------------------------------------------------------------- /priv/templates/rpm/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | $(REBAR) -v create \ 9 | template_dir=$(PKG_ID)/$(DEPS_DIR)/node_package/priv/templates \ 10 | template_vars=$(PKG_ID)/pkg.vars.config template=rpm 11 | make -f Makefile 12 | -------------------------------------------------------------------------------- /priv/templates/smartos/epmd: -------------------------------------------------------------------------------- 1 | # Wrapper script for starting epmd 2 | 3 | . /lib/svc/share/smf_include.sh 4 | 5 | case "$1" in 6 | 'start') 7 | {{platform_base_dir}}/%ERTS_PATH%/bin/epmd -kill 8 | {{platform_base_dir}}/%ERTS_PATH%/bin/epmd -daemon 9 | ;; 10 | 11 | *) 12 | exit 1 13 | ;; 14 | esac 15 | exit 0 16 | -------------------------------------------------------------------------------- /src/node_package.app.src: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | {application, node_package, 5 | [{description, "RPM/Debian/Solaris packaging templates for Erlang Nodes"}, 6 | {vsn, git}, 7 | {modules, []}, 8 | {registered, []}, 9 | {applications, [kernel, stdlib]} 10 | ]}. 11 | -------------------------------------------------------------------------------- /priv/templates/osx/osx.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% 3 | {variables, [ 4 | {package_name, "package_name"}, 5 | {package_install_name, "package_install_name"}, 6 | {package_install_user, "package_install_user"} 7 | ] 8 | }. 9 | {template, "Makefile", "Makefile"}. 10 | {template, "vars.config", "vars.config"}. 11 | -------------------------------------------------------------------------------- /priv/templates/solaris/pkginfo.tmpl: -------------------------------------------------------------------------------- 1 | # Set this for the default basedir for relocatable packages 2 | BASEDIR=/opt 3 | CLASSES=none preserve 4 | TZ=EST 5 | PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin 6 | PKG=@@PKG@@ 7 | NAME=@@PKGNAME@@ 8 | VERSION=@@VERSION@@ 9 | CATEGORY=application 10 | DESC={{package_descr}} 11 | VENDOR={{vendor_name}} 12 | EMAIL={{vendor_contact_email}} 13 | PKGSAV=/var/sadm/pkg/@@PKG@@/save 14 | -------------------------------------------------------------------------------- /priv/templates/deb/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | mkdir -p $(PKG_ID)/debian 9 | cd $(PKG_ID)/debian && $(REBAR) -v create \ 10 | template_dir=../$(DEPS_DIR)/node_package/priv/templates \ 11 | template_vars=../pkg.vars.config template=deb 12 | make -C $(PKG_ID) -f debian/Makefile 13 | -------------------------------------------------------------------------------- /priv/templates/fbsd/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | mkdir -p $(PKG_ID)/fbsd 9 | cd $(PKG_ID)/fbsd && $(REBAR) -v create \ 10 | template_dir=../$(DEPS_DIR)/node_package/priv/templates \ 11 | template_vars=../pkg.vars.config template=fbsd 12 | $(MAKE) -C $(PKG_ID) -f fbsd/Makefile 13 | -------------------------------------------------------------------------------- /priv/templates/fbsdng/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | mkdir -p $(PKG_ID)/fbsdng 9 | cd $(PKG_ID)/fbsdng && $(REBAR) -v create \ 10 | template_dir=../$(DEPS_DIR)/node_package/priv/templates \ 11 | template_vars=../pkg.vars.config template=fbsdng 12 | $(MAKE) -C $(PKG_ID) -f fbsdng/Makefile 13 | -------------------------------------------------------------------------------- /priv/templates/smartos/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | mkdir -p $(PKG_ID)/smartos 9 | cd $(PKG_ID)/smartos && $(REBAR) -v create \ 10 | template_dir=../$(DEPS_DIR)/node_package/priv/templates \ 11 | template_vars=../pkg.vars.config template=smartos 12 | $(MAKE) -C $(PKG_ID) -f smartos/Makefile 13 | -------------------------------------------------------------------------------- /priv/templates/solaris/Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | 2 | ## 3 | ## Export all variables to sub-invocation 4 | ## 5 | export 6 | 7 | bootstrap: 8 | mkdir -p $(PKG_ID)/solaris 9 | cd $(PKG_ID)/solaris && $(REBAR) -v create \ 10 | template_dir=../$(DEPS_DIR)/node_package/priv/templates \ 11 | template_vars=../pkg.vars.config template=solaris 12 | $(MAKE) -C $(PKG_ID) -f solaris/Makefile 13 | -------------------------------------------------------------------------------- /priv/templates/deb/install: -------------------------------------------------------------------------------- 1 | rel/{{package_install_name}}/lib usr/lib/{{package_install_name}} 2 | rel/{{package_install_name}}/erts* usr/lib/{{package_install_name}} 3 | rel/{{package_install_name}}/releases usr/lib/{{package_install_name}} 4 | 5 | {{#package_commands}} 6 | rel/{{package_install_name}}/bin/{{name}} usr/{{bin_or_sbin}} 7 | {{/package_commands}} 8 | 9 | rel/{{package_install_name}}/etc/* etc/{{package_install_name}} 10 | rel/{{package_install_name}}/data/* var/lib/{{package_install_name}} -------------------------------------------------------------------------------- /priv/templates/deb/package.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description={{package_shortdesc}} 3 | 4 | [Service] 5 | ExecStart=/usr/{{bin_or_sbin}}/{{package_install_name}} start 6 | ExecStop=/usr/{{bin_or_sbin}}/{{package_install_name}} stop 7 | User={{package_install_user}} 8 | Type=forking 9 | PIDFile=/var/run/{{package_install_name}}/{{package_install_name}}.pid 10 | EnvironmentFile=-/etc/default/{{package_install_name}} 11 | RuntimeDirectory={{package_install_name}} 12 | 13 | [Install] 14 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /priv/templates/fbsdng/rc.d: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # $FreeBSD$ 4 | # 5 | # PROVIDE: {{package_install_name}} 6 | # REQUIRE: LOGIN 7 | # KEYWORD: shutdown 8 | 9 | . /etc/rc.subr 10 | 11 | name={{package_install_name}} 12 | command={{platform_base_dir}}/%ERTS_PATH%/bin/beam.smp 13 | rcvar={{package_install_name}}_enable 14 | start_cmd="{{platform_bin_dir}}/${name} start" 15 | stop_cmd="{{platform_bin_dir}}/${name} stop" 16 | pidfile="/var/run/${name}/${name}.pid" 17 | 18 | load_rc_config $name 19 | run_rc_command "$1" 20 | -------------------------------------------------------------------------------- /priv/templates/fbsd/+DEINSTALL: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$2" != "POST-DEINSTALL" ]; then 4 | exit 0 5 | fi 6 | 7 | USER={{package_install_user}} 8 | 9 | if pw usershow "${USER}" 2>/dev/null 1>&2; then 10 | echo "To delete {{package_name}} user permanently, use 'pw userdel ${USER}'" 11 | fi 12 | 13 | echo "" 14 | echo "To completely clean your system you will need to remove the following directories manually" 15 | echo "* {{platform_data_dir}}" 16 | echo "* {{platform_log_dir}}" 17 | 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /priv/templates/solaris/i.preserve: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # {{copyright}} 4 | # 5 | 6 | # 7 | # If files are marked as "preserve" we want to simple install the new files 8 | # along side the original with a unique-ish name 9 | # 10 | 11 | while read src dest; do 12 | if [ ! -f $dest ] ; then 13 | cp $src $dest 14 | else 15 | format=`date '+%Y-%m-%d-%H:%M'` 16 | cp $src $dest.$format 17 | echo "$dest exists, not replacing. Saving as $dest.$format instead." 18 | fi 19 | done 20 | -------------------------------------------------------------------------------- /priv/templates/deb/control: -------------------------------------------------------------------------------- 1 | Source: {{package_name}} 2 | Section: net 3 | Priority: extra 4 | Maintainer: {{vendor_contact_name}} <{{vendor_contact_email}}> 5 | Build-Depends: debhelper (>= 7) 6 | Standards-Version: 3.9.3 7 | Homepage: {{vendor_url}} 8 | 9 | Package: {{package_name}} 10 | Architecture: any 11 | Depends: ${misc:Depends}, ${shlibs:Depends}, adduser, logrotate, sudo, {{deb_depends}} 12 | Homepage: {{vendor_url}} 13 | Description: {{package_shortdesc}} 14 | {{package_desc}} 15 | {{package_replacement_line}} 16 | {{package_conflicts_line}} 17 | -------------------------------------------------------------------------------- /priv/templates/solaris/r.preserve: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # {{copyright}} 4 | 5 | PKGBASE=/var/sadm/pkg/{{solaris_pkgname}} 6 | RELOC=$PKGBASE/save/pspool/{{solaris_pkgname}}/reloc 7 | 8 | while read dest 9 | do 10 | orig=$RELOC/`echo $dest | cut -d / -f 3-` 11 | 12 | dsum=`sum $dest | cut -d ' ' -f 1` 13 | osum=`sum $orig | cut -d ' ' -f 1` 14 | 15 | if [ "$dsum" = "$osum" ] ; then 16 | # The file is the same as the original, just remove it 17 | rm -f $dest 18 | else 19 | echo "Not removing changed file $dest" 20 | fi 21 | done 22 | -------------------------------------------------------------------------------- /priv/templates/osx/Makefile: -------------------------------------------------------------------------------- 1 | PKGNAME = {{package_name}}-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tar.gz 2 | 3 | default: buildrel 4 | mkdir -p packages 5 | mkdir -p osxbuild 6 | cd $(PKG_ID) && \ 7 | cp -R rel/{{package_install_name}} \ 8 | ../osxbuild/{{package_name}}-$(PKG_VERSION) 9 | cd osxbuild && \ 10 | tar -czf ../packages/$(PKGNAME) \ 11 | {{package_name}}-$(PKG_VERSION) 12 | cd packages && \ 13 | for tarfile in *.gz; do \ 14 | shasum -a 256 $${tarfile} > $${tarfile}.sha \ 15 | ; done 16 | 17 | 18 | buildrel: $(PKG_ID) 19 | cd $^ && \ 20 | OVERLAY_VARS="overlay_vars=../../vars.config" $(MAKE) rel 21 | -------------------------------------------------------------------------------- /priv/templates/solaris/preinstall: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # create {{package_install_group}} group only if it doesn't already exist 4 | getent group {{package_install_group}} >/dev/null 2>&1 5 | if [ $? -ne 0 ]; then 6 | groupadd {{package_install_group}} 7 | fi 8 | 9 | # create {{package_install_user}} user only if it doesn't already exist 10 | getent passwd {{package_install_user}} >/dev/null 2>&1 11 | if [ $? -ne 0 ]; then 12 | useradd -g {{package_install_group}} -d {{platform_data_dir}} -s /usr/bin/ksh {{package_install_user}} 13 | usermod -c "{{package_install_user_desc}}" {{package_install_user}} 14 | fi 15 | 16 | -------------------------------------------------------------------------------- /priv/templates/fbsd/+DISPLAY: -------------------------------------------------------------------------------- 1 | Thank you for installing {{package_name}}. 2 | 3 | {{package_name}} has been installed in /usr/local owned by user:group root:wheel 4 | 5 | The primary directories are: 6 | 7 | {platform_bin_dir, "{{platform_bin_dir}}"} 8 | {platform_data_dir, "{{platform_data_dir}}"} 9 | {platform_etc_dir, "{{platform_etc_dir}}"} 10 | {platform_lib_dir, "{{platform_lib_dir}}"} 11 | {platform_log_dir, "{{platform_log_dir}}"} 12 | 13 | These can be configured and changed in the {{platform_etc_dir}}/app.config. 14 | 15 | Add {{platform_bin_dir}} to your path to run {{#package_commands}}{{name}} {{/package_commands}} directly. 16 | 17 | Man pages are available for {{#package_commands}}{{name}}(1) {{/package_commands}} 18 | -------------------------------------------------------------------------------- /priv/templates/deb/Makefile: -------------------------------------------------------------------------------- 1 | 2 | default: 3 | ln -sf $(PKG_ID).tar.gz ../{{package_name}}_$(PKG_VERSION).orig.tar.gz 4 | export DEBFULLNAME="{{vendor_contact_name}}"; \ 5 | export DEBEMAIL="{{vendor_contact_email}}"; \ 6 | dch --create --package {{package_name}} -v "$(PKG_VERSION)-$(PKG_BUILD)" \ 7 | "Build from $(PKG_VERSION)";\ 8 | debuild --prepend-path=$(ERLANG_BIN) \ 9 | -e REVISION=$(PKG_VERSION) \ 10 | -e RELEASE=$(PKG_BUILD) \ 11 | -e REBAR=$(REBAR) \ 12 | {{debuild_extra_options}} \ 13 | -uc -us 14 | mkdir -p ../packages 15 | cd .. && mv *$(PKG_VERSION)-$(PKG_BUILD)_*.deb packages 16 | cd ../packages && \ 17 | for debfile in *.deb; do \ 18 | sha256sum $${debfile} > $${debfile}.sha \ 19 | ; done 20 | -------------------------------------------------------------------------------- /priv/templates/osx/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Set base and script directories to 5 | %% runner_base_dir (RUNNER_BASE_DIR) will be the root 6 | %% result of reltool generate 7 | %% The runner_script directory will be typically bin or 8 | %% sbin within that runner_base_dir 9 | {runner_script_dir, "$(cd ${0%/*} && pwd)"}. 10 | {runner_base_dir, "$(cd ${0%/*} && pwd)/.."}. 11 | {runner_etc_dir, "$RUNNER_BASE_DIR/etc"}. 12 | {runner_log_dir, "$RUNNER_BASE_DIR/log"}. 13 | {runner_lib_dir, "$RUNNER_BASE_DIR/lib"}. 14 | {runner_patch_dir, "$RUNNER_BASE_DIR/lib/{{package_patch_dir}}"}. 15 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 16 | 17 | -------------------------------------------------------------------------------- /priv/templates/smartos/+DEINSTALL: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$2" != "POST-DEINSTALL" ]; then 4 | exit 0 5 | fi 6 | 7 | 8 | if getent group "{{package_install_group}}" 2>/dev/null 1>&2; then 9 | echo "To delete {{package_install_group}} group permanently, use 'groupdel {{package_install_group}}'" 10 | fi 11 | 12 | if getent passwd "{{package_install_user}}" 2>/dev/null 1>&2; then 13 | echo "To delete {{package_install_user}} user permanently, use 'userdel {{package_install_user}}'" 14 | fi 15 | 16 | echo "-------------------------------------------------------" 17 | echo "Data and log directories were not removed automatically" 18 | echo "Remove {{platform_data_dir}} and {{platform_log_dir}} to" 19 | echo "completely clean your system" 20 | echo "-------------------------------------------------------" 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /priv/templates/fbsd/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Platform-specific installation paths 5 | {platform_bin_dir, "{{platform_bin_dir}}"}. 6 | {platform_data_dir, "{{platform_data_dir}}"}. 7 | {platform_etc_dir, "{{platform_etc_dir}}"}. 8 | {platform_base_dir, "{{platform_base_dir}}"}. 9 | {platform_lib_dir, "{{platform_lib_dir}}"}. 10 | {platform_log_dir, "{{platform_log_dir}}"}. 11 | 12 | %% TODO can we just get rid of these? 13 | {runner_script_dir, "{{platform_bin_dir}}"}. 14 | {runner_base_dir, "{{platform_base_dir}}"}. 15 | {runner_etc_dir, "{{platform_etc_dir}}"}. 16 | {runner_log_dir, "{{platform_log_dir}}"}. 17 | {runner_user, "{{package_install_user}}"}. 18 | {runner_lib_dir, "{{platform_lib_dir}}"}. 19 | {runner_patch_dir, "{{platform_lib_dir}}/{{package_patch_dir}}"}. 20 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 21 | -------------------------------------------------------------------------------- /priv/templates/fbsdng/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Platform-specific installation paths 5 | {platform_bin_dir, "{{platform_bin_dir}}"}. 6 | {platform_data_dir, "{{platform_data_dir}}"}. 7 | {platform_etc_dir, "{{platform_etc_dir}}"}. 8 | {platform_base_dir, "{{platform_base_dir}}"}. 9 | {platform_lib_dir, "{{platform_lib_dir}}"}. 10 | {platform_log_dir, "{{platform_log_dir}}"}. 11 | 12 | %% TODO can we just get rid of these? 13 | {runner_script_dir, "{{platform_bin_dir}}"}. 14 | {runner_base_dir, "{{platform_base_dir}}"}. 15 | {runner_etc_dir, "{{platform_etc_dir}}"}. 16 | {runner_log_dir, "{{platform_log_dir}}"}. 17 | {runner_user, "{{package_install_user}}"}. 18 | {runner_lib_dir, "{{platform_lib_dir}}"}. 19 | {runner_patch_dir, "{{platform_lib_dir}}/{{package_patch_dir}}"}. 20 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 21 | -------------------------------------------------------------------------------- /priv/templates/smartos/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Platform-specific installation paths 5 | {platform_bin_dir, "{{platform_bin_dir}}"}. 6 | {platform_data_dir, "{{platform_data_dir}}"}. 7 | {platform_etc_dir, "{{platform_etc_dir}}"}. 8 | {platform_base_dir, "{{platform_base_dir}}"}. 9 | {platform_lib_dir, "{{platform_lib_dir}}"}. 10 | {platform_log_dir, "{{platform_log_dir}}"}. 11 | 12 | %% TODO can we just get rid of these? 13 | {runner_script_dir, "{{platform_bin_dir}}"}. 14 | {runner_base_dir, "{{platform_base_dir}}"}. 15 | {runner_etc_dir, "{{platform_etc_dir}}"}. 16 | {runner_log_dir, "{{platform_log_dir}}"}. 17 | {runner_user, "{{package_install_user}}"}. 18 | {runner_lib_dir, "{{platform_lib_dir}}"}. 19 | {runner_patch_dir, "{{platform_lib_dir}}/{{package_patch_dir}}"}. 20 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 21 | -------------------------------------------------------------------------------- /priv/templates/solaris/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Platform-specific installation paths 5 | {platform_bin_dir, "{{platform_bin_dir}}"}. 6 | {platform_data_dir, "{{platform_data_dir}}"}. 7 | {platform_etc_dir, "{{platform_etc_dir}}"}. 8 | {platform_base_dir, "{{platform_base_dir}}"}. 9 | {platform_lib_dir, "{{platform_lib_dir}}"}. 10 | {platform_log_dir, "{{platform_log_dir}}"}. 11 | 12 | %% TODO can we just get rid of these? 13 | {runner_script_dir, "{{platform_bin_dir}}"}. 14 | {runner_base_dir, "{{platform_base_dir}}"}. 15 | {runner_etc_dir, "{{platform_etc_dir}}"}. 16 | {runner_log_dir, "{{platform_log_dir}}"}. 17 | {runner_user, "{{package_install_user}}"}. 18 | {runner_lib_dir, "{{platform_lib_dir}}"}. 19 | {runner_patch_dir, "{{platform_lib_dir}}/{{package_patch_dir}}"}. 20 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 21 | -------------------------------------------------------------------------------- /priv/templates/rpm/rpm.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% 3 | {variables, [ 4 | {package_name, "package_name"}, 5 | {package_install_name, "package_install_name"}, 6 | {package_install_user, "package_install_user"}, 7 | {package_install_user_desc, "package_install_user_desc"}, 8 | {package_install_group, "package_install_group"}, 9 | {license_type, "license_type"}, 10 | {license_full_text, "license_full_text"}, 11 | {vendor_name, "vendor_name"}, 12 | {vendor_url, "vendor_url"}, 13 | {vendor_contact_name, "vendor_contact"}, 14 | {vendor_contact_email, "vendor_contact_email"}, 15 | {bin_or_sbin, "bin"} 16 | ] 17 | }. 18 | {template, "Makefile", "Makefile"}. 19 | {template, "specfile", "specfile"}. 20 | {template, "rhel.init.script", "rhel.init.script"}. 21 | {template, "suse.init.script", "suse.init.script"}. 22 | -------------------------------------------------------------------------------- /priv/templates/fbsdng/+MANIFEST: -------------------------------------------------------------------------------- 1 | name: "{{package_name}}" 2 | origin: "{{freebsd_package_category}}" 3 | comment: "{{package_shortdesc}}" 4 | licenses: ["{{license_type}}"] 5 | licenselogic: "single" 6 | arch: "freebsd:10:x86:64" 7 | www: "{{vendor_url}}" 8 | maintainer: "{{vendor_contact_email}}" 9 | users: ["{{package_install_user}}"] 10 | groups: ["{{package_install_group}}"] 11 | prefix: "/usr/local" 12 | categories: ["{{freebsd_package_category}}"] 13 | desc: "{{package_desc}}" 14 | scripts: { 15 | pre-install: "if ! pw groupshow {{package_install_group}} 2>/dev/null; then pw groupadd {{package_install_group}}; fi \n if ! pw usershow {{package_install_user}} 2>/dev/null; then pw useradd {{package_install_user}} -g {{package_install_group}} -h - -d {{platform_data_dir}} -s /bin/sh -c \"{{package_install_user_desc}}\"; fi \n if [ ! -d /var/log/{{package_install_name}} ]; then mkdir /var/log/{{package_install_name}} && chown {{package_install_user}}:{{package_install_group}} /var/log/{{package_install_name}}; fi" 16 | } 17 | -------------------------------------------------------------------------------- /priv/templates/deb/vars.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | 4 | %% Platform-specific installation paths 5 | {platform_bin_dir, "{{platform_bin_dir}}"}. 6 | {platform_data_dir, "{{platform_data_dir}}"}. 7 | {platform_etc_dir, "{{platform_etc_dir}}"}. 8 | {platform_base_dir, "{{platform_base_dir}}"}. 9 | {platform_lib_dir, "{{platform_lib_dir}}"}. 10 | {platform_log_dir, "{{platform_log_dir}}"}. 11 | 12 | {runner_script_dir, "{{platform_bin_dir}}"}. 13 | {runner_base_dir, "{{platform_base_dir}}"}. 14 | {runner_etc_dir, "{{platform_etc_dir}}"}. 15 | {runner_log_dir, "{{platform_log_dir}}"}. 16 | {runner_user, "{{package_install_user}}"}. 17 | {runner_lib_dir, "{{platform_lib_dir}}"}. 18 | {runner_patch_dir, "{{platform_lib_dir}}/{{package_patch_dir}}"}. 19 | {pipe_dir, "/tmp/{{package_install_name}}/"}. 20 | {package_replacement_line, "{{package_replacement_line_debian}}"}. 21 | {package_conflicts_line, "{{package_replacement_line_debian}}"}. 22 | -------------------------------------------------------------------------------- /priv/templates/deb/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postinst script for {{package_name}} 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | # create group 9 | if ! getent group {{package_install_group}} >/dev/null; then 10 | addgroup --system {{package_install_group}} 11 | fi 12 | 13 | # create user 14 | if ! getent passwd {{package_install_user}} >/dev/null; then 15 | adduser --ingroup {{package_install_group}} \ 16 | --home /var/lib/{{package_install_name}} \ 17 | --disabled-password \ 18 | --system --shell /bin/bash --no-create-home \ 19 | --gecos "{{package_install_user_desc}}" {{package_install_user}} 20 | fi 21 | 22 | for i in lib log; do 23 | chown -R {{package_install_user}}:{{package_install_group}} /var/$i/{{package_install_name}} 24 | done 25 | 26 | case "$1" in 27 | configure) 28 | ;; 29 | 30 | abort-upgrade|abort-remove|abort-deconfigure) 31 | ;; 32 | 33 | *) 34 | echo "postinst called with unknown argument \`$1'" >&2 35 | exit 1 36 | ;; 37 | esac 38 | 39 | # dh_installdeb will replace this with shell code automatically 40 | # generated by other debhelper scripts. 41 | 42 | #DEBHELPER# 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /priv/templates/fbsdng/fbsdng.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | %% 4 | {variables, [ 5 | {package_name, "package_name"}, 6 | {package_install_name, "package_install_name"}, 7 | {package_install_user, "package_install_user"}, 8 | {package_install_user_desc, "package_install_user_desc"}, 9 | {package_install_group, "package_install_group"}, 10 | {bin_or_sbin, "bin"}, 11 | {freebsd_package_category, "db"}, 12 | 13 | %% Platform-specific installation paths 14 | {platform_bin_dir, "/usr/local/{{bin_or_sbin}}"}, 15 | {platform_data_dir, "/usr/local/{{package_install_name}}"}, 16 | {platform_etc_dir, "/usr/local/etc/{{package_install_name}}"}, 17 | {platform_base_dir, "/usr/local/lib/{{package_install_name}}"}, 18 | {platform_lib_dir, "/usr/local/lib/{{package_install_name}}/lib"}, 19 | {platform_log_dir, "/var/log/{{package_install_name}}"} 20 | ] 21 | }. 22 | {template, "Makefile", "Makefile"}. 23 | {template, "vars.config", "vars.config"}. 24 | {template, "+MANIFEST", "+MANIFEST"}. 25 | {template, "rc.d", "rc.d"}. 26 | -------------------------------------------------------------------------------- /priv/templates/rpm/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PWD = $(shell pwd) 3 | 4 | 5 | ifeq ($(OSNAME),RedHat) 6 | DISTRO = $(shell head -1 /etc/redhat-release| awk \ 7 | '{if ($$0 ~ /CentOS release 5/) { print ".el5."} else { print "." }} ') 8 | INITSCRIPT=rhel.init.script 9 | endif 10 | ifeq ($(OSNAME),SLES) 11 | DISTRO = .SLES$(shell grep VERSION /etc/SuSE-release | cut -d ' ' -f 3). 12 | INITSCRIPT=suse.init.script 13 | endif 14 | 15 | # No hyphens are allowed in the _version field in RPM 16 | PKG_VERSION_NO_H ?= $(shell echo $(PKG_VERSION) | tr - .) 17 | 18 | default: init.script 19 | mkdir -p BUILD 20 | mkdir -p packages 21 | rpmbuild --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}$(DISTRO)%%{ARCH}.rpm" \ 22 | --define '_topdir $(PWD)' \ 23 | --define '_sourcedir $(PWD)' \ 24 | --define '_specdir $(PWD)' \ 25 | --define '_rpmdir $(PWD)/packages' \ 26 | --define '_srcrpmdir $(PWD)/packages' \ 27 | --define "_revision $(PKG_VERSION)" \ 28 | --define "_version $(PKG_VERSION_NO_H)" \ 29 | --define "_release $(PKG_BUILD)" \ 30 | --define "_tarname $(PKG_ID).tar.gz" \ 31 | --define "_tarname_base $(PKG_ID)" \ 32 | -ba $(PWD)/specfile 33 | cd packages && \ 34 | for rpmfile in *.rpm; do \ 35 | sha256sum $${rpmfile} > $${rpmfile}.sha \ 36 | ; done 37 | 38 | init.script: 39 | cp $(INITSCRIPT) init.script 40 | -------------------------------------------------------------------------------- /priv/templates/fbsd/fbsd.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | %% 4 | {variables, [ 5 | {package_name, "package_name"}, 6 | {package_install_name, "package_install_name"}, 7 | {package_install_user, "package_install_user"}, 8 | {package_install_user_desc, "package_install_user_desc"}, 9 | {package_install_group, "package_install_group"}, 10 | {bin_or_sbin, "bin"}, 11 | {freebsd_package_category, "db"}, 12 | 13 | %% Platform-specific installation paths 14 | {platform_bin_dir, "/usr/local/{{bin_or_sbin}}"}, 15 | {platform_data_dir, "/var/db/{{package_install_name}}"}, 16 | {platform_etc_dir, "/usr/local/etc/{{package_install_name}}"}, 17 | {platform_base_dir, "/usr/local/lib/{{package_install_name}}"}, 18 | {platform_lib_dir, "/usr/local/lib/{{package_install_name}}/lib"}, 19 | {platform_log_dir, "/var/log/{{package_install_name}}"} 20 | ] 21 | }. 22 | {template, "Makefile", "Makefile"}. 23 | {template, "vars.config", "vars.config"}. 24 | {template, "+COMMENT", "+COMMENT"}. 25 | {template, "+DEINSTALL", "+DEINSTALL"}. 26 | {template, "+DESC", "+DESC"}. 27 | {template, "+DISPLAY", "+DISPLAY"}. 28 | {template, "+MTREE_DIRS", "+MTREE_DIRS"}. 29 | -------------------------------------------------------------------------------- /priv/templates/solaris/solaris.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | %% 4 | {variables, [ 5 | {package_name, "package_name"}, 6 | {package_install_name, "package_install_name"}, 7 | {package_install_user, "package_install_user"}, 8 | {package_install_user_desc, "package_install_user_desc"}, 9 | {package_install_group, "package_install_group"}, 10 | {bin_or_sbin, "bin"}, 11 | 12 | %% Platform-specific installation paths 13 | {platform_bin_dir, "/opt/{{package_install_name}}/{{bin_or_sbin}}"}, 14 | {platform_data_dir, "/opt/{{package_install_name}}/data"}, 15 | {platform_etc_dir, "/opt/{{package_install_name}}/etc"}, 16 | {platform_base_dir, "/opt/{{package_install_name}}"}, 17 | {platform_lib_dir, "/opt/{{package_install_name}}/lib"}, 18 | {platform_log_dir, "/opt/{{package_install_name}}/log"}, 19 | {solaris_pkgname, "MAINTapp"} 20 | ] 21 | }. 22 | {template, "Makefile", "Makefile"}. 23 | {template, "vars.config", "vars.config"}. 24 | {template, "copyright", "copyright"}. 25 | {template, "depend", "depend"}. 26 | {template, "i.preserve", "i.preserve"}. 27 | {template, "pkginfo.tmpl", "pkginfo.tmpl"}. 28 | {template, "preinstall", "preinstall"}. 29 | {template, "r.preserve", "r.preserve"}. 30 | -------------------------------------------------------------------------------- /priv/base/erl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. 4 | if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then 5 | POSIX_SHELL="true" 6 | export POSIX_SHELL 7 | exec /usr/bin/ksh $0 "$@" 8 | fi 9 | unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well 10 | 11 | 12 | ## This script replaces the default "erl" in erts-VSN/bin. This is necessary 13 | ## as escript depends on erl and in turn, erl depends on having access to a 14 | ## bootscript (start.boot). Note that this script is ONLY invoked as a side-effect 15 | ## of running escript -- the embedded node bypasses erl and uses erlexec directly 16 | ## (as it should). 17 | ## 18 | ## Note that this script makes the assumption that there is a start_clean.boot 19 | ## file available in $ROOTDIR/release/VSN. 20 | 21 | ## installed by node_package (github.com/basho/node_package) 22 | 23 | # Determine the abspath of where this script is executing from. 24 | ERTS_BIN_DIR=$(cd ${0%/*} && pwd) 25 | 26 | # Now determine the root directory -- this script runs from erts-VSN/bin, 27 | # so we simply need to strip off two dirs from the end of the ERTS_BIN_DIR 28 | # path. 29 | ROOTDIR=${ERTS_BIN_DIR%/*/*} 30 | 31 | # Parse out release and erts info 32 | START_ERL=`cat $ROOTDIR/releases/start_erl.data` 33 | ERTS_VSN=${START_ERL% *} 34 | APP_VSN=${START_ERL#* } 35 | 36 | BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin 37 | EMU=beam 38 | PROGNAME=`echo $0 | sed 's/.*\///'` 39 | CMD="$BINDIR/erlexec" 40 | export EMU 41 | export ROOTDIR 42 | export BINDIR 43 | export PROGNAME 44 | 45 | exec $CMD -boot $ROOTDIR/releases/$APP_VSN/start_clean ${1+"$@"} 46 | -------------------------------------------------------------------------------- /priv/templates/smartos/epmd-manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /priv/templates/smartos/smartos.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% ex: ft=erlang ts=4 sw=4 et 3 | %% 4 | {variables, [ 5 | {package_name, "package_name"}, 6 | {package_install_name, "package_install_name"}, 7 | {package_install_user, "package_install_user"}, 8 | {package_install_user_desc, "package_install_user_desc"}, 9 | {package_install_group, "package_install_group"}, 10 | {bin_or_sbin, "bin"}, 11 | 12 | %% Platform specific settings 13 | {platform_bin_dir, "/opt/local/{{bin_or_sbin}}"}, 14 | {platform_data_dir, "/var/db/{{package_install_name}}"}, 15 | {platform_etc_dir, "/opt/local/etc/{{package_install_name}}"}, 16 | {platform_base_dir, "/opt/local/lib/{{package_install_name}}"}, 17 | {platform_lib_dir, "/opt/local/lib/{{package_install_name}}/lib"}, 18 | {platform_log_dir, "/var/log/{{package_install_name}}"} 19 | ] 20 | }. 21 | {template, "Makefile", "Makefile"}. 22 | {template, "vars.config", "vars.config"}. 23 | {template, "+BUILD_INFO", "+BUILD_INFO"}. 24 | {template, "+COMMENT", "+COMMENT"}. 25 | {template, "+DEINSTALL", "+DEINSTALL"}. 26 | {template, "+DESC", "+DESC"}. 27 | {template, "+DISPLAY", "+DISPLAY"}. 28 | {template, "+INSTALL", "+INSTALL"}. 29 | {template, "epmd-manifest.xml", "epmd-manifest.xml"}. 30 | {template, "manifest16.xml", "manifest16.xml"}. 31 | {template, "manifest18.xml", "manifest18.xml"}. 32 | {template, "manifest131.xml", "manifest131.xml"}. 33 | {template, "manifest154.xml", "manifest154.xml"}. 34 | {template, "epmd", "epmd"}. 35 | {template, "runner.patch", "runner.patch"}. 36 | -------------------------------------------------------------------------------- /priv/templates/smartos/runner.patch: -------------------------------------------------------------------------------- 1 | 176,177c176,182 2 | < # Warn the user if ulimit is too low 3 | < check_ulimit 4 | --- 5 | > # Make sure we have access to enough file descriptors 6 | > ULIMIT_S=$(prctl -n process.max-file-descriptor -t system -P $$ | awk '/max-file-descriptor/ { print $3 }') 7 | > ULIMIT_H=$(prctl -n process.max-file-descriptor -t priv -P $$ | awk '/max-file-descriptor/ { print $3 }') 8 | > if [ ${ULIMIT_S} -lt ${ULIMIT_H} ]; then 9 | > echo "Trying to raise the file descriptor limit to maximum allowed." 10 | > prctl -n process.max-file-descriptor -t system -v ${ULIMIT_H} $$ || true 11 | > fi 12 | 250a256,260 13 | > if [ "${SMF_METHOD}" != "start" ]; then 14 | > echo "***" 15 | > echo "Warning: please use 'svcadm enable $SCRIPT' instead" 16 | > echo "***" 17 | > fi 18 | 256a267,271 19 | > if [ "${SMF_METHOD}" != "stop" ]; then 20 | > echo "***" 21 | > echo "Warning: please use 'svcadm disable $SCRIPT' instead" 22 | > echo "***" 23 | > fi 24 | 327,328c342,348 25 | < # Warn the user if ulimit -n is less than the defined threshold 26 | < check_ulimit 27 | --- 28 | > # Make sure we have access to enough file descriptors 29 | > ULIMIT_S=$(prctl -n process.max-file-descriptor -t system -P $$ | awk '/max-file-descriptor/ { print $3 }') 30 | > ULIMIT_H=$(prctl -n process.max-file-descriptor -t priv -P $$ | awk '/max-file-descriptor/ { print $3 }') 31 | > if [ ${ULIMIT_S} -lt ${ULIMIT_H} ]; then 32 | > echo "Trying to raise the file descriptor limit to maximum allowed." 33 | > prctl -n process.max-file-descriptor -t system -v ${ULIMIT_H} $$ || true 34 | > fi 35 | -------------------------------------------------------------------------------- /priv/templates/smartos/+DISPLAY: -------------------------------------------------------------------------------- 1 | Thank you for installing {{package_name}}. 2 | 3 | {{package_name}} has been installed in {{platform_base_dir}} owned by user:group root:root 4 | 5 | The primary directories are: 6 | 7 | {platform_bin_dir, "{{platform_bin_dir}}"} 8 | {platform_data_dir, "{{platform_data_dir}}"} 9 | {platform_etc_dir, "{{platform_etc_dir}}"} 10 | {platform_lib_dir, "{{platform_lib_dir}}"} 11 | {platform_log_dir, "{{platform_log_dir}}"} 12 | 13 | These can be configured and changed in the configuration files in {{platform_etc_dir}} 14 | 15 | Add {{platform_bin_dir}} to your path to run the {{#package_commands}}{{name}} {{/package_commands}} directly. 16 | 17 | Man pages are available for {{#package_commands}}{{name}}(1) {{/package_commands}} 18 | 19 | ////////////////////////////////////////////////////////////////////////////// 20 | 21 | This package is SMF enabled, which means you can use SMF to 'enable', 22 | 'disable' or 'restart' the persistent daemon process, e.g.: 23 | 24 | $ svcadm enable -r {{package_install_name}} 25 | 26 | Two SMF manifests were created, "{{package_install_name}}-epmd" and "{{package_install_name}}". {{package_name}} depends 27 | on the "{{package_install_name}}-epmd" service to be enabled, so either use "-r" to specify 28 | to "svcadm" (as shown above) to recursively start dependencies or 29 | start each service independent of each other. 30 | 31 | $ svcadm enable {{package_install_name}}-epmd 32 | $ svcadm enable {{package_install_name}} 33 | 34 | You should *NOT* stop or restart the "{{package_install_name}}-epmd" service at any time, 35 | if you need to restart {{package_name}}, just restart the "{{package_install_name}}" service. 36 | 37 | See the SmartOS wiki on what's SMF and how to use it to your advantage: 38 | 39 | http://wiki.joyent.com/display/smart/About+the+Service+Management+Facility 40 | 41 | ////////////////////////////////////////////////////////////////////////////// 42 | -------------------------------------------------------------------------------- /priv/templates/deb/deb.template: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 2 | %% 3 | {variables, [ 4 | {package_name, "package_name"}, 5 | {package_install_name, "package_install_name"}, 6 | {package_install_user, "package_install_user"}, 7 | {package_install_user_desc, "package_install_user_desc"}, 8 | {package_install_group, "package_install_group"}, 9 | {package_replacement_line, "{{package_replacement_line_debian}}"}, 10 | {package_conflicts_line, "{{package_conflicts_line_debian}}"}, 11 | {vendor_name, "vendor_name"}, 12 | {vendor_url, "vendor_url"}, 13 | {vendor_contact_name, "vendor_contact_name"}, 14 | {vendor_contact_email, "vendor_contact_email"}, 15 | {copyright, "copyright"}, 16 | {license_type, "license_type"}, 17 | {license_full_text, ""}, 18 | {bin_or_sbin, "bin"}, 19 | 20 | %% Platform Specific Settings 21 | {platform_bin_dir, "/usr/{{bin_or_sbin}}"}, 22 | {platform_data_dir, "/var/lib/{{package_install_name}}"}, 23 | {platform_etc_dir, "/etc/{{package_install_name}}"}, 24 | {platform_base_dir, "/usr/lib/{{package_install_name}}"}, 25 | {platform_lib_dir, "/usr/lib/{{package_install_name}}/lib"}, 26 | {platform_log_dir, "/var/log/{{package_install_name}}"} 27 | ] 28 | }. 29 | {template, "Makefile", "Makefile"}. 30 | {template, "compat", "compat"}. 31 | {template, "control", "control"}. 32 | {template, "copyright", "copyright"}. 33 | {template, "dirs", "dirs"}. 34 | {template, "install", "install"}. 35 | {template, "postinst", "postinst"}. 36 | {template, "postrm", "postrm"}. 37 | {template, "rules", "rules"}. 38 | {template, "vars.config", "vars.config"}. 39 | {template, "init.script", "{{package_name}}.{{package_install_name}}.init"}. 40 | {template, "package.service", "{{package_name}}.{{package_install_name}}.service"}. 41 | {template, "package.manpages", "{{package_name}}.manpages"}. 42 | -------------------------------------------------------------------------------- /priv/templates/deb/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # modified for node_package by dizzyd@basho.com and jared@basho.com 10 | 11 | # Uncomment this to turn on verbose mode. 12 | export DH_VERBOSE=1 13 | 14 | ROOTDIR := debian/{{package_name}} 15 | 16 | ## Clear variables that may confound our build of sub-projects; also 17 | ## note that it is necessary to use overlay_vars relative to .. as 18 | ## the generate command EXECUTES in rel/ 19 | build: 20 | unset CC CFLAGS CPPFLAGS LDFLAGS CXX CXXFLAGS \ 21 | && OVERLAY_VARS="overlay_vars=../debian/vars.config" make rel 22 | touch build 23 | 24 | clean: 25 | dh_clean 26 | rm -f build 27 | make clean 28 | 29 | ## dh_shlibdeps was added to figure out the dependencies on shared libraries 30 | ## and will populate the ${shlibs:Depends} callout in the control file 31 | install: LIBDIR := $(ROOTDIR)/usr/lib/{{package_install_name}} 32 | install: build 33 | dh_testdir 34 | dh_testroot 35 | dh_prep 36 | dh_installdirs 37 | dh_install 38 | dh_installman 39 | dh_installinit --name={{package_install_name}} --no-start 40 | dh_fixperms 41 | chmod 0755 $(ROOTDIR)/etc/{{package_install_name}} 42 | chmod -R a+rX $(ROOTDIR)/etc/{{package_install_name}} 43 | for file in lib/env.sh lib/app_epath.sh erts-*/bin/nodetool; do \ 44 | if [ -f $(LIBDIR)/$$file ]; then \ 45 | chmod 0755 $(LIBDIR)/$$file; \ 46 | fi; \ 47 | done 48 | chmod -R go+rX debian/{{package_name}}/usr/lib/{{package_install_name}}/lib/ 49 | dh_shlibdeps 50 | 51 | # We have nothing to do by default. 52 | binary-indep: install build-stamp 53 | build-stamp: 54 | 55 | # Build architecture-dependent files here. 56 | binary-arch: install 57 | dh_strip -a 58 | dh_compress -a 59 | dh_installdeb 60 | dh_gencontrol 61 | dh_builddeb 62 | 63 | binary: binary-indep binary-arch 64 | -------------------------------------------------------------------------------- /priv/templates/deb/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postrm script for {{package_name}} 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | 7 | # summary of how this script can be called: 8 | # * `remove' 9 | # * `purge' 10 | # * `upgrade' 11 | # * `failed-upgrade' 12 | # * `abort-install' 13 | # * `abort-install' 14 | # * `abort-upgrade' 15 | # * `disappear' 16 | # 17 | # for details, see http://www.debian.org/doc/debian-policy/ or 18 | # the debian-policy package 19 | 20 | set -e 21 | 22 | case "$1" in 23 | purge) 24 | rm -f /etc/default/{{package_install_name}} 25 | if [ -d /var/log/{{package_install_name}} ]; then 26 | rm -r /var/log/{{package_install_name}} 27 | fi 28 | if [ -d /var/run/{{package_install_name}} ]; then 29 | rm -r /var/run/{{package_install_name}} 30 | fi 31 | if [ -d /etc/{{package_install_name}} ]; then 32 | rm -r /etc/{{package_install_name}} 33 | fi 34 | if [ -e /etc/init.d/{{package_install_name}} ]; then 35 | rm /etc/init.d/{{package_install_name}} 36 | fi 37 | # Remove User & Group, killing any process owned by them 38 | if getent passwd {{package_install_user}} >/dev/null; then 39 | pkill -u {{package_install_user}} || true 40 | deluser --quiet --system {{package_install_user}} 41 | fi 42 | if getent group {{package_install_group}} >/dev/null; then 43 | delgroup --quiet --system --only-if-empty {{package_install_group}} || true 44 | fi 45 | ;; 46 | 47 | remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) 48 | ;; 49 | 50 | *) 51 | echo "postrm called with unknown argument \`$1\`" >&2 52 | exit 1 53 | ;; 54 | esac 55 | 56 | # dh_installdeb will replace this with shell code automatically 57 | # generated by other debhelper scripts. 58 | 59 | #DEBHELPER# 60 | 61 | exit 0 62 | -------------------------------------------------------------------------------- /priv/templates/smartos/manifest18.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /priv/templates/smartos/manifest131.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /priv/templates/smartos/manifest154.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /priv/templates/smartos/manifest16.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /priv/templates/solaris/Makefile: -------------------------------------------------------------------------------- 1 | # requires GNU make 2 | PKG = {{solaris_pkgname}} 3 | APP = {{package_name}} 4 | # possible ARCH values are i386, sparc, all 5 | KERNEL = $(shell uname -r) 6 | SOLARIS_VER ?= $(shell echo "$(KERNEL)" | sed -e 's/^5\.//') 7 | PKGFILE = $(PKG)-$(PKG_VERSION)-$(DISTRO)$(SOLARIS_VER)-$(ARCH).pkg 8 | 9 | build: buildrel depend pkginfo prototype 10 | cp $(PKGERDIR)/copyright $(PKGERDIR)/preinstall $(PKGERDIR)/*.preserve . 11 | mkdir -p pkgbuild ../packages 12 | pkgmk -o -d pkgbuild -a $(ARCH) 13 | touch ../packages/$(PKGFILE) 14 | pkgtrans -s pkgbuild ../packages/$(PKGFILE) $(PKG) 15 | rm -r pkgbuild/$(PKG) 16 | gzip ../packages/$(PKGFILE) 17 | chmod 0644 ../packages/$(PKGFILE).gz 18 | @echo 19 | @echo Wrote: ../packages/$(PKGFILE).gz 20 | @echo 21 | cd ../packages && echo "`digest -a sha256 $(PKGFILE).gz` $(PKGFILE).gz" > $(PKGFILE).gz.sha 22 | 23 | # Build the release we need to package 24 | # Make sure to copy binaries to {{bin_or_sbin}} 25 | buildrel: 26 | @# Make sure we set our EUID properly 27 | @# Ye Olde Bourne Shell on Solaris means we have to do it old school 28 | echo "Using `which erl` to build"; \ 29 | OVERLAY_VARS="overlay_vars=../solaris/vars.config" $(MAKE) rel 30 | chmod -R go+rX rel/{{package_install_name}} 31 | chmod 0755 rel/{{package_install_name}}/etc 32 | chmod -R a+rX rel/{{package_install_name}}/etc 33 | chmod 0755 rel/{{package_install_name}}/lib/env.sh 34 | chmod 0755 rel/{{package_install_name}}/lib/app_epath.sh 35 | chmod 0755 rel/{{package_install_name}}/erts-*/bin/nodetool 36 | chmod -R go+rX rel/{{package_install_name}}/lib/ 37 | chmod 0755 rel/{{package_install_name}}/bin/* \ 38 | rel/{{package_install_name}}/erts-*/bin/* 39 | if [ "{{bin_or_sbin}}" != "bin" ]; then \ 40 | mv rel/{{package_install_name}}/bin rel/{{package_install_name}}/{{bin_or_sbin}}; fi 41 | 42 | depend: 43 | cp $(PKGERDIR)/depend . 44 | 45 | pkginfo: 46 | sed -e 's/@@VERSION@@/$(PKG_VERSION)-$(RELEASE)/g' \ 47 | -e 's/@@PKG@@/$(PKG)/g' \ 48 | -e 's/@@PKGNAME@@/$(APP)/g' \ 49 | < $(PKGERDIR)/pkginfo.tmpl > pkginfo 50 | 51 | prototype: 52 | echo "i pkginfo" > prototype 53 | echo "i copyright" >> prototype 54 | echo "i depend" >> prototype 55 | echo "i preinstall" >> prototype 56 | echo "i i.preserve" >> prototype 57 | echo "i r.preserve" >> prototype 58 | echo '' >> prototype 59 | pkgproto rel/{{package_install_name}}={{package_install_name}} >> prototype 60 | sed -e "s/ $(LOGNAME) .*$$/ root bin/" \ 61 | -e "s/\([f|d]\) none {{package_install_name}}\/log\(.*\) \(.*\) root bin/\1 none {{package_install_name}}\/log\2 \3 {{package_install_user}} {{package_install_group}}/" \ 62 | -e "s/\([f|d]\) none {{package_install_name}}\/data\(.*\) \(.*\) root bin/\1 none {{package_install_name}}\/data\2 \3 {{package_install_user}} {{package_install_group}}/" \ 63 | -e 's/f none {{package_install_name}}\/etc/e preserve {{package_install_name}}\/etc/' prototype > prototype.tmp && mv prototype.tmp prototype 64 | 65 | $(PKGERDIR)/pkgclean: 66 | rm -rf copyright depend pkgbuild pkginfo prototype 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## Export all variables to sub-invocation 3 | ## 4 | export 5 | 6 | OS = $(shell uname -s) 7 | ERLANG_BIN ?= $(shell dirname $(shell which erl)) 8 | DEPS_DIR ?= deps 9 | 10 | ## 11 | ## Support RPM and Debian based linux systems 12 | ## 13 | ifeq ($(OS),Linux) 14 | ARCH = $(shell uname -m) 15 | ISRPM = $(shell cat /etc/redhat-release 2> /dev/null) 16 | ISDEB = $(shell cat /etc/debian_version 2> /dev/null) 17 | ISSLES = $(shell cat /etc/SuSE-release 2> /dev/null) 18 | ifneq ($(ISRPM),) 19 | OSNAME = RedHat 20 | PKGERDIR = rpm 21 | BUILDDIR = rpmbuild 22 | else 23 | ifneq ($(ISDEB),) 24 | OSNAME = Debian 25 | PKGERDIR = deb 26 | BUILDDIR = debuild 27 | else 28 | ifneq ($(ISSLES),) 29 | OSNAME = SLES 30 | PKGERDIR = rpm 31 | BUILDDIR = rpmbuild 32 | endif # SLES 33 | endif # deb 34 | endif # rpm 35 | endif # linux 36 | 37 | ifeq ($(OS),Darwin) # OSX 38 | OSNAME = OSX 39 | ARCH = $(shell file `which erlc` | grep -c x86_64 2> /dev/null | awk \ 40 | '{if ($$1 == "0") {print "i386"} else {print "x86_64"}}') 41 | PKGERDIR = osx 42 | BUILDDIR = osxbuild 43 | endif 44 | 45 | ifeq ($(OS),FreeBSD) 46 | OSNAME = FreeBSD 47 | ARCH = $(shell uname -m) 48 | BUILDDIR = fbsdbuild 49 | PKGNG = $(shell uname -r | awk -F. '{ print ($$1 > 9) ? "true" : "false" }') 50 | ifeq ($(PKGNG),true) # FreeBSD 10.0 or greater 51 | PKGERDIR = fbsdng 52 | else # Older FreeBSD pkg_add 53 | PKGERDIR = fbsd 54 | endif 55 | endif 56 | 57 | ifeq ($(OS),SunOS) # Solaris flavors 58 | KERNELVER = $(shell uname -v | grep -c joyent 2> /dev/null) 59 | ARCH = $(shell file `which erlc` | grep -c 64-bit 2> /dev/null | awk \ 60 | '{if ($$1 == "0") {print "i386"} else {print "x86_64"}}') 61 | 62 | ifneq ($(KERNELVER),0) # SmartOS 63 | OSNAME = SmartOS 64 | PKGERDIR = smartos 65 | BUILDDIR = smartosbuild 66 | else # Solaris / OmniOS 67 | DISTRO = $(shell head -1 /etc/release|awk \ 68 | '{if ($$1 == "OmniOS") {print $$1} else {print "Solaris"}}') 69 | OSNAME = ${DISTRO} 70 | PKGERDIR = solaris 71 | BUILDDIR = solarisbuild 72 | endif 73 | 74 | endif 75 | 76 | DATE = $(shell date +%Y-%m-%d) 77 | 78 | # Default the package build version to 1 if not already set 79 | PKG_BUILD ?= 1 80 | 81 | .PHONY: ostype varcheck 82 | 83 | ## Call platform dependent makefile 84 | ostype: varcheck setversion 85 | $(if $(PKGERDIR),,$(error "Operating system '$(OS)' not supported by node_package")) 86 | $(MAKE) -f $(PKG_ID)/$(DEPS_DIR)/node_package/priv/templates/$(PKGERDIR)/Makefile.bootstrap 87 | 88 | ## Set app version 89 | setversion: varcheck 90 | echo "{app_version, \"$(PKG_VERSION)\"}." >> $(PKG_ID)/$(DEPS_DIR)/node_package/priv/templates/$(PKGERDIR)/vars.config 91 | 92 | ## Check required settings before continuing 93 | varcheck: 94 | $(if $(PKG_VERSION),,$(error "Variable PKG_VERSION must be set and exported, see basho/node_package readme")) 95 | $(if $(PKG_ID),,$(error "Variable PKG_ID must be set and exported, see basho/node_package readme")) 96 | -------------------------------------------------------------------------------- /priv/templates/rpm/rhel.init.script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # {{package_name}} 4 | # 5 | # chkconfig: 2345 80 30 6 | # description: {{package_shortdesc}} 7 | # processname: beam 8 | # config: /etc/{{package_install_name}}/app.config 9 | # config: /etc/{{package_install_name}}/vm.args 10 | # config: /etc/sysconfig/{{package_install_name}} 11 | # 12 | 13 | # Source function library. 14 | . /etc/rc.d/init.d/functions 15 | 16 | RETVAL=0 17 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 18 | DESC="{{package_shortdesc}}" 19 | NAME={{package_install_name}} 20 | DAEMON=/usr/{{bin_or_sbin}}/$NAME 21 | lockfile=/var/lock/subsys/$NAME 22 | pidfile=/var/run/$NAME/$NAME.pid 23 | 24 | # Check for script, config and data dirs 25 | [ -x /usr/{{bin_or_sbin}}/$NAME ] || exit 0 26 | [ -d /etc/$NAME ] || exit 0 27 | [ -d /var/lib/$NAME ] || exit 0 28 | 29 | # Read configuration variable file if it is present and readable 30 | [ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME 31 | 32 | # `service` strips all environmental VARS so 33 | # if no HOME was set in /etc/sysconfig/$NAME then set one here 34 | # to the data directory for erlexec's sake 35 | if [ -z "$HOME" ]; then 36 | export HOME={{platform_data_dir}} 37 | fi 38 | 39 | status -p $pidfile -l $(basename $lockfile) $NAME >/dev/null 2>&1 40 | running=$? 41 | 42 | check_pid_status() { 43 | pid=$(ps ax | grep beam.smp | grep "\-progname $NAME " | awk '{print $1}') 44 | if [ "$pid" = "" ]; then 45 | # prog not running? 46 | return 1 47 | else 48 | # running 49 | return 0 50 | fi 51 | } 52 | 53 | start() { 54 | # Start daemons. 55 | echo -n $"Starting {{package_install_name}}: " 56 | $DAEMON start 57 | RETVAL=$? 58 | if [ $RETVAL -eq 0 ]; then 59 | touch $lockfile 60 | success 61 | else 62 | failure $"$NAME start" 63 | fi 64 | echo 65 | return $RETVAL 66 | } 67 | 68 | stop() { 69 | # Stop daemon. 70 | echo -n $"Shutting down {{package_install_name}}: " 71 | $DAEMON stop 2>/dev/null 72 | for n in $(seq 1 10); do 73 | sleep 1 74 | check_pid_status 75 | RETVAL=$? 76 | if [ $RETVAL -eq 1 ]; then 77 | break 78 | fi 79 | done 80 | if [ $RETVAL -eq 1 ]; then 81 | rm -f $lockfile $pidfile 82 | success 83 | echo && return 0 84 | else 85 | failure $"$NAME stop" 86 | echo && return 1 87 | fi 88 | } 89 | 90 | hardstop() { 91 | echo -n $"Shutting down $NAME: " 92 | su - {{package_install_user}} -c "ps -ef | grep beam.smp | grep '\-progname $NAME ' | grep -v grep | awk '{print \$2}' | xargs kill -9" 93 | for n in $(seq 1 10); do 94 | sleep 1 95 | check_pid_status 96 | RETVAL=$? 97 | if [ $RETVAL -eq 1 ]; then 98 | break 99 | fi 100 | done 101 | if [ $RETVAL -eq 1 ]; then 102 | rm -f $lockfile $pidfile 103 | success 104 | echo && return 0 105 | else 106 | failure $"$NAME hardstop" 107 | echo && return 1 108 | fi 109 | } 110 | 111 | # See how we were called. 112 | case "$1" in 113 | start) 114 | [ $running -eq 0 ] && exit 0 115 | start 116 | ;; 117 | stop) 118 | if [ $running -eq 0 ]; then 119 | stop 120 | else 121 | check_pid_status 122 | RETVAL=$? 123 | if [ $RETVAL -eq 1 ]; then 124 | rm -f $lockfile $pidfile 125 | fi 126 | exit 0 127 | fi 128 | ;; 129 | restart|force-reload) 130 | [ $running -eq 0 ] && stop 131 | start 132 | ;; 133 | hardstop) 134 | [ $running -eq 0 ] || exit 0 135 | hardstop 136 | ;; 137 | condrestart|try-restart) 138 | [ $running -eq 0 ] || exit 0 139 | restart 140 | ;; 141 | status) 142 | status -p $pidfile -l $(basename $lockfile) $NAME 143 | ;; 144 | ping) 145 | $DAEMON ping || exit $? 146 | ;; 147 | *) 148 | echo $"Usage: $0 {start|stop|restart|force-reload|hardstop|condrestart|try-restart|status|ping}" 149 | exit 1 150 | esac 151 | 152 | exit $? 153 | -------------------------------------------------------------------------------- /priv/templates/fbsdng/Makefile: -------------------------------------------------------------------------------- 1 | BUILDDIR = $(shell pwd) 2 | BUILD_STAGE_DIR = $(BUILDDIR)/{{package_name}} 3 | 4 | # Where we install things (based on vars.config) 5 | # /usr/local based dirs 6 | PMAN_DIR = $(BUILD_STAGE_DIR)/usr/local/man 7 | PBIN_DIR = $(BUILD_STAGE_DIR)/{{platform_bin_dir}} 8 | PETC_DIR = $(BUILD_STAGE_DIR)/{{platform_etc_dir}} 9 | PLIB_DIR = $(BUILD_STAGE_DIR)/{{platform_base_dir}} 10 | # /var based dirs 11 | PDATA_DIR = $(BUILD_STAGE_DIR)/{{platform_data_dir}} 12 | PLOG_DIR = $(BUILD_STAGE_DIR)/var/log/{{package_install_name}} 13 | 14 | # For scanning later, remove the leading slash 15 | # '/var/db/server' becomes 'var/db/server' 16 | PDATA_ROOT_DIR = $(shell echo "{{platform_data_dir}}" | cut -d'/' -f 2-4) 17 | 18 | TARNAME = {{package_name}}-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tar 19 | PKGNAME = {{package_name}}-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tbz 20 | 21 | 22 | # Recursive assignment of ERTS version 23 | # We will know this after building the rel 24 | ERTS_PATH = $(shell ls $(BUILDDIR)/rel/{{package_install_name}} | egrep -o "erts-.*") 25 | 26 | build: packing_list_files 27 | @echo "Building package $(PKGNAME)" 28 | 29 | cd $(BUILD_STAGE_DIR) && \ 30 | mkdir ../../packages && \ 31 | pkg create -m . -r . -o ../../packages 32 | 33 | cd ../packages && \ 34 | for tarfile in *.txz; do \ 35 | shasum -a 256 $${tarfile} > $${tarfile}.sha \ 36 | ; done 37 | 38 | packing_list_files: $(BUILD_STAGE_DIR) 39 | @mv ${BUILDDIR}/fbsdng/+MANIFEST ${BUILD_STAGE_DIR} 40 | sed -e "s/%ERTS_PATH%/${ERTS_PATH}/" < \ 41 | ${BUILDDIR}/fbsdng/rc.d > ${BUILD_STAGE_DIR}/usr/local/etc/rc.d/{{package_install_name}} 42 | chmod -w ${BUILD_STAGE_DIR}/usr/local/etc/rc.d/{{package_install_name}} 43 | chmod +x ${BUILD_STAGE_DIR}/usr/local/etc/rc.d/{{package_install_name}} 44 | @cd $(BUILD_STAGE_DIR) && \ 45 | echo "version: \"${PKG_VERSION}\"" >> +MANIFEST && \ 46 | echo "files: {" >> +MANIFEST 47 | 48 | @echo "Copying Man pages to staging directory" 49 | @cd $(BUILDDIR) && \ 50 | if [ -d doc/man/man1 ]; then \ 51 | mkdir -p $(PMAN_DIR) && \ 52 | cp -R doc/man/man1 $(PMAN_DIR); fi 53 | 54 | 55 | @echo "Packaging /usr/local files" 56 | @cd $(BUILD_STAGE_DIR) && \ 57 | find usr -type f | while read file ; do \ 58 | mode=$$(stat -f%p "$$file" | cut -c 3-) && \ 59 | sum=$$(sha256 -q $$file) && \ 60 | echo " /$$file: { sum: \"$$sum\", perm: \"$$mode\", uname: \"root\", gname: \"wheel\" }," >> +MANIFEST; done && \ 61 | sed -i .bak '$$s/,$$//' +MANIFEST && \ 62 | rm -- +MANIFEST.bak && \ 63 | echo " }" >> +MANIFEST 64 | 65 | 66 | @cd $(BUILD_STAGE_DIR) && \ 67 | echo "directories: {" >> +MANIFEST && \ 68 | echo " {{platform_base_dir}}: \"y\"," >> +MANIFEST && \ 69 | echo " {{platform_data_dir}}: {uname: \"{{package_install_user}}\", gname: \"{{package_install_group}}\", perm: \"0700\" }," >> +MANIFEST && \ 70 | echo " {{platform_etc_dir}}: \"y\"" >> +MANIFEST && \ 71 | echo " }" >> +MANIFEST 72 | 73 | # Copy the app rel directory to the staging directory to build our 74 | # package structure and move the directories into the right place 75 | # for the package, see the vars.config file for destination 76 | # directories 77 | $(BUILD_STAGE_DIR): buildrel 78 | @echo "Copying rel directory to staging directory" 79 | mkdir -p $@ 80 | mkdir -p $(PBIN_DIR) 81 | cp -R rel/{{package_install_name}}/bin/* $(PBIN_DIR) 82 | mkdir -p $(PETC_DIR) 83 | cp -R rel/{{package_install_name}}/etc/* $(PETC_DIR) 84 | mkdir -p $(PLIB_DIR) 85 | cp -R rel/{{package_install_name}}/lib $(PLIB_DIR) 86 | cp -R rel/{{package_install_name}}/erts-* $(PLIB_DIR) 87 | cp -R rel/{{package_install_name}}/releases $(PLIB_DIR) 88 | mkdir -p $(PDATA_DIR) 89 | cp -R rel/{{package_install_name}}/data/* $(PDATA_DIR) 90 | mkdir -p ${BUILD_STAGE_DIR}/usr/local/etc/rc.d 91 | 92 | 93 | # Build the release we need to package 94 | # * Ensure all binaries are executable 95 | # * copy the vars.config over for build config 96 | buildrel: 97 | OVERLAY_VARS="overlay_vars=../fbsdng/vars.config" $(MAKE) rel 98 | chmod 0755 rel/{{package_install_name}}/bin/* rel/{{package_install_name}}/erts-*/bin/* 99 | 100 | $(BUILDDIR): 101 | mkdir -p $@ 102 | 103 | $(PKGERDIR)/pkgclean: 104 | rm -rf $(BUILD_STAGE_DIR) $(BUILDDIR) 105 | -------------------------------------------------------------------------------- /priv/templates/smartos/+INSTALL: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Variable that will get replaced by the Makefile dirs_create target 4 | PACKAGE_USER_WRITABLE_DIRS="%PACKAGE_USER_WRITABLE_DIRS%" 5 | 6 | # Config files that could possibly be installed 7 | CONFIG_FILES="vm.args app.config advanced.config {{cuttlefish_conf}}" 8 | 9 | if [ "$2" = "PRE-INSTALL" ]; then 10 | if ! getent group "{{package_install_group}}" 2>/dev/null 1>&2; then 11 | groupadd {{package_install_group}} 12 | fi 13 | 14 | if ! getent passwd "{{package_install_user}}" 2>/dev/null 1>&2; then 15 | useradd -g {{package_install_group}} -d {{platform_data_dir}} -s /bin/sh {{package_install_user}} 16 | fi 17 | 18 | # Create var directories outside of +CONTENTS 19 | # Read directories from the PACKAGE_USER_WRITABLE_DIRS variable 20 | for i in $PACKAGE_USER_WRITABLE_DIRS; do 21 | if [ -d $i ]; then 22 | echo "Skipping directory creation of $i, directory already exists" 23 | else 24 | echo "Creating directory $i owned by {{package_install_user}}" 25 | mkdir -p $i 26 | chown -R {{package_install_user}}:{{package_install_group}} $i 27 | chmod 700 $i 28 | fi 29 | done 30 | 31 | # Backup config files if they already exist 32 | # These will be moved back to their proper names in the post-install 33 | for i in $CONFIG_FILES; do 34 | if [ -f {{platform_etc_dir}}/$i ]; then 35 | echo "Config file exists: backing up {{platform_etc_dir}}/$i to {{platform_etc_dir}}/$i.bak" 36 | mv {{platform_etc_dir}}/$i {{platform_etc_dir}}/$i.bak 37 | fi 38 | done 39 | fi 40 | 41 | if [ "$2" = "POST-INSTALL" ]; then 42 | 43 | # Ensure proper permissions on {{package_name}} scripts 44 | for i in {{#package_commands}}{{name}} {{/package_commands}}; do 45 | chown root:root {{platform_bin_dir}}/$i 46 | chmod 755 {{platform_bin_dir}}/$i 47 | done 48 | 49 | # Ensure proper ownership of lib directory 50 | chown -R root:root {{platform_lib_dir}} 51 | chmod -R g+r {{platform_lib_dir}} 52 | 53 | # Treat new configuration files as new if old ones already exist 54 | # if FILE and FILE.bak both exist, move FILE to FILE.new and FILE.bak to FILE 55 | # If there is just a FILE.bak and no newer file, copy the .bak file back to FILE 56 | # this supports the changing of configuration file names on upgrades 57 | for i in $CONFIG_FILES; do 58 | if [ -f {{platform_etc_dir}}/$i -a -f {{platform_etc_dir}}/$i.bak ]; then 59 | echo "Config file already exists, creating new configuration file as {{platform_etc_dir}}/$i.new" 60 | mv {{platform_etc_dir}}/$i {{platform_etc_dir}}/$i.new 61 | mv {{platform_etc_dir}}/$i.bak {{platform_etc_dir}}/$i 62 | elif [ -f {{platform_etc_dir}}/$i.bak -a ! -f {{platform_etc_dir}}/$i ]; then 63 | mv {{platform_etc_dir}}/$i.bak {{platform_etc_dir}}/$i 64 | fi 65 | done 66 | 67 | # Ensure proper ownership of etc directory 68 | # This shouldn't have to happen in the post-install, but 69 | # there is some non-deterministic stuff happening during 70 | # install on SmartOS that causes wrong ownership. 71 | chown -R root:{{package_install_group}} {{platform_etc_dir}} 72 | 73 | for i in $CONFIG_FILES; do 74 | if [ -f {{platform_etc_dir}}/$i ]; then 75 | chmod 640 {{platform_etc_dir}}/$i 76 | fi 77 | done 78 | 79 | chmod -R g+r+X {{platform_etc_dir}} 80 | 81 | 82 | # Create {{package_install_name}} project to handle custom system settings 83 | if ! projects -l {{package_install_name}} >/dev/null 2>&1; then 84 | projadd -U {{package_install_user}} -G {{package_install_group}} \ 85 | -K "process.max-file-descriptor=(priv,262140,deny)" \ 86 | -c "{{package_install_name}} default project" {{package_install_name}} 87 | fi 88 | 89 | # Ensure proper permissions of SMF files 90 | chown -R root:root /opt/local/share/smf/{{package_install_name}} 91 | chown -R root:root /opt/local/share/smf/{{package_install_name}}-epmd 92 | chmod 755 /opt/local/share/smf/{{package_install_name}}-epmd/{{package_install_name}}-epmd 93 | 94 | # Import SMF definitions 95 | svccfg import /opt/local/share/smf/{{package_install_name}}-epmd/manifest.xml 96 | svccfg import /opt/local/share/smf/{{package_install_name}}/manifest.xml 97 | fi 98 | -------------------------------------------------------------------------------- /priv/templates/rpm/suse.init.script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # {{package_name}} 4 | # 5 | ### BEGIN INIT INFO 6 | # Provides: {{package_name}} 7 | # Required-Start: $remote_fs $syslog 8 | # Required-Stop: $remote_fs $syslog 9 | # Default-Start: 2 3 4 5 10 | # Default-Stop: 0 1 6 11 | # Short-Description: {{package_shortdesc}} 12 | # Description: {{package_desc}} 13 | ### END INIT INFO 14 | 15 | # Source the LSB function library. 16 | . /lib/lsb/init-functions 17 | 18 | RETVAL=0 19 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 20 | DESC="{{package_shortdesc}}" 21 | NAME={{package_install_name}} 22 | DAEMON=/usr/{{bin_or_sbin}}/$NAME 23 | lockfile=/var/lock/subsys/$NAME 24 | pidfile=/var/run/$NAME/$NAME.pid 25 | 26 | # Check for script, config and data dirs 27 | [ -x /usr/{{bin_or_sbin}}/$NAME ] || exit 0 28 | [ -d /etc/$NAME ] || exit 0 29 | [ -d /var/lib/$NAME ] || exit 0 30 | 31 | # Read configuration variable file if it is present and readable 32 | [ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME 33 | 34 | # `service` strips all environmental VARS so 35 | # if no HOME was set in /etc/sysconfig/$NAME then set one here 36 | # to the data directory for erlexec's sake 37 | if [ -z "$HOME" ]; then 38 | export HOME={{platform_data_dir}} 39 | fi 40 | 41 | # Checks the status of a node 42 | do_status() { 43 | $DAEMON ping >/dev/null 2>&1 && return 0 || return 3 44 | } 45 | 46 | check_pid_status() { 47 | pid=$(ps ax | grep beam.smp | grep "\-progname $NAME " | awk '{print $1}') 48 | if [ "$pid" = "" ]; then 49 | # prog not running? 50 | return 1 51 | else 52 | # running 53 | return 0 54 | fi 55 | } 56 | 57 | do_start() { 58 | # Start daemons. 59 | echo -n $"Starting {{package_install_name}}: " 60 | $DAEMON start 61 | RETVAL=$? 62 | if [ $RETVAL -eq 0 ]; then 63 | touch $lockfile 64 | log_success_msg 65 | else 66 | log_failure_msg $"$NAME start" 67 | fi 68 | echo 69 | return $RETVAL 70 | } 71 | 72 | do_stop() { 73 | # Stop daemon. 74 | echo -n $"Shutting down {{package_install_name}}: " 75 | $DAEMON stop 2>/dev/null 76 | for n in $(seq 1 10); do 77 | sleep 1 78 | check_pid_status 79 | RETVAL=$? 80 | if [ $RETVAL -eq 1 ]; then 81 | break 82 | fi 83 | done 84 | if [ $RETVAL -eq 1 ]; then 85 | rm -f $lockfile $pidfile 86 | log_success_msg 87 | echo && return 0 88 | else 89 | log_failure_msg $"$NAME stop" 90 | echo && return 1 91 | fi 92 | } 93 | 94 | do_hardstop() { 95 | echo -n $"Shutting down $NAME: " 96 | su - {{package_install_user}} -c "ps -ef | grep beam.smp | grep '\-progname $NAME ' | grep -v grep | awk '{print \$2}' | xargs kill -9" 97 | for n in $(seq 1 10); do 98 | sleep 1 99 | check_pid_status 100 | RETVAL=$? 101 | if [ $RETVAL -eq 1 ]; then 102 | break 103 | fi 104 | done 105 | if [ $RETVAL -eq 1 ]; then 106 | rm -f $lockfile $pidfile 107 | log_success_msg 108 | echo && return 0 109 | else 110 | log_failure_msg $"$NAME hardstop" 111 | echo && return 1 112 | fi 113 | } 114 | 115 | # See how we were called. 116 | case "$1" in 117 | start) 118 | do_status && exit 0 119 | do_start 120 | ;; 121 | stop) 122 | if do_status; then 123 | do_stop 124 | else 125 | check_pid_status 126 | RETVAL=$? 127 | if [ $RETVAL -eq 1 ]; then 128 | rm -f $lockfile $pidfile 129 | fi 130 | exit 0 131 | fi 132 | ;; 133 | restart|reload|force-reload) 134 | do_status && do_stop 135 | do_start 136 | ;; 137 | hardstop) 138 | do_status || exit 0 139 | do_hardstop 140 | ;; 141 | condrestart|try-restart) 142 | do_status && do_stop || exit 0 143 | do_start 144 | ;; 145 | status) 146 | do_status && echo $"$NAME is running" && exit 0 || echo $"$NAME is stopped" && exit 3 147 | ;; 148 | ping) 149 | $DAEMON ping || exit $? 150 | ;; 151 | *) 152 | echo $"Usage: $0 {start|stop|restart|reload|force-reload|hardstop|condrestart|try-restart|status|ping}" 153 | exit 1 154 | esac 155 | 156 | exit $? 157 | -------------------------------------------------------------------------------- /priv/templates/deb/init.script: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: {{package_name}} 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: {{package_shortdesc}} 9 | # Description: {{package_desc}} 10 | ### END INIT INFO 11 | 12 | NAME={{package_install_name}} 13 | DAEMON=/usr/{{bin_or_sbin}}/$NAME 14 | SCRIPTNAME=/etc/init.d/$NAME 15 | RUNDIR=/var/run/$NAME 16 | 17 | # Read configuration variable file if it is present 18 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 19 | 20 | # Load the VERBOSE setting and other rcS variables 21 | . /lib/init/vars.sh 22 | . /lib/lsb/init-functions 23 | 24 | # `service` strips all environmental VARS so 25 | # if no HOME was set in /etc/default/$NAME then set one here 26 | # to the data directory for erlexec's sake 27 | if [ -z "$HOME" ]; then 28 | export HOME={{platform_data_dir}} 29 | fi 30 | 31 | # 32 | # Function that starts the daemon/service 33 | # 34 | do_start() 35 | { 36 | if [ ! -d $RUNDIR ]; then 37 | mkdir $RUNDIR 38 | chown {{package_install_user}}:{{package_install_group}} $RUNDIR 39 | fi 40 | # Return 41 | # 0 if daemon has been started 42 | # 1 if daemon was already running 43 | # 2 if daemon could not be started 44 | 45 | # Startup with the appropriate user 46 | start-stop-daemon --start \ 47 | --name {{package_install_name}} \ 48 | --user {{package_install_user}} \ 49 | --exec $DAEMON -- start \ 50 | || return 2 51 | } 52 | 53 | # 54 | # Function that stops the daemon/service 55 | # 56 | do_stop() 57 | { 58 | # Identify the erts directory 59 | ERTS_PATH=`$DAEMON ertspath` 60 | 61 | # Attempt a clean shutdown. 62 | $DAEMON stop 63 | 64 | # Return 65 | # 0 if daemon has been stopped 66 | # 1 if daemon was already stopped 67 | # 2 if daemon could not be stopped 68 | # other if a failure occurred 69 | # Make sure it's down by using a more direct approach 70 | start-stop-daemon --stop \ 71 | --quiet \ 72 | --retry=TERM/30/KILL/5 \ 73 | --user {{package_install_user}} \ 74 | --exec $ERTS_PATH/run_erl 75 | return $? 76 | } 77 | 78 | # 79 | # Function that graceful reload the daemon/service 80 | # 81 | do_reload() { 82 | # Restart the VM without exiting the process 83 | $DAEMON restart && return $? || return 2 84 | } 85 | 86 | # Checks the status of a node 87 | do_status() { 88 | $DAEMON ping && echo $"$NAME is running" && return 0 89 | echo $"$NAME is stopped" && return 2 90 | } 91 | 92 | case "$1" in 93 | start) 94 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $NAME" 95 | $DAEMON ping >/dev/null 2>&1 && echo $"$NAME is already running" && exit 0 96 | do_start 97 | case "$?" in 98 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 99 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 100 | exit 1 101 | ;; 102 | esac 103 | ;; 104 | stop) 105 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $NAME" 106 | do_stop 107 | case "$?" in 108 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 109 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 110 | exit 1 111 | ;; 112 | esac 113 | ;; 114 | ping) 115 | # See if the VM is alive 116 | $DAEMON ping || exit $? 117 | ;; 118 | reload|force-reload) 119 | log_daemon_msg "Reloading $NAME" 120 | do_reload 121 | ES=$? 122 | log_end_msg $ES 123 | exit $ES 124 | ;; 125 | restart) 126 | log_daemon_msg "Restarting $NAME" 127 | do_stop 128 | case "$?" in 129 | 0|1) 130 | do_start 131 | case "$?" in 132 | 0) log_end_msg 0 ;; 133 | 1) log_end_msg 1 && exit 1 ;; # Old process is still running 134 | *) log_end_msg 1 && exit 1 ;; # Failed to start 135 | esac 136 | ;; 137 | *) 138 | # Failed to stop 139 | log_end_msg 1 && exit 1 140 | ;; 141 | esac 142 | ;; 143 | status) 144 | do_status && exit 0 || exit $? 145 | ;; 146 | *) 147 | echo "Usage: $SCRIPTNAME {start|stop|ping|restart|force-reload|status}" >&2 148 | exit 3 149 | ;; 150 | esac 151 | 152 | : 153 | -------------------------------------------------------------------------------- /RELEASE-NOTES.md: -------------------------------------------------------------------------------- 1 | # node_package 3.0.0 2 | ## Security Improvements 3 | ### Introduction 4 | ### Security Advisory dated March 1, 2016 5 | It was [recently reported](http://docs.basho.com/riak/latest/community/product-advisories/codeinjectioninitfiles/) 6 | that, if a user could gain access to the `riak` user (or, in node_package 7 | parlance, the `package_install_user`), that user would then 8 | have write access to init scripts that are generally run as `root`, exposing an 9 | escalation of privileges attack where said user could then get the `root` user 10 | to execute a script that could allow the original user to become `root` on the 11 | system. 12 | 13 | ### Additional Security Review 14 | 15 | After the security advisory was initially released, a more thorough review of 16 | all of the `node_package`-generated packages was conducted. This review found 17 | some additional cases of files or directories owned by the 18 | `package_install_user` or `package_install_group` that could also potentially 19 | allow a someone with access to run in the context of that user account to 20 | overwrite files that may later be executed by `root`. This release of 21 | `node_package` has significantly tightened the ownership and permissions of 22 | files installed, in most cases following the target systems' conventions 23 | (`root:root`, `root:bin`, `root:wheel`) for all files that are executable or 24 | could be executed, including library files that the packaged application may 25 | read. 26 | 27 | The [node_package](https://github.com/basho/node_package) library is used to 28 | build deployable packages for Erlang applications that target many operating 29 | systems. Node_package supports building installation packages for: 30 | 31 | - Redhat / Fedora and variants 32 | - Debian / Ubuntu and variants 33 | - FreeBSD 34 | - OSX 35 | - SmartOS 36 | - Solaris 37 | 38 | ### TL;DR - What should I do? 39 | 40 | #### You're a user updating a system (like Riak) installed by node_package: 41 | 42 | When upgrading from an older version of a system like Riak that uses 43 | node_package for installation, you may need to verify the following (note, the 44 | examples will be for a Centos 7-based Linux installation of Riak, but should 45 | illustrate the required checks for most OSes and similar packages): 46 | 47 | - Validate permissions on existing directories and make them owned by root:root 48 | (or the appropriate user/group for your operating system) and not writable by 49 | the package_install_user/group. For this example, we will list the specific 50 | directories for the Centos 7 install, and then their `node_package` template 51 | names in parenthesis afterward. Directories and files include: 52 | - /usr/lib64/riak (`platform_lib_dir`) 53 | - /etc/riak (`platform_etc_dir`) 54 | - /usr/bin (`platform_bin_dir`), specifically 55 | - riak 56 | - riak-admin 57 | - riak-debug 58 | - riak-repl 59 | - search-cmd 60 | - /etc/init.d/riak (`platform_etc_dir`/init.d/`package_install_name`) 61 | 62 | - Validate the home directory of the `platform_install_user` user is set to the 63 | `platform_data_dir`, in the case of Riak on Centos 7 this should be the `riak` 64 | user and the `/var/lib/riak` directory, and not `/usr/lib64/riak`. If 65 | necessary, change the home directory of the `riak` (`package_install_user`) 66 | user to point to `/var/lib/riak` (`platform_data_dir`). 67 | 68 | #### You're an application maintainer that uses node_package to produce packages for your application: 69 | 70 | Please upgrade to version 3.0.0 of node_package and test your packaging/install 71 | process carefully. If you were depending on the writability of directories 72 | outside of the `platform_data_dir` you may need to adjust your application to 73 | store writable files in `platform_data_dir` rather than some other directory, 74 | like `package_root_dir`. 75 | 76 | Additionally, the home directory of the `package_install_user` has been 77 | normalized across platforms to be the `platform_data_dir`. If you depended on 78 | the home directory to be set to `platform_base_dir` make appropriate changes to 79 | ensure your application can handle the change in home directory. 80 | 81 | ### Changes in version 3.0.0 82 | #### File Ownership/Permissions 83 | In all cases, the only files installed as owned by 84 | `package_install_user:package_install_group` are now files to which the 85 | packaged application needs to write. These files/directories include data 86 | directories and log directories. All other files/directories installed by 87 | `node_package`-packaged systems should now be owned by the appropriate `root` 88 | account and group for the target operating system. 89 | 90 | #### Home directory of `package_install_user` 91 | In some cases, the home directory of the created `package_install_user` was set 92 | to a directory that is now not writable by that user (often the 93 | `package_base_dir`). In all cases, we have standardized on using the 94 | `platform_data_dir` for the home directory of the `package_install_user`. This 95 | may cause issues on upgrades, as the user in that case won't be updated (since 96 | it already exists) but post-install scripts may now ensure that the directory 97 | set as the `package_install_user`'s home directory is owned by the appropriate 98 | root user/group. This will manifest itself as start/stop scripts, ping, etc. 99 | failing to be able to write to a file called `.erlang.cookie` in that 100 | directory. In order to resolve this issue, please use your operating system's 101 | `usermod` or similar utility to change the home directory of the user to match 102 | the `platform_data_dir` of the installed application. 103 | 104 | ### Details of the changes: 105 | To view the individual changes to install package instructions, please see 106 | [this PR](https://github.com/basho/node_package/pull/196). As always, if you 107 | have seen or find any additional issues that may raise security concerns, 108 | please email [security@basho.com](mailto:security@basho.com). 109 | -------------------------------------------------------------------------------- /priv/base/app_epath.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## --------------------------------------------------------------------- 4 | ## 5 | ## app_epath.sh: Parse Erlang app.config with POSIX tools for automation 6 | ## 7 | ## Copyright (c) 2013 Basho Technologies, Inc. All Rights Reserved. 8 | ## 9 | ## This file is provided to you under the Apache License, 10 | ## Version 2.0 (the "License"); you may not use this file 11 | ## except in compliance with the License. You may obtain 12 | ## a copy of the License at 13 | ## 14 | ## http://www.apache.org/licenses/LICENSE-2.0 15 | ## 16 | ## Unless required by applicable law or agreed to in writing, 17 | ## software distributed under the License is distributed on an 18 | ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 | ## KIND, either express or implied. See the License for the 20 | ## specific language governing permissions and limitations 21 | ## under the License. 22 | ## 23 | ## --------------------------------------------------------------------- 24 | 25 | ## Example usage: 26 | # 27 | # #!/bin/sh 28 | # 29 | # # Load the functions 30 | # . path/to/app_epath.sh 31 | # 32 | # # Build the path info 33 | # epaths=`make_app_epaths path/to/app.config` 34 | # 35 | # # View all of the settings. Quotes are important. 36 | # echo "$epaths" 37 | # 38 | # # Grep around in the paths for various items. 39 | # echo "$epaths" | grep 'riak_core ring_creation_size' 40 | # echo "$epaths" | grep "lager handlers lager_file_backend" | grep info 41 | # 42 | # # Use the epath function to get directly at settings 43 | # epath 'riak_core ring_creation_size' "$epaths" 44 | # epath 'riak_core platform_bin_dir' "$epaths" 45 | # epath 'riak_kv storage_backend' "$epaths" 46 | # 47 | # # Use epath to view all of the riak_core settings 48 | # epath riak_core 49 | # 50 | ## End example 51 | 52 | ## Here is a command you can put in your path for general cli use. 53 | # 54 | # #!/bin/sh 55 | # 56 | # # $1 quoted eterm path for search: 'riak_core ring_creation_size' 57 | # # $2 path/to/app.config 58 | # 59 | # . path/to/app_epath.sh 60 | # 61 | # epaths=`make_app_epaths "$2"` 62 | # epath "$1" "$epaths" 63 | # 64 | ## End epath command 65 | 66 | # make_app_epaths takes a path to an app.config file as its argument and 67 | # and returns (prints) a flattened text structure of configuration settings. 68 | 69 | make_app_epaths () { 70 | # Remove all lines containing comments 71 | # Remove all blank lines 72 | # Remove the first [ 73 | # Remove the last ]. 74 | # Remove all blank lines again (just in case) 75 | appconfig=`cat $1 \ 76 | | sed '/^[ \t]*%/d' \ 77 | | sed '/^[ \t]*$/d' \ 78 | | sed -e '/\[/{s///;:a' -e '$!N;$!ba' -e '}' \ 79 | | sed '$ s/\]\.//g' \ 80 | | sed '/^[ \t]*$/d'` 81 | 82 | STACK= 83 | INQUOTE=0 84 | # The awk puts each char, spaces included, on their own line for parsing. 85 | echo "$appconfig" | awk '{gsub(//,"\n");print}' | while read i; do 86 | case "x${i}x" in 87 | "x\"x") 88 | # Flip the INQUOTE state and echo the quote 89 | if [ 1 -eq $INQUOTE ]; then 90 | INQUOTE=0 91 | else 92 | INQUOTE=1 93 | fi 94 | STACK="${STACK}${i}" 95 | ;; 96 | "xx") 97 | if [ 1 -eq $INQUOTE ]; then 98 | # If in quotes, keep this space 99 | STACK="${STACK} " 100 | fi 101 | ;; 102 | "x,x") 103 | if [ 1 -eq $INQUOTE ]; then 104 | # If in quotes, keep this comma 105 | STACK="${STACK}," 106 | else 107 | # Commas outside quotes means a new item is next 108 | STACK="${STACK} " 109 | fi 110 | ;; 111 | "x{x") 112 | if [ 1 -eq $INQUOTE ]; then 113 | # If in quotes, keep this bracket 114 | STACK="${STACK}{" 115 | else 116 | # Add brace to the stack; will pop off from here on next } 117 | STACK="${STACK} __EBRACE__ " 118 | fi 119 | ;; 120 | "x}x") 121 | if [ 1 -eq $INQUOTE ]; then 122 | # If in quotes, keep this bracket 123 | STACK="${STACK}}" 124 | else 125 | # We're only interested in printing leaves, not 126 | # intermediates like 'riak_core http', which contain lists. 127 | # See if the current stack ends with ] (end of list). 128 | echo $STACK | grep -E "__EBRACKET__$" >/dev/null 2>&1 129 | if [ 1 -eq $? ]; then 130 | # If not, print the stack without all of the mess. 131 | echo "$STACK" | \ 132 | sed 's/ *__EBRACE__//g;s/ *__EBRACKET__//g;s/^ *//' 133 | fi 134 | # Pop off everything from the last brace on. 135 | STACK=`echo "$STACK" | sed 's/\(.*\) __EBRACE__.*/\1/g'` 136 | fi 137 | ;; 138 | "x[x") 139 | if [ 1 -eq $INQUOTE ]; then 140 | # If in quotes, keep this bracket 141 | STACK="${STACK}[" 142 | else 143 | # Add a placeholder to aid in determining whether or not to 144 | # print. That is, we don't want to print 'riak_core http'. 145 | STACK="${STACK} __EBRACKET__ " 146 | fi 147 | ;; 148 | "x]x") 149 | if [ 1 -eq $INQUOTE ]; then 150 | # If in quotes, keep this bracket 151 | STACK="${STACK}]" 152 | fi 153 | # Don't actually do anything with ], as the starting brackets 154 | # are instead removed with }. 155 | ;; 156 | *) 157 | # Anything else is just pushed. 158 | STACK="${STACK}${i}" 159 | ;; 160 | esac 161 | done 162 | } 163 | 164 | epath () { 165 | # arg1 - a pattern to search for 166 | # arg2 - output of make_app_epaths, passed in quoted 167 | # output - search of arg2 for arg1, trimming arg1 from the beginning 168 | # Note: there may be multiple lines of output. 169 | pat=$1 170 | shift 171 | echo "$*" | grep "$pat " | sed "s/^${pat} *//" 172 | } 173 | 174 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * node_package 2 | ** Release 3.0.0 - Release notes 3 | 4 | Please see [[RELEASE-NOTES.md][RELEASE-NOTES.md]] for important changes in the 3.0.0 release of `node_package` 5 | 6 | ** Overview 7 | 8 | `node_package` is a set of RPM/Debian/Solaris templates and scripts, suitable for 9 | packaging embedded Erlang nodes. 10 | 11 | *** Supported Operating Systems 12 | 13 | Currently supported operating systems / distros 14 | - Redhat / Fedora and variants 15 | - Debian / Ubuntu and variants 16 | - FreeBSD 17 | - OSX 18 | - SmartOS 19 | - Solaris 20 | 21 | ** Use 22 | 23 | *** Makefile Variables 24 | 25 | **** Required Variables 26 | 27 | The following variables need to be exported for node_package to work correctly. 28 | 29 | - =PKG_VERSION= - The version of your application (ex: 1.2.0) 30 | - =PKG_ID= - The full name of the package, typically 31 | ={{package_name}}-PKG_VERSION= (ex: riak-1.2.0) 32 | 33 | **** Defaulted Variables 34 | 35 | The following variables will have a default, but can be overriden in your 36 | application. 37 | 38 | - =PKG_BUILD= - (Default: 1) Sets the "release" version of the build 39 | (ex: app-5.4-1 <- the '1') 40 | - =ERLANG_BIN= - (Default: `which erl`) Sets the path of the current erlang 41 | binary 42 | - =DEPS_DIR= - (Default: deps) Sets the deps directory of the project, most 43 | projects uses 'deps'. Change this if something different is used. 44 | 45 | ** Package and Script Variables 46 | 47 | *** Package Variables 48 | The following variables describe a package and should be put in the 49 | =pkg.vars.config= file. 50 | 51 | **** Required Variables 52 | - =package_name= - The name of the package 53 | - =package_install_name= - The name used in the install directories 54 | eg: /usr/lib/{{package_install_name}}. Usually the same as package_name. 55 | - =package_shortdesc= - A short (< one line) description of the package 56 | - =package_install_user= - The user to create and run the daemon from 57 | - =package_install_group= - The group to create and add the above user to 58 | - =copyright= - The copyright holder (ex: 2011 Basho Technologies, Inc) 59 | - =license_type= - The short desciption of what license the app is under 60 | - =vendor_name= - The name of the person or company who is releasing this 61 | package 62 | - =vendor_url= - The website of the person or company who is releasing this 63 | package 64 | - =vendor_contact_name= - The name of the maintainer (ex: Basho Packaging) 65 | - =vendor_contact_email= - The email address of the maintainer 66 | (ex: packages@basho.com) 67 | - =solaris_pkgname= - Package names for Solaris follow a naming convention of 68 | MAINTapp (ex: BASHOriak) 69 | - =runner_wait_process= - The erlang process to wait for to determine if your 70 | app started or not. (ex: `riak_core_node_watcher` in riak's case) 71 | 72 | 73 | **** Optional Variables 74 | - =license_full_text= - If the full text of a license needs to be included, use 75 | this variable 76 | - =deb_depends= - Dependencies you require on deb sytems. This should be a 77 | comma separated list. 78 | - =package_desc= - A long description of the package 79 | - =solaris_depends= - (not supported yet) Dependencies specific to the solaris 80 | package 81 | - =package_install_user_desc= - The description of the user created for the app 82 | - =bin_or_sbin= - Tells where to put the binaries, in */bin or */sbin 83 | (default: bin) 84 | - =freebsd_package_category= - The subsection the package is filed under in FreeBSD 85 | (ex: in this line, "ORIGIN: db/riak" 'db' would be the package_category) 86 | This defaults to 'db' if not specified for lack of a better default. 87 | - =debuild_extra_options= - This is added to pass extra flags to debuild 88 | - =cuttlefish_conf= - If your app uses cuttlefish for configuration, this 89 | is the filename you are using for configuration (ex: "riak.conf") 90 | 91 | *** Script Variables 92 | The following variables are used in the =env.sh= and =runner= scripts which can 93 | be used by reltool for =rel= and =devrel= builds. They should be set in 94 | your application's =vars.config=. 95 | 96 | **** Optional Variables 97 | - =runner_ulimit_warn= - The runner script will warn if `ulimit -n` is less than 98 | this value. This defaults to 4096 in all packages. 99 | - =package_patch_dir= - Directory to include in erlang's load path to allow for 100 | patches to be hotloaded. By default this will be in the =platform_lib_dir= 101 | (ex: "basho-patches") 102 | - =runner_user= - The username to run the application as 103 | - =runner_wait_process= - Registered process to wait for to consider start a 104 | success 105 | - =cuttlefish_conf= - This is a rare case of a repeated variable since it is 106 | used in packaging and the main runner scripts, you should have this set 107 | in both the vars.config and pkg.vars.config (sadly this was the cleanest 108 | solution). 109 | 110 | *** Templating Order 111 | There are several templating steps done in node_package: 112 | 113 | - pkg.vars.config from the application is used to template 114 | .template from 115 | deps/node_package/priv/templates//.template 116 | - For all the files in .template, those files are copied and 117 | templated according to the values from .template and 118 | pkg.vars.config, with pkg.vars.config trumping values from 119 | .template. This includes vars.config, which will be used in 120 | the next templating step. 121 | - Finally, as part of the rebar generate phase, the values from the 122 | package's rel/vars.config and node_package's vars.config are used to 123 | template any overlay files marked as a template in 124 | rel/reltool.config. Values from node_package's vars.config trump the 125 | ones from rel/vars.config. 126 | 127 | So, if you want to have a variable persist all the way through to the 128 | final reltool step, the variable needs to be set in pkg.vars.config 129 | (or defaulted in .template) AND be present in the vars.config, 130 | so it can be applied to the reltool templates. 131 | 132 | *** Example App 133 | 134 | The easiest app that uses =node_package= is [[https://github.com/basho/stanchion][stanchion]] a small application that Basho uses along side Riak CS. 135 | 136 | In particular, see: 137 | 138 | - [[https://github.com/basho/stanchion/blob/develop/pkg.vars.config][pkg.vars.config]] 139 | - [[https://github.com/basho/stanchion/blob/develop/Makefile#L73][makefile]] 140 | - [[https://github.com/basho/stanchion/blob/develop/rel/reltool.config#L46][reltool.config]] 141 | 142 | It also has custom settings in its [[https://github.com/basho/stanchion/blob/develop/rel/vars.config#L31][vars.config]] for adjusting settings in the =bin/stanchion= that comes from node_package's =runner= script. 143 | -------------------------------------------------------------------------------- /priv/templates/fbsd/Makefile: -------------------------------------------------------------------------------- 1 | BUILDDIR = $(shell pwd) 2 | BUILD_STAGE_DIR = $(BUILDDIR)/{{package_name}} 3 | 4 | # Where we install things (based on vars.config) 5 | # /usr/local based dirs 6 | PMAN_DIR = $(BUILD_STAGE_DIR)/man 7 | PBIN_DIR = $(BUILD_STAGE_DIR)/{{bin_or_sbin}} 8 | PETC_DIR = $(BUILD_STAGE_DIR)/etc/{{package_install_name}} 9 | PLIB_DIR = $(BUILD_STAGE_DIR)/lib/{{package_install_name}} 10 | # /var based dirs 11 | PDATA_DIR = $(BUILD_STAGE_DIR)/{{platform_data_dir}} 12 | PLOG_DIR = $(BUILD_STAGE_DIR)/log/{{package_install_name}} 13 | 14 | # For scanning later, remove the leading slash 15 | # '/var/db/server' becomes 'var/db/server' 16 | PDATA_ROOT_DIR = $(shell echo "{{platform_data_dir}}" | cut -d'/' -f 2-4) 17 | 18 | TARNAME = {{package_name}}-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tar 19 | PKGNAME = {{package_name}}-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tbz 20 | 21 | build: packing_list_files templates 22 | @echo "Building package $(PKGNAME)" 23 | mkdir -p packages 24 | cd $(BUILD_STAGE_DIR) && \ 25 | tar -cf $(TARNAME) +CONTENTS +COMMENT +DESC +MTREE_DIRS +DEINSTALL +DISPLAY 26 | cd $(BUILD_STAGE_DIR) && \ 27 | find man -type f | tar -rf $(TARNAME) -T - && \ 28 | find {{bin_or_sbin}} -type f | tar -rf $(TARNAME) -T - && \ 29 | find lib -type f | tar -rf $(TARNAME) -T - && \ 30 | find etc -type f | tar -rf $(TARNAME) -T - && \ 31 | find var -type f | tar -rf $(TARNAME) -T - && \ 32 | find log -type f | tar -rf $(TARNAME) -T - 33 | 34 | cd $(BUILD_STAGE_DIR) && \ 35 | mkdir ../../packages && \ 36 | gzip $(TARNAME) && \ 37 | mv $(TARNAME).gz ../../packages/$(PKGNAME) 38 | 39 | cd ../packages && \ 40 | for tarfile in *.tbz; do \ 41 | shasum -a 256 $${tarfile} > $${tarfile}.sha \ 42 | ; done 43 | 44 | # Where most of the magic (horror?) happens 45 | # Create a packing list according to pkg_create(1) 46 | # Write initial settings to a local file then copy 47 | # to the destination folder where we use 'find' 48 | # to populate the files and directories 49 | # Regarding @owner and @group callouts 50 | # They work on files, but not on directories. 51 | # Also, the last callout should be blank to revert 52 | # back to the default so the /var/db/pkg directory 53 | # doesn't get set to something bad (which is a 54 | # horrible bug in pkg_add). 55 | packing_list_files: $(BUILD_STAGE_DIR) 56 | @echo "Adding to packaging list {{package_name}}-$(PKG_VERSION)" 57 | echo "@name {{package_name}}-$(PKG_VERSION)" >> plist 58 | echo "@conflicts {{package_name}}-*" >> plist 59 | echo "@exec if ! pw groupshow {{package_install_group}} 2>/dev/null; then pw groupadd {{package_install_group}}; fi" >> plist 60 | echo "@exec if ! pw usershow {{package_install_user}} 2>/dev/null; then pw useradd {{package_install_user}} -g {{package_install_group}} -h - -d {{platform_data_dir}} -s /bin/sh -c \"{{package_install_user_desc}}\"; fi" >> plist 61 | echo "@comment ORIGIN:{{freebsd_package_category}}/{{package_install_name}}" >> plist 62 | 63 | @echo "Copying Man pages to staging directory" 64 | if [ -d doc/man/man1 ]; then \ 65 | mkdir -p $(PMAN_DIR) && \ 66 | cp -R doc/man/man1 $(PMAN_DIR) && \ 67 | echo "@cwd /usr/local" >> plist && \ 68 | echo "@owner root" >> plist && \ 69 | echo "@group wheel" >> plist && \ 70 | {{#package_commands}}if [ -f doc/man/man1/{{name}}.1.gz ]; then \ 71 | echo "man/man1/{{name}}.1.gz" >> plist \ 72 | ; fi && \ 73 | {{/package_commands}} echo -n; fi 74 | 75 | @echo "Scanning data and log directories for empty directories to add" 76 | $(eval PACKAGE_USER_WRITABLE_DIRS = {{platform_log_dir}}) 77 | $(eval PACKAGE_USER_WRITABLE_DIRS += $(shell cd $(BUILD_STAGE_DIR) && find $(PDATA_ROOT_DIR) -type d -exec printf "/%s " {} \;)) 78 | for i in $(PACKAGE_USER_WRITABLE_DIRS); \ 79 | do \ 80 | echo "@exec mkdir -p $$i" >> plist; \ 81 | echo "@exec chown -R {{package_install_user}}:{{package_install_group}} $$i" >> plist; \ 82 | echo "@exec chmod 700 $$i" >> plist; \ 83 | done 84 | 85 | @echo "Copying staging package listing to +CONTENTS" 86 | mv plist $(BUILD_STAGE_DIR)/+CONTENTS 87 | 88 | @echo "Packaging /usr/local files" 89 | cd $(BUILD_STAGE_DIR) && \ 90 | echo "@cwd /usr/local" >> +CONTENTS && \ 91 | echo "@owner root" >> +CONTENTS && \ 92 | echo "@group wheel" >> +CONTENTS && \ 93 | echo "@mode 0755" >> +CONTENT 94 | cd $(BUILD_STAGE_DIR) && \ 95 | find lib -type f >> +CONTENTS && \ 96 | find lib -d -type d -mindepth 1 -exec echo "@dirrm {}" \; >> +CONTENTS && \ 97 | echo "@exec chown -R root:wheel {{platform_base_dir}}" >> +CONTENTS && \ 98 | find {{bin_or_sbin}} -type f >> +CONTENTS 99 | cd $(BUILD_STAGE_DIR) && \ 100 | echo "@mode 0644" >> +CONTENTS && \ 101 | find etc -type f >> +CONTENTS && \ 102 | find etc -d -type d -mindepth 1 -exec echo "@dirrm {}" \; >> +CONTENTS 103 | @echo "Packaging /var files" 104 | cd $(BUILD_STAGE_DIR) && \ 105 | echo "@cwd /var" >> +CONTENTS 106 | cd $(BUILD_STAGE_DIR) && \ 107 | echo "@owner {{package_install_user}}" >> +CONTENTS && \ 108 | echo "@group {{package_install_group}}" >> +CONTENTS 109 | cd $(BUILD_STAGE_DIR) && \ 110 | find var/db -type f >> +CONTENTS 111 | cd $(BUILD_STAGE_DIR) && \ 112 | find log -type f >> +CONTENTS 113 | 114 | cd $(BUILD_STAGE_DIR) && \ 115 | echo "@owner" >> +CONTENTS && \ 116 | echo "@group" >> +CONTENTS && \ 117 | echo "@mode" >> +CONTENTS && \ 118 | echo "@display +DISPLAY" >> +CONTENTS 119 | 120 | 121 | templates: $(BUILD_STAGE_DIR) 122 | @echo "Copying metadata files to package" 123 | cp $(PKGERDIR)/+DESC $(PKGERDIR)/+COMMENT $(PKGERDIR)/+DEINSTALL \ 124 | $(PKGERDIR)/+MTREE_DIRS $(PKGERDIR)/+DISPLAY \ 125 | $(BUILD_STAGE_DIR) 126 | 127 | 128 | # Copy the app rel directory to the staging directory to build our 129 | # package structure and move the directories into the right place 130 | # for the package, see the vars.config file for destination 131 | # directories 132 | $(BUILD_STAGE_DIR): buildrel 133 | @echo "Copying rel directory to staging directory" 134 | mkdir -p $@ 135 | mkdir -p $(PBIN_DIR) 136 | cp -R rel/{{package_install_name}}/bin/* $(PBIN_DIR) 137 | mkdir -p $(PETC_DIR) 138 | cp -R rel/{{package_install_name}}/etc/* $(PETC_DIR) 139 | mkdir -p $(PLIB_DIR) 140 | cp -R rel/{{package_install_name}}/lib $(PLIB_DIR) 141 | cp -R rel/{{package_install_name}}/erts-* $(PLIB_DIR) 142 | cp -R rel/{{package_install_name}}/releases $(PLIB_DIR) 143 | mkdir -p $(PDATA_DIR) 144 | cp -R rel/{{package_install_name}}/data/* $(PDATA_DIR) 145 | mkdir -p $(PLOG_DIR) 146 | 147 | 148 | # Build the release we need to package 149 | # * Ensure all binaries are executable 150 | # * copy the vars.config over for build config 151 | buildrel: 152 | OVERLAY_VARS="overlay_vars=../fbsd/vars.config" $(MAKE) rel 153 | chmod 0755 rel/{{package_install_name}}/bin/* rel/{{package_install_name}}/erts-*/bin/* 154 | 155 | $(BUILDDIR): 156 | mkdir -p $@ 157 | 158 | $(PKGERDIR)/pkgclean: 159 | rm -rf $(BUILD_STAGE_DIR) $(BUILDDIR) 160 | -------------------------------------------------------------------------------- /priv/templates/rpm/specfile: -------------------------------------------------------------------------------- 1 | ## ------------------------------------------------------------------- 2 | ## 3 | ## Copyright (c) 2014 Basho Technologies, Inc. 4 | ## 5 | ## This file is provided to you under the Apache License, 6 | ## Version 2.0 (the "License"); you may not use this file 7 | ## except in compliance with the License. You may obtain 8 | ## a copy of the License at 9 | ## 10 | ## http://www.apache.org/licenses/LICENSE-2.0 11 | ## 12 | ## Unless required by applicable law or agreed to in writing, 13 | ## software distributed under the License is distributed on an 14 | ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | ## KIND, either express or implied. See the License for the 16 | ## specific language governing permissions and limitations 17 | ## under the License. 18 | ## 19 | ## ------------------------------------------------------------------- 20 | 21 | Name: {{package_name}} 22 | Version: %{_version} 23 | Release: %{_release}%{?dist} 24 | License: {{license_type}} 25 | Group: Development/Libraries 26 | Source: %{_tarname} 27 | URL: {{vendor_url}} 28 | Vendor: {{vendor_name}} 29 | Packager: {{vendor_contact_name}} <{{vendor_contact_email}}> 30 | BuildRoot: %{_tmppath}/%{name}-%{_revision}-%{release}-root 31 | Summary: {{package_shortdesc}} 32 | Obsoletes: {{package_name}} 33 | 34 | %description 35 | {{package_desc}} 36 | 37 | %define init_script %{_sysconfdir}/init.d/{{package_install_name}} 38 | %define debug_package %{nil} 39 | %define __prelink_undo_cmd /bin/cat prelink library 40 | 41 | %define platform_bin_dir %{_{{bin_or_sbin}}dir} 42 | %define platform_data_dir %{_localstatedir}/lib/{{package_install_name}} 43 | %define platform_etc_dir %{_sysconfdir}/{{package_install_name}} 44 | %define platform_base_dir %{_libdir}/{{package_install_name}} 45 | %define platform_lib_dir %{platform_base_dir}/lib 46 | %define platform_log_dir %{_localstatedir}/log/{{package_install_name}} 47 | 48 | 49 | %prep 50 | %setup -q -n %{_tarname_base} 51 | 52 | # Setup vars.config like other platforms, but do it inside of spec file 53 | cat > rpm.vars.config <> additional_files_list \ 107 | ; fi && \ 108 | {{/package_commands}}echo -n; fi 109 | 110 | cp -R %{relpath}/etc/* %{buildroot_etc} 111 | 112 | mkdir -p %{buildroot}%{_localstatedir}/lib/{{package_install_name}} 113 | cp -R %{relpath}/data/* \ 114 | %{buildroot}%{_localstatedir}/lib/{{package_install_name}} 115 | 116 | mkdir -p %{buildroot}%{_sysconfdir}/init.d 117 | install -m755 %{_topdir}/init.script %{buildroot}%{_sysconfdir}/init.d/{{package_install_name}} 118 | 119 | # Needed to work around check-rpaths which seems to be hardcoded into recent 120 | # RPM releases 121 | export QA_RPATHS=3 122 | 123 | 124 | %pre 125 | # Pre-install script 126 | if ! getent group {{package_install_group}} >/dev/null 2>&1; then 127 | groupadd -r {{package_install_group}} 128 | fi 129 | 130 | if getent passwd {{package_install_user}} >/dev/null 2>&1; then 131 | usermod -d %{_localstatedir}/lib/{{package_install_name}} {{package_install_user}} || true 132 | else 133 | useradd -r -g {{package_install_group}} \ 134 | --home %{_localstatedir}/lib/{{package_install_name}} \ 135 | --comment "{{package_install_user_desc}}" \ 136 | --shell /bin/bash \ 137 | {{package_install_user}} 138 | fi 139 | 140 | 141 | %post 142 | # Post Installation Script 143 | 144 | # For distros with SELinux (RHEL/Fedora) 145 | if [ `which selinuxenabled > /dev/null 2>&1` ] ; then 146 | # Fixup perms for SELinux (if it is enabled) 147 | selinuxenabled && find %{_localstatedir}/lib/{{package_install_name}} -name "*.so" -exec chcon -t textrel_shlib_t {} \; 148 | fi 149 | 150 | # Make sure shell library file is readable 151 | chmod 0755 %{_libdir}/{{package_install_name}}/lib/env.sh 152 | 153 | # Add application to chkconfig, but default to "off" 154 | /sbin/chkconfig --add {{package_install_name}} 155 | /sbin/chkconfig {{package_install_name}} off 156 | 157 | 158 | %preun 159 | # Pre-uninstall script 160 | 161 | # Only on uninstall, not upgrades 162 | if [ "$1" = 0 ] ; then 163 | /sbin/service {{package_install_name}} stop > /dev/null 2>&1 164 | /sbin/chkconfig --del {{package_install_name}} 165 | fi 166 | exit 0 167 | 168 | 169 | # Man pages are optional and might be missing, read from file 170 | %files -f additional_files_list 171 | %defattr(-,{{package_install_user}},{{package_install_group}}) 172 | %{_localstatedir}/lib/{{package_install_name}} 173 | %{_localstatedir}/log/{{package_install_name}} 174 | %{_localstatedir}/run/{{package_install_name}} 175 | %defattr(-,root,root) 176 | %{_sysconfdir}/init.d/{{package_install_name}} 177 | %{_{{bin_or_sbin}}dir}/* 178 | %{_libdir}/* 179 | %dir %{_sysconfdir}/{{package_install_name}} 180 | %config(noreplace) %{_sysconfdir}/{{package_install_name}}/* 181 | 182 | %clean 183 | rm -rf %{buildroot} 184 | -------------------------------------------------------------------------------- /priv/base/nodetool: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %%! +fnu 3 | %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- 4 | %% ex: ft=erlang ts=4 sw=4 et 5 | %% ------------------------------------------------------------------- 6 | %% 7 | %% nodetool: Helper Script for interacting with live nodes 8 | %% 9 | %% ------------------------------------------------------------------- 10 | 11 | %% installed by node_package (github.com/basho/node_package) 12 | 13 | main(Args) -> 14 | io:setopts([{encoding, utf8}]), 15 | ok = start_epmd(), 16 | %% Extract the args 17 | {RestArgs, TargetNode} = process_args(Args, [], undefined), 18 | 19 | %% Extract the RPC timeout from process dictionary, if it's defined 20 | RpcTimeout = case erlang:get(rpctimeout) of 21 | undefined -> 22 | 60000; 23 | Value -> 24 | Value 25 | end, 26 | 27 | %% process_args() has side-effects (e.g. when processing "-name"), 28 | %% so take care of app-starting business first. 29 | [application:start(App) || App <- [crypto, public_key, ssl]], 30 | 31 | %% any commands that don't need a running node 32 | case RestArgs of 33 | ["chkconfig", File] -> 34 | chkconfig(File); 35 | ["chkconfig", "-config", File|_] -> 36 | chkconfig(File); 37 | _ -> 38 | ok 39 | end, 40 | 41 | %% See if the node is currently running -- if it's not, we'll bail 42 | case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of 43 | {true, pong} -> 44 | ok; 45 | {false, pong} -> 46 | io:format(standard_error, "failed to connect to node ~p .\n", [TargetNode]), 47 | halt(1); 48 | {_, pang} -> 49 | io:format(standard_error, "Node ~p not responding to pings.\n", [TargetNode]), 50 | halt(1) 51 | end, 52 | 53 | case RestArgs of 54 | ["getpid"] -> 55 | io:format("~p\n", [list_to_integer(rpc:call(TargetNode, os, getpid, []))]); 56 | ["ping"] -> 57 | %% If we got this far, the node already responsed to a ping, so just dump 58 | %% a "pong" 59 | io:format("pong\n"); 60 | ["stop"] -> 61 | io:format("~p\n", [rpc:call(TargetNode, erlang, apply, 62 | [fun() -> 63 | catch error_logger:info_msg("Administrative stop\n"), 64 | init:stop() 65 | end, []], RpcTimeout)]); 66 | ["restart"] -> 67 | io:format("~p\n", [rpc:call(TargetNode, erlang, apply, 68 | [fun() -> 69 | catch error_logger:info_msg("Administrative restart\n"), 70 | init:restart() 71 | end, []], RpcTimeout)]); 72 | ["reboot"] -> 73 | io:format("~p\n", [rpc:call(TargetNode, erlang, apply, 74 | [fun() -> 75 | catch error_logger:info_msg("Administrative reboot\n"), 76 | init:reboot() 77 | end, []], RpcTimeout)]); 78 | ["rpc", Module, Function | RpcArgs] -> 79 | case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 80 | [RpcArgs], RpcTimeout) of 81 | ok -> 82 | ok; 83 | {badrpc, Reason} -> 84 | io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]), 85 | halt(1); 86 | {error, Code} when is_integer(Code) -> 87 | halt(Code); 88 | {error, Code, Reason} when is_integer(Code) -> 89 | io:format(standard_error, "ERROR: ~p\n", [Reason]), 90 | halt(Code); 91 | _ -> 92 | halt(1) 93 | end; 94 | ["rpc_infinity", Module, Function | RpcArgs] -> 95 | case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], infinity) of 96 | ok -> 97 | ok; 98 | {badrpc, Reason} -> 99 | io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]), 100 | halt(1); 101 | {error, Code} when is_integer(Code) -> 102 | halt(Code); 103 | {error, Code, Reason} when is_integer(Code) -> 104 | io:format(standard_error, "ERROR: ~p\n", [Reason]), 105 | halt(Code); 106 | _ -> 107 | halt(1) 108 | end; 109 | ["rpcterms", Module, Function, ArgsAsString] -> 110 | case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), 111 | consult(ArgsAsString), RpcTimeout) of 112 | {badrpc, Reason} -> 113 | io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]), 114 | halt(1); 115 | {error, Code} when is_integer(Code) -> 116 | halt(Code); 117 | {error, Code, Reason} when is_integer(Code) -> 118 | io:format(standard_error, "ERROR: ~p\n", [Reason]), 119 | halt(Code); 120 | Other -> 121 | io:format("~p\n", [Other]) 122 | end; 123 | Other -> 124 | io:format("Other: ~p\n", [Other]), 125 | io:format("Usage: nodetool {ping|stop|restart|reboot|chkconfig}\n") 126 | end, 127 | net_kernel:stop(). 128 | 129 | process_args([], Acc, TargetNode) -> 130 | {lists:reverse(Acc), TargetNode}; 131 | process_args(["-kernel", "net_ticktime", Value | Rest], Acc, TargetNode) -> 132 | application:set_env(kernel, net_ticktime, list_to_integer(Value)), 133 | process_args(Rest, Acc, TargetNode); 134 | process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> 135 | erlang:set_cookie(node(), list_to_atom(Cookie)), 136 | process_args(Rest, Acc, TargetNode); 137 | process_args(["-name", TargetName | Rest], Acc, _) -> 138 | ThisNode = append_node_suffix(TargetName, "_maint_"), 139 | {ok, _} = net_kernel:start([ThisNode, longnames]), 140 | process_args(Rest, Acc, nodename(TargetName)); 141 | process_args(["-sname", TargetName | Rest], Acc, _) -> 142 | ThisNode = append_node_suffix(TargetName, "_maint_"), 143 | {ok, _} = net_kernel:start([ThisNode, shortnames]), 144 | process_args(Rest, Acc, nodename(TargetName)); 145 | process_args(["-rpctimeout", TimeoutStr | Rest], Acc, TargetNode) -> 146 | Timeout = case TimeoutStr of 147 | "infinity" -> infinity; 148 | _ -> list_to_integer(TimeoutStr) 149 | end, 150 | erlang:put(rpctimeout, Timeout), 151 | process_args(Rest, Acc, TargetNode); 152 | process_args([Arg | Rest], Acc, Opts) -> 153 | process_args(Rest, [Arg | Acc], Opts). 154 | 155 | 156 | start_epmd() -> 157 | case os:getenv("NO_EPMD") of 158 | false -> 159 | [] = os:cmd(epmd_path() ++ " -daemon"), 160 | ok; 161 | _ -> 162 | ok 163 | end. 164 | 165 | epmd_path() -> 166 | ErtsBinDir = filename:dirname(escript:script_name()), 167 | Name = "epmd", 168 | case os:find_executable(Name, ErtsBinDir) of 169 | false -> 170 | case os:find_executable(Name) of 171 | false -> 172 | io:format("Could not find epmd.~n"), 173 | halt(1); 174 | GlobalEpmd -> 175 | GlobalEpmd 176 | end; 177 | Epmd -> 178 | Epmd 179 | end. 180 | 181 | 182 | nodename(Name) -> 183 | case string:tokens(Name, "@") of 184 | [_Node, _Host] -> 185 | list_to_atom(Name); 186 | [Node] -> 187 | [_, Host] = string:tokens(atom_to_list(node()), "@"), 188 | list_to_atom(lists:concat([Node, "@", Host])) 189 | end. 190 | 191 | append_node_suffix(Name, Suffix) -> 192 | Rnd = erlang:phash2({os:timestamp(),os:getpid()}, 1000), 193 | case string:tokens(Name, "@") of 194 | [Node, Host] -> 195 | list_to_atom(lists:concat([Node, Suffix, Rnd, "@", Host])); 196 | [Node] -> 197 | list_to_atom(lists:concat([Node, Suffix, Rnd])) 198 | end. 199 | 200 | chkconfig(File) -> 201 | case file:consult(File) of 202 | {ok, _} -> 203 | io:format("ok\n"), 204 | halt(0); 205 | {error, {Line, Mod, Term}} -> 206 | io:format(standard_error, 207 | ["Error on line ", 208 | file:format_error({Line, Mod, Term}), "\n"], []), 209 | halt(1); 210 | {error, R} -> 211 | io:format(standard_error, 212 | ["Error reading config file: ", 213 | file:format_error(R), "\n"], []), 214 | halt(1) 215 | end. 216 | 217 | 218 | %% 219 | %% Given a string or binary, parse it into a list of terms, ala file:consult/0 220 | %% 221 | consult(Str) when is_list(Str) -> 222 | consult([], Str, []); 223 | consult(Bin) when is_binary(Bin)-> 224 | consult([], binary_to_list(Bin), []). 225 | 226 | consult(Cont, Str, Acc) -> 227 | case erl_scan:tokens(Cont, Str, 0) of 228 | {done, Result, Remaining} -> 229 | case Result of 230 | {ok, Tokens, _} -> 231 | {ok, Term} = erl_parse:parse_term(Tokens), 232 | consult([], Remaining, [Term | Acc]); 233 | {eof, _Other} -> 234 | lists:reverse(Acc); 235 | {error, Info, _} -> 236 | {error, Info} 237 | end; 238 | {more, Cont1} -> 239 | consult(Cont1, eof, Acc) 240 | end. 241 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | -------------------------------------------------------------------------------- /priv/templates/smartos/Makefile: -------------------------------------------------------------------------------- 1 | BUILDDIR = $(shell pwd) 2 | # SmartOS doesn't like package names with '-' in the name, so clean any if they 3 | # exist 4 | PACKAGE_NAME_CLEAN = $(shell echo "{{package_name}}" | sed -e 's/-/_/g') 5 | BUILD_STAGE_DIR = $(BUILDDIR)/$(PACKAGE_NAME_CLEAN) 6 | 7 | ## Version Information 8 | ## ## pkgsrc version mapping to SmartOS version 9 | ## SmartOS pkgsrc 10 | ## 1.6 2011Q4 11 | ## 1.8 2012Q2 12 | ## 13.1 2013Q1 13 | ## ## Erlang Deps by version 14 | ## SmartOS openssl ncurses 15 | ## 1.6 0.9.8knb1 5.4nb1 16 | ## 1.8 0.9.8knb1 5.4nb1 17 | ## 13.1 1.0.1c 5.4nb1 18 | ## 19 | ## ## SMF Manifest Mapping 20 | ## SmartOS Manifest File 21 | ## 1.6 manifest16.xml 22 | ## 1.8 manifest18.xml 23 | ## 13.1 manifest131.xml 24 | 25 | PKGSRC_VERSION = $(shell head -1 /etc/pkgsrc_version 2>/dev/null | cut -d' ' -f2) 26 | 27 | ifeq ($(PKGSRC_VERSION),2011Q4) # SmartOS 1.6 28 | NCURSES_DEP = ncurses-5* 29 | OPENSSL_DEP = openssl-0.9.8* 30 | GCC_DEP = gcc-runtime-4.6.2 31 | SMF_MANIFEST = manifest16.xml 32 | endif 33 | ifeq ($(PKGSRC_VERSION),2012Q2) # SmartOS 1.8 34 | NCURSES_DEP = ncurses-5* 35 | OPENSSL_DEP = openssl-0.9.8* 36 | GCC_DEP = gcc47-runtime>=4.7.0 37 | SMF_MANIFEST = manifest18.xml 38 | endif 39 | ifeq ($(PKGSRC_VERSION),2013Q1) # SmartOS 13.1 40 | NCURSES_DEP = ncurses-5* 41 | OPENSSL_DEP = openssl-1.0.1* 42 | GCC_DEP = gcc47-libs>=4.7.0 43 | SMF_MANIFEST = manifest131.xml 44 | endif 45 | ifeq ($(PKGSRC_VERSION),2015Q4) # SmartOS 15.4.0 46 | NCURSES_DEP = ncurses-6* 47 | OPENSSL_DEP = openssl-1.0.2* 48 | GCC_DEP = gcc49-libs>=4.9.3 49 | SMF_MANIFEST = manifest154.xml 50 | endif 51 | 52 | 53 | # Where we install things (based on vars.config) 54 | # /opt/local based dirs 55 | # /var based dirs are handled in the +INSTALL file and dirs_file target 56 | PMAN_DIR := $(BUILD_STAGE_DIR)/man 57 | PBIN_DIR := $(BUILD_STAGE_DIR)/{{bin_or_sbin}} 58 | PETC_DIR := $(BUILD_STAGE_DIR)/etc/{{package_install_name}} 59 | PLIB_DIR := $(BUILD_STAGE_DIR)/lib/{{package_install_name}} 60 | PSMF_DIR := $(BUILD_STAGE_DIR)/share/smf/{{package_install_name}} 61 | ESMF_DIR := $(BUILD_STAGE_DIR)/share/smf/{{package_install_name}}-epmd 62 | PDATA_DIR := $(BUILD_STAGE_DIR)/{{platform_data_dir}} 63 | 64 | # For scanning later, grab the first dirname 65 | # '/var/db/server' becomes 'var' 66 | PDATA_ROOT_DIR = $(shell echo "{{platform_data_dir}}" | cut -d'/' -f 2) 67 | 68 | 69 | 70 | # Recursive assignment of ERTS version 71 | # We will know this after building the rel 72 | ERTS_PATH = $(shell ls $(BUILDDIR)/rel/{{package_install_name}} | egrep -o "erts-.*") 73 | 74 | TARNAME := $(PACKAGE_NAME_CLEAN)-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tar 75 | PKGNAME := $(PACKAGE_NAME_CLEAN)-$(PKG_VERSION)-$(OSNAME)-$(ARCH).tgz 76 | 77 | # pkg_add on Smartos requires that the tar file 78 | # and +CONTENTS files are in the exact same order 79 | # so we need to pack up the tar in a very 80 | # particular order to not anger pkg_add. 81 | # This is done by piping the file listings into tar 82 | # in the same manner we did with the +CONTENTS file 83 | build: packing_list_files dirs_file 84 | @echo "Building package $(PKGNAME)" 85 | mkdir -p packages 86 | cd $(BUILD_STAGE_DIR) && \ 87 | tar -cf $(TARNAME) +CONTENTS +COMMENT +DESC +INSTALL +DEINSTALL +DISPLAY +BUILD_INFO 88 | cd $(BUILD_STAGE_DIR) && \ 89 | find man -type f | tar -rf $(TARNAME) -T - && \ 90 | find etc -type f | tar -rf $(TARNAME) -T - && \ 91 | find lib -type f | tar -rf $(TARNAME) -T - && \ 92 | find {{bin_or_sbin}} -type f | tar -rf $(TARNAME) -T - && \ 93 | find share -type f | tar -rf $(TARNAME) -T - 94 | 95 | cd $(BUILD_STAGE_DIR) && \ 96 | mkdir ../../packages && \ 97 | gzip $(TARNAME) && \ 98 | mv $(TARNAME).gz ../../packages/$(PKGNAME) 99 | 100 | cd ../packages && \ 101 | for tarfile in *.tgz; do \ 102 | shasum -a 256 $${tarfile} > $${tarfile}.sha \ 103 | ; done 104 | 105 | 106 | # Where most of the magic (horror?) happens 107 | # Create a packing list according to pkg_create(1) 108 | # Write initial settings to a local plist then copy 109 | # to the destination folder where we use 'find' 110 | # to populate the files 111 | # SmartOS doesn't allow packages to modify /var 112 | # in the +CONTENTS so that is all done in the +INSTALL instead 113 | packing_list_files: $(BUILD_STAGE_DIR) templates 114 | @echo "Adding to packaging list $(PACKAGE_NAME_CLEAN)-$(PKG_VERSION)" 115 | echo "@name $(PACKAGE_NAME_CLEAN)-$(PKG_VERSION)" >> plist 116 | echo "@pkgcfl $(PACKAGE_NAME_CLEAN)-*" >> plist 117 | echo "@pkgdep $(OPENSSL_DEP)" >> plist 118 | echo "@pkgdep $(NCURSES_DEP)" >> plist 119 | echo "@pkgdep $(GCC_DEP)" >> plist 120 | 121 | @echo "Copying staging package listing to +CONTENTS" 122 | mv plist $(BUILD_STAGE_DIR)/+CONTENTS 123 | 124 | @echo "Packaging /opt/local files" 125 | cd $(BUILD_STAGE_DIR) && \ 126 | echo "@comment Packing manpage files" >> +CONTENTS && \ 127 | echo "@cwd /opt/local" >> +CONTENTS && \ 128 | echo "@owner root" >> +CONTENTS && \ 129 | echo "@group root" >> +CONTENTS && \ 130 | find man -type f >> +CONTENTS 131 | 132 | cd $(BUILD_STAGE_DIR) && \ 133 | echo "@comment Packing /opt/local/etc files" >> +CONTENTS && \ 134 | echo "@cwd /opt/local" >> +CONTENTS && \ 135 | echo "@owner root" >> +CONTENTS && \ 136 | echo "@group {{package_install_user}}" >> +CONTENTS && \ 137 | find etc -type f >> +CONTENTS 138 | 139 | cd $(BUILD_STAGE_DIR) && \ 140 | echo "@comment Packing lib files" >> +CONTENTS && \ 141 | echo "@cwd /opt/local" >> +CONTENTS && \ 142 | echo "@owner root" >> +CONTENTS && \ 143 | echo "@group root" >> +CONTENTS 144 | 145 | cd $(BUILD_STAGE_DIR) && \ 146 | find lib -type f >> +CONTENTS && \ 147 | echo "@exec chown -R root:root {{platform_base_dir}}" >> +CONTENTS 148 | 149 | cd $(BUILD_STAGE_DIR) && \ 150 | echo "@comment Packing /usr/local {{bin_or_sbin}} files" >> +CONTENTS && \ 151 | echo "@owner root" >> +CONTENTS && \ 152 | echo "@group root" >> +CONTENTS && \ 153 | echo "@mode 0755" >> +CONTENTS && \ 154 | find {{bin_or_sbin}} -type f >> +CONTENTS 155 | 156 | cd $(BUILD_STAGE_DIR) && \ 157 | echo "@owner root" >> +CONTENTS && \ 158 | echo "@group root" >> +CONTENTS && \ 159 | find share -type f >> +CONTENTS 160 | 161 | cd $(BUILD_STAGE_DIR) && \ 162 | echo "@display +DISPLAY" >> +CONTENTS 163 | 164 | 165 | # Creates a variable to be read by the +INSTALL script to 166 | # create directories not supported by the +CONTENTS file 167 | # such as log and data directories. 168 | # platform_log_dir and platform_data_dir are always added 169 | # This is black magic appending the directories to 170 | # a variable inside of the makefile target 171 | # and then using sed to insert that list into 172 | # the +INSTALL script. 173 | # I feel dirty now. 174 | dirs_file: $(BUILD_STAGE_DIR) 175 | @echo "Adding data and log directories to directory list" 176 | $(eval PACKAGE_USER_WRITABLE_DIRS = {{platform_data_dir}}) 177 | $(eval PACKAGE_USER_WRITABLE_DIRS += {{platform_log_dir}}) 178 | @echo "Scanning var directory for any additional install paths" 179 | $(eval PACKAGE_USER_WRITABLE_DIRS += $(shell cd $(BUILD_STAGE_DIR) && find $(PDATA_ROOT_DIR) -type d -exec printf "/%s " {} \;)) 180 | cd $(BUILD_STAGE_DIR) && \ 181 | cp +INSTALL +INSTALL.tmp && \ 182 | sed -e 's|%PACKAGE_USER_WRITABLE_DIRS%|${PACKAGE_USER_WRITABLE_DIRS}|' < \ 183 | +INSTALL.tmp > +INSTALL && \ 184 | rm +INSTALL.tmp 185 | 186 | 187 | # These are static files that should not have to change often 188 | templates: $(BUILD_STAGE_DIR) 189 | @echo "Copying metadata files to package" 190 | cp $(PKGERDIR)/+DESC $(PKGERDIR)/+COMMENT $(PKGERDIR)/+DEINSTALL \ 191 | $(PKGERDIR)/+INSTALL $(PKGERDIR)/+BUILD_INFO \ 192 | $(PKGERDIR)/+DISPLAY $(BUILD_STAGE_DIR) 193 | mkdir -p $(PSMF_DIR) 194 | cp $(PKGERDIR)/$(SMF_MANIFEST) $(PSMF_DIR)/manifest.xml 195 | mkdir -p $(ESMF_DIR) 196 | sed -e "s/%ERTS_PATH%/${ERTS_PATH}/" < \ 197 | $(PKGERDIR)/epmd > $(ESMF_DIR)/{{package_install_name}}-epmd 198 | cp $(PKGERDIR)/epmd-manifest.xml $(ESMF_DIR)/manifest.xml 199 | 200 | 201 | # Copy the app rel directory to the staging directory to build our 202 | # package structure and move the directories into the right place 203 | # for the package, see the vars.config file for destination 204 | # directories 205 | # The data and log directories need to go into /var, but the 206 | # smartos pkg_add doesn't allow this to be in the +CONTENTS 207 | # file so the directories are created in the +INSTALL script 208 | # We copy the data and log directories if they exist to make 209 | # scanning them easier later 210 | $(BUILD_STAGE_DIR): buildrel patch_runner 211 | @echo "Copying rel directory to staging directory" 212 | mkdir -p $@ 213 | cp -R $(BUILDDIR)/rel/{{package_install_name}} $(BUILD_STAGE_DIR) 214 | mkdir -p $(PBIN_DIR) 215 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/bin/* $(PBIN_DIR) 216 | mkdir -p $(PETC_DIR) 217 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/etc/* $(PETC_DIR) 218 | mkdir -p $(PLIB_DIR) 219 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/lib $(PLIB_DIR) 220 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/erts-* $(PLIB_DIR) 221 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/releases $(PLIB_DIR) 222 | @echo "Copying man pages to staging directory" 223 | mkdir -p $(PMAN_DIR) 224 | if [ -d $(BUILDDIR)/doc/man/man1 ]; then \ 225 | cp -R $(BUILDDIR)/doc/man/man1 $(PMAN_DIR); fi 226 | @echo "Copying data and log directories to staging directory" 227 | if [ -d $(BUILDDIR)/rel/{{package_install_name}}/data ]; then \ 228 | mkdir -p $(PDATA_DIR) && \ 229 | cp -R $(BUILDDIR)/rel/{{package_install_name}}/data/* $(PDATA_DIR); fi 230 | 231 | 232 | # If we can read the PKGSRC_VERSION we should fail 233 | # If NCURSES_DEP wasn't set, we know it was an unknown PKGSRC version 234 | smartos_check: 235 | @echo "Checking SmartOS Version" 236 | $(if $(PKGSRC_VERSION),,$(error "Cannot find pkgsrc version from /etc/pkgsrc_version, cannot continue")) 237 | $(if $(NCURSES_DEP),,$(error "Unsupported SmartOS version, please add to github.com/basho/node_package")) 238 | @echo "Building for pkgsrc version $(PKGSRC_VERSION)" 239 | 240 | # Patch the runner script with SmartOS modifications 241 | patch_runner: buildrel 242 | cp $(PKGERDIR)/runner.patch $(BUILDDIR)/rel/{{package_install_name}}/bin/ 243 | cd $(BUILDDIR)/rel/{{package_install_name}}/bin && \ 244 | patch -p0 {{package_install_name}} runner.patch 245 | rm $(BUILDDIR)/rel/{{package_install_name}}/bin/runner.patch 246 | 247 | 248 | # Build the release we need to package 249 | # * Ensure all binaries are executable 250 | # * copy the vars.config over for build config 251 | buildrel: $(BUILDDIR) smartos_check 252 | OVERLAY_VARS="overlay_vars=../smartos/vars.config" $(MAKE) rel 253 | chmod 0755 $(BUILDDIR)/rel/{{package_install_name}}/bin/* $(BUILDDIR)/rel/{{package_install_name}}/erts-*/bin/* 254 | 255 | $(BUILDDIR): 256 | mkdir -p $@ 257 | 258 | $(PKGERDIR)/pkgclean: 259 | rm -rf $(BUILD_STAGE_DIR) $(BUILDDIR) 260 | -------------------------------------------------------------------------------- /priv/base/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # -*- tab-width:4;indent-tabs-mode:nil -*- 3 | # ex: ts=4 sw=4 et 4 | 5 | # installed by node_package (github.com/basho/node_package) 6 | 7 | # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. 8 | if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then 9 | POSIX_SHELL="true" 10 | export POSIX_SHELL 11 | # To support POSIX.2 compliant 'id' add /usr/xpg4/bin to path 12 | PATH=/usr/xpg4/bin:$PATH 13 | export PATH 14 | exec /usr/bin/ksh $0 "$@" 15 | fi 16 | unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well 17 | 18 | RUNNER_SCRIPT_DIR={{runner_script_dir}} 19 | RUNNER_SCRIPT=${0##*/} 20 | 21 | RUNNER_BASE_DIR={{runner_base_dir}} 22 | RUNNER_ETC_DIR={{runner_etc_dir}} 23 | RUNNER_LOG_DIR={{runner_log_dir}} 24 | RUNNER_LIB_DIR={{runner_lib_dir}} 25 | RUNNER_PATCH_DIR={{runner_patch_dir}} 26 | PIPE_DIR={{pipe_dir}} 27 | RUNNER_USER={{runner_user}} 28 | APP_VERSION={{app_version}} 29 | 30 | # Variables needed to support creation of .pid files 31 | # PID directory and pid file name of this app 32 | # ex: /var/run/riak & /var/run/riak/riak.pid 33 | RUN_DIR="/var/run" # for now hard coded unless we find a platform that differs 34 | PID_DIR=$RUN_DIR/$RUNNER_SCRIPT 35 | PID_FILE=$PID_DIR/$RUNNER_SCRIPT.pid 36 | 37 | # Threshold where users will be warned of low ulimit file settings 38 | # default it if it is not set 39 | ULIMIT_WARN={{runner_ulimit_warn}} 40 | if [ -z "$ULIMIT_WARN" ]; then 41 | ULIMIT_WARN=4096 42 | fi 43 | 44 | # Registered process to wait for to consider start a success 45 | WAIT_FOR_PROCESS={{runner_wait_process}} 46 | 47 | WHOAMI=`id -un` 48 | 49 | # erlexec requires HOME to be set. The username needs to be a 50 | # unquoted literal because of the tilde expansion, hence the 51 | # usage of eval. 52 | if [ -z "$HOME" ]; then 53 | export HOME=`eval echo "~$WHOAMI"` 54 | fi 55 | 56 | # Echo to stderr on errors 57 | echoerr() { echo "$@" 1>&2; } 58 | 59 | # Extract the target node name from node.args 60 | NAME_ARG=`egrep '^\-name' $RUNNER_ETC_DIR/vm.args 2> /dev/null` 61 | if [ -z "$NAME_ARG" ]; then 62 | NODENAME=`egrep '^[ \t]*nodename[ \t]*=[ \t]*' $RUNNER_ETC_DIR/{{cuttlefish_conf}} 2> /dev/null | tail -1 | cut -d = -f 2` 63 | if [ -z "$NODENAME" ]; then 64 | echoerr "vm.args needs to have a -name parameter." 65 | echoerr " -sname is not supported." 66 | exit 1 67 | else 68 | NAME_ARG="-name ${NODENAME# *}" 69 | fi 70 | fi 71 | 72 | # Learn how to specify node name for connection from remote nodes 73 | NAME_PARAM="-name" 74 | echo "$NAME_ARG" | grep '@.*' > /dev/null 2>&1 75 | if [ "X$?" = "X0" ]; then 76 | NAME_HOST=`echo "${NAME_ARG}" | sed -e 's/.*\(@.*\)$/\1/'` 77 | else 78 | NAME_HOST="" 79 | fi 80 | 81 | # Extract the target cookie 82 | COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args 2> /dev/null` 83 | if [ -z "$COOKIE_ARG" ]; then 84 | COOKIE=`egrep '^[ \t]*distributed_cookie[ \t]*=[ \t]*' $RUNNER_ETC_DIR/{{cuttlefish_conf}} 2> /dev/null | tail -1 | cut -d = -f 2` 85 | if [ -z "$COOKIE" ]; then 86 | echoerr "vm.args needs to have a -setcookie parameter." 87 | exit 1 88 | else 89 | COOKIE_ARG="-setcookie $COOKIE" 90 | fi 91 | fi 92 | 93 | # Extract the target net_ticktime 94 | NET_TICKTIME_ARG=`grep '^\-kernel net_ticktime' $RUNNER_ETC_DIR/vm.args 2> /dev/null` 95 | if [ -z "$NET_TICKTIME_ARG" ]; then 96 | NET_TICKTIME=`egrep '^[ \t]*erlang.distribution.net_ticktime[ \t]*=[ \t]*' $RUNNER_ETC_DIR/{{cuttlefish_conf}} 2> /dev/null | tail -1 | cut -d = -f 2` 97 | if [ -z "$NET_TICKTIME" ]; then 98 | NET_TICKTIME_ARG="" 99 | else 100 | NET_TICKTIME_ARG="-kernel net_ticktime $NET_TICKTIME" 101 | fi 102 | fi 103 | 104 | # Optionally specify a NUMA policy 105 | NUMACTL_ARG="{{numactl_arg}}" 106 | if [ -z "$NUMACTL_ARG" ] 107 | then 108 | NUMACTL="" 109 | # Confirms `numactl` is in the path and validates $NUMACTL_ARG 110 | elif which numactl > /dev/null 2>&1 && numactl $NUMACTL_ARG ls /dev/null > /dev/null 2>&1 111 | then 112 | NUMACTL="numactl $NUMACTL_ARG" 113 | else 114 | echoerr "NUMACTL_ARG is specified in env.sh but numactl is not installed or NUMACTL_ARG is invalid." 115 | exit 1 116 | fi 117 | 118 | # Parse out release and erts info 119 | START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data` 120 | ERTS_VSN=${START_ERL% *} 121 | APP_VSN=${START_ERL#* } 122 | 123 | # Add ERTS bin dir to our path 124 | ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin 125 | 126 | # Setup command to control the node 127 | NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NET_TICKTIME_ARG $NAME_ARG $COOKIE_ARG" 128 | NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool" 129 | 130 | 131 | ## Are we using cuttlefish (http://github.com/basho/cuttlefish) 132 | ## for configuration. This needs to come after the $ERTS_PATH 133 | ## definition 134 | CUTTLEFISH="{{cuttlefish}}" 135 | if [ -z "$CUTTLEFISH" ]; then 136 | CUTTLEFISH_COMMAND_PREFIX="" 137 | else 138 | CUTTLEFISH_COMMAND_PREFIX="$ERTS_PATH/escript $ERTS_PATH/cuttlefish -e $RUNNER_ETC_DIR -s $RUNNER_LIB_DIR -d {{platform_data_dir}}/generated.configs -c $RUNNER_ETC_DIR/{{cuttlefish_conf}}" 139 | fi 140 | 141 | # Ping node without stealing stdin 142 | ping_node() { 143 | $NODETOOL ping < /dev/null 144 | } 145 | 146 | # Attempts to create a pid directory like /var/run/APPNAME and then 147 | # changes the permissions on that directory so the $RUNNER_USER can 148 | # read/write/delete .pid files during startup/shutdown 149 | create_pid_dir() { 150 | # Validate RUNNER_USER is set and they have permissions to write to /var/run 151 | # Don't continue if we've already su'd to RUNNER_USER 152 | if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then 153 | if [ -w $RUN_DIR ]; then 154 | mkdir -p $PID_DIR 155 | ES=$? 156 | if [ "$ES" -ne 0 ]; then 157 | return 1 158 | else 159 | # Change permissions on $PID_DIR 160 | chown $RUNNER_USER $PID_DIR 161 | ES=$? 162 | if [ "$ES" -ne 0 ]; then 163 | return 1 164 | else 165 | return 0 166 | fi 167 | fi 168 | else 169 | # If we don't have permissions, fail 170 | return 1 171 | fi 172 | fi 173 | 174 | # If RUNNER_USER is not set this is probably a test setup (devrel) and does 175 | # not need a .pid file, so do not return error 176 | return 0 177 | } 178 | 179 | # Attempt to create a pid file for the process 180 | # This function assumes the process is already up and running and can 181 | # respond to a getpid call. It also assumes that two processes 182 | # with the same name will not be run on the machine 183 | # Do not print any error messages as failure to create a pid file because 184 | # pid files are strictly optional 185 | # This function should really only be called in a "start" function 186 | # you have been warned 187 | create_pid_file() { 188 | # Validate a pid directory even exists 189 | if [ -w $PID_DIR ]; then 190 | # Grab the proper pid from getpid 191 | get_pid 192 | ES=$? 193 | if [ "$ES" -ne 0 ]; then 194 | return $ES 195 | else 196 | # Remove pid file if it already exists since we do not 197 | # plan for multiple identical runners on a single machine 198 | rm -f $PID_FILE 199 | echo $PID > $PID_FILE 200 | return 0 201 | fi 202 | else 203 | return 1 204 | fi 205 | } 206 | 207 | 208 | # Simple way to check the correct user and fail early 209 | check_user_internal() { 210 | # Validate that the user running the script is the owner of the 211 | # RUN_DIR. 212 | if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then 213 | if [ "x$WHOAMI" != "xroot" ]; then 214 | echo "You need to be root or use sudo to run this command" 215 | exit 1 216 | fi 217 | fi 218 | } 219 | 220 | # Function to su into correct user that is poorly named for historical 221 | # reasons (excuses) 222 | # This also serves as an entry point to most functions 223 | check_user() { 224 | check_user_internal 225 | 226 | # This call must be before the su call, when the user is dropped 227 | # optional config will be brought in if available 228 | load_default_os_config 229 | 230 | # do not su again if we are already the runner user 231 | if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then 232 | # Escape any double quotes that might be in the command line 233 | # args. Without this, passing something like JSON on the command 234 | # line will get stripped. 235 | # Ex: 236 | # riak-admin bucket-type create mytype '{"props": {"n_val": 4}}' 237 | # would become 238 | # riak-admin bucket-type create mytype {props: {n_val: 4}} 239 | # after the arguments were passed into the new shell during exec su 240 | # 241 | # So this regex finds any '(', ')', "'" , '"', '{', or '}' and prepends with a '\' 242 | ESCAPED_ARGS=`echo "$@" | sed -e 's/\([\\\(\\\){}"\x27]\)/\\\\\1/g'` 243 | 244 | # This will drop priviledges into the runner user 245 | # It exec's in a new shell and the current shell will exit 246 | exec su - $RUNNER_USER -c "$RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $ESCAPED_ARGS" 247 | fi 248 | } 249 | 250 | # Function to load default config files based on OS 251 | load_default_os_config() { 252 | # Only run this if we already dropped to the runner user 253 | if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" = "x$RUNNER_USER" ]); then 254 | # Common config file on Debian-like systems 255 | [ -r /etc/default/$RUNNER_SCRIPT ] && . /etc/default/$RUNNER_SCRIPT 256 | 257 | # Common config file on RPM-like systems 258 | [ -r /etc/sysconfig/$RUNNER_SCRIPT ] && . /etc/sysconfig/$RUNNER_SCRIPT 259 | fi 260 | } 261 | 262 | # Function to validate the node is down 263 | node_down_check() { 264 | MUTE=`ping_node 2> /dev/null` 265 | if [ "$?" -eq 0 ]; then 266 | echoerr "Node is already running!" 267 | exit 1 268 | fi 269 | } 270 | 271 | # Function to validate the node is up 272 | node_up_check() { 273 | MUTE=`ping_node 2> /dev/null` 274 | if [ "$?" -ne 0 ]; then 275 | echoerr "Node did not respond to ping!" 276 | exit 1 277 | fi 278 | } 279 | 280 | # Function to check if the config file is valid 281 | check_config() { 282 | if [ -z "$CUTTLEFISH" ]; then 283 | # Note: we have added a parameter '-vm_args' to this. It 284 | # appears redundant but it is not! the erlang vm allows us to 285 | # access all arguments to the erl command EXCEPT '-args_file', 286 | # so in order to get access to this file location from within 287 | # the vm, we need to pass it in twice. 288 | CONFIG_ARGS=" -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/vm.args -vm_args $RUNNER_ETC_DIR/vm.args " 289 | else 290 | CONFIG_ARGS=`$CUTTLEFISH_COMMAND_PREFIX generate` 291 | if [ "$?" -ne 0 ]; then 292 | echoerr "Error generating config with cuttlefish" 293 | echoerr " run \`$RUNNER_SCRIPT config generate -l debug\` for more information." 294 | exit 1 295 | fi 296 | fi 297 | 298 | MUTE=`$NODETOOL_LITE chkconfig $CONFIG_ARGS` 299 | if [ "$?" -ne 0 ]; then 300 | echoerr "Error reading $CONFIG_ARGS" 301 | exit 1 302 | fi 303 | echo "config is OK" 304 | echo $CONFIG_ARGS 305 | } 306 | 307 | # Function to check if ulimit is properly set 308 | check_ulimit() { 309 | 310 | # don't fail if this is unset 311 | if [ ! -z "$ULIMIT_WARN" ]; then 312 | ULIMIT_F=`ulimit -n` 313 | if [ "$ULIMIT_F" -lt $ULIMIT_WARN ]; then 314 | echo "!!!!" 315 | echo "!!!! WARNING: ulimit -n is ${ULIMIT_F}; ${ULIMIT_WARN} is the recommended minimum." 316 | echo "!!!!" 317 | fi 318 | fi 319 | } 320 | 321 | # Set the PID global variable, return 1 on error 322 | get_pid() { 323 | PID=`$NODETOOL getpid < /dev/null` 324 | if [ "$?" -ne 0 ]; then 325 | echo "Node is not running!" 326 | return 1 327 | fi 328 | 329 | # don't allow empty or init pid's 330 | if [ -z $PID ] || [ "$PID" -le 1 ]; then 331 | return 1 332 | fi 333 | 334 | return 0 335 | } 336 | -------------------------------------------------------------------------------- /priv/base/runner: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # -*- tab-width:4;indent-tabs-mode:nil -*- 3 | # ex: ts=4 sw=4 et 4 | 5 | # installed by node_package (github.com/basho/node_package) 6 | 7 | # Pull environment for this install 8 | . "{{runner_base_dir}}/lib/env.sh" 9 | 10 | 11 | # Keep track of where script was invoked 12 | ORIGINAL_DIR=$(pwd) 13 | 14 | # Make sure CWD is set to runner run dir 15 | cd $RUNNER_BASE_DIR 16 | 17 | # Identify the script name 18 | SCRIPT=`basename $0` 19 | 20 | usage() { 21 | cat <&1 189 | 190 | if [ ! -z "$WAIT_FOR_PROCESS" ]; then 191 | # Wait for the node to come up. We can't just ping it because 192 | # distributed erlang comes up for a second before the node crashes 193 | # (eg. in the case of an unwriteable disk). Once the node comes 194 | # up we check for the $WAIT_FOR_PROCESS} process. If that's running 195 | # then we assume things are good enough. This will at least let 196 | # the user know when the node is crashing right after startup. 197 | WAIT=${WAIT_FOR_ERLANG:-15} 198 | while [ $WAIT -gt 0 ]; do 199 | WAIT=`expr $WAIT - 1` 200 | sleep 1 201 | 202 | # squash stderr output to not frighten users if the node does not 203 | # come up right away 204 | MUTE=`ping_node 2> /dev/null` 205 | if [ "$?" -ne 0 ]; then 206 | continue 207 | fi 208 | PROCESS=`$NODETOOL rpcterms erlang whereis "'${WAIT_FOR_PROCESS}'."` 209 | if [ "$PROCESS" != "undefined" ]; then 210 | # Attempt to create a .pid file for the process 211 | create_pid_file 212 | exit 0 213 | fi 214 | done 215 | echo "${SCRIPT} failed to start within ${WAIT_FOR_ERLANG:-15} seconds," 216 | echo "see the output of '${SCRIPT} console' for more information." 217 | echo "If you want to wait longer, set the environment variable" 218 | echo "WAIT_FOR_ERLANG to the number of seconds to wait." 219 | exit 1 220 | fi 221 | 222 | # Attempt to create .pid file 223 | create_pid_file 224 | } 225 | 226 | do_stop() { 227 | get_pid 228 | ES=$? 229 | if [ "$ES" -ne 0 ] || [ -z $PID ]; then 230 | exit $ES 231 | fi 232 | 233 | # Tell nodetool to stop 234 | $NODETOOL stop 235 | ES=$? 236 | if [ "$ES" -ne 0 ]; then 237 | exit $ES 238 | fi 239 | 240 | # Now wait for the app to *really* stop 241 | while `kill -s 0 $PID 2>/dev/null`; 242 | do 243 | sleep 1 244 | done 245 | 246 | # remove pid file 247 | rm -f $PID_FILE 248 | } 249 | 250 | # Check the first argument for instructions 251 | case "$1" in 252 | start) 253 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 254 | bootstrapd $@ 255 | do_start 256 | ;; 257 | 258 | stop) 259 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 260 | bootstrapd $@ 261 | do_stop 262 | ;; 263 | 264 | restart) 265 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 266 | bootstrapd $@ 267 | do_stop 268 | do_start 269 | ;; 270 | 271 | ping) 272 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 273 | bootstrapd $@ 274 | ## See if the VM is alive 275 | ping_node 276 | ES=$? 277 | if [ "$ES" -ne 0 ]; then 278 | exit $ES 279 | fi 280 | ;; 281 | 282 | attach-direct) 283 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 284 | bootstrapd $@ 285 | 286 | # Allow attaching to a node without pinging it 287 | if [ "$2" = "-f" ]; then 288 | echo "Forcing connection..." 289 | else 290 | # Make sure a node is running 291 | node_up_check 292 | fi 293 | 294 | echo "Direct Shell: Use \"Ctrl-D\" to quit. \"Ctrl-C\" will terminate the $SCRIPT node." 295 | shift 296 | exec $ERTS_PATH/to_erl $PIPE_DIR 297 | ;; 298 | 299 | attach) 300 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 301 | bootstrapd $@ 302 | 303 | # Make sure a node is running 304 | node_up_check 305 | 306 | echo "Remote Shell: Use \"Ctrl-G q\" to quit." 307 | echo "q() or init:stop() will terminate the $SCRIPT node." 308 | shift 309 | RAND=$(($(($$ % 1000)) + 1)) 310 | NODE_NAME=${NAME_ARG#* } 311 | exec $ERTS_PATH/erl -name c$RAND$NODE_NAME -hidden -remsh $NODE_NAME $COOKIE_ARG $NET_TICKTIME_ARG 312 | ;; 313 | 314 | console) 315 | # Bootstrap daemon command (check perms & drop to $RUNNER_USER) 316 | bootstrapd $@ 317 | 318 | RES=`ping_node 2> /dev/null` 319 | if [ "$?" -eq 0 ]; then 320 | echo "Node is already running - use '$SCRIPT attach' instead" 321 | exit 1 322 | fi 323 | 324 | # Sanity check the app.config file 325 | check_config 326 | ES=$? 327 | if [ "$ES" -ne 0 ]; then 328 | exit $ES 329 | fi 330 | 331 | # Warn the user if ulimit -n is less than the defined threshold 332 | check_ulimit 333 | 334 | # Make sure log directory exists 335 | mkdir -p $RUNNER_LOG_DIR 336 | 337 | # Setup beam-required vars 338 | ROOTDIR=$RUNNER_BASE_DIR 339 | BINDIR=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin 340 | EMU=beam 341 | PROGNAME=`echo $0 | sed 's/.*\///'` 342 | CMD="$NUMACTL $BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$RUNNER_SCRIPT \ 343 | $CONFIG_ARGS \ 344 | -pa $RUNNER_PATCH_DIR -- ${1+"$@"}" 345 | export EMU 346 | export ROOTDIR 347 | export BINDIR 348 | export PROGNAME 349 | 350 | # Dump environment info for logging purposes 351 | echo "Exec: $CMD" 352 | echo "Root: $ROOTDIR" 353 | 354 | # Log the startup 355 | logger -t "$SCRIPT[$$]" "Starting up" 356 | 357 | # Start the VM 358 | exec $CMD 359 | ;; 360 | 361 | top) 362 | # Make sure the local node IS running 363 | node_up_check 364 | 365 | shift 366 | RAND=$(($(($$ % 1000)) + 1)) 367 | NODE_NAME=${NAME_ARG#* } 368 | $ERTS_PATH/erl -noshell -noinput \ 369 | -pa $RUNNER_PATCH_DIR \ 370 | -hidden $NAME_PARAM np_etop$RAND$NAME_HOST $COOKIE_ARG $NET_TICKTIME_ARG \ 371 | -s etop -s erlang halt -output text \ 372 | -node $NODE_NAME \ 373 | $* -tracing off 374 | ;; 375 | 376 | ertspath) 377 | echo $ERTS_PATH 378 | ;; 379 | 380 | chkconfig) 381 | bootstrapd $@ 382 | 383 | check_config 384 | ;; 385 | 386 | config) 387 | shift 388 | if [ -z "$CUTTLEFISH" ]; then 389 | echo "This application is not configured to use cuttlefish." 390 | echo "$RUNNER_SCRIPT config is not available." 391 | exit 1 392 | else 393 | # Let's validate the output 394 | 395 | case "$1" in 396 | effective) ## Great, pass through! 397 | ;; 398 | describe) 399 | if [ $# -lt 2 ] || [ "$2" = "-l" ]; then 400 | echo "$RUNNER_SCRIPT config describe requires a variable name to query" 401 | echo " Try \`$RUNNER_SCRIPT config describe setting.name\`" 402 | exit 1 403 | fi 404 | ;; 405 | generate) ## Great, pass through! 406 | ;; 407 | *) 408 | echo "Valid commands for $RUNNER_SCRIPT config are:" 409 | echo " $RUNNER_SCRIPT config effective" 410 | echo " $RUNNER_SCRIPT config describe VARIABLE" 411 | exit 1 412 | ;; 413 | esac 414 | 415 | printf '%s \n' "`$CUTTLEFISH_COMMAND_PREFIX $@`" 416 | fi 417 | ;; 418 | 419 | escript) 420 | shift 421 | $ERTS_PATH/escript "$@" 422 | ES=$? 423 | if [ "$ES" -ne 0 ]; then 424 | exit $ES 425 | fi 426 | ;; 427 | 428 | version) 429 | echo $APP_VERSION 430 | ;; 431 | 432 | getpid) 433 | # Get the PID from nodetool 434 | get_pid 435 | ES=$? 436 | if [ "$ES" -ne 0 ] || [ -z $PID ]; then 437 | exit $ES 438 | fi 439 | echo $PID 440 | ;; 441 | 442 | help) 443 | help 444 | ;; 445 | *) 446 | usage 447 | ;; 448 | esac 449 | 450 | exit 0 451 | -------------------------------------------------------------------------------- /priv/templates/fbsd/+MTREE_DIRS: -------------------------------------------------------------------------------- 1 | # $FreeBSD: ports/Templates/BSD.local.dist,v 1.3 2010/11/12 20:57:14 pav Exp $ 2 | # 3 | # Please see the file src/etc/mtree/README before making changes to this file. 4 | # 5 | 6 | /set type=dir uname=root gname=wheel mode=0755 7 | . 8 | bin 9 | .. 10 | etc 11 | devd 12 | .. 13 | man.d 14 | .. 15 | pam.d 16 | .. 17 | rc.d 18 | .. 19 | .. 20 | include 21 | X11 22 | .. 23 | .. 24 | info 25 | .. 26 | lib 27 | X11 28 | app-defaults 29 | .. 30 | fonts 31 | local 32 | .. 33 | .. 34 | .. 35 | .. 36 | libdata 37 | ldconfig 38 | .. 39 | ldconfig32 40 | .. 41 | pkgconfig 42 | .. 43 | .. 44 | libexec 45 | .. 46 | man 47 | /set uname=man 48 | cat1 49 | .. 50 | cat2 51 | .. 52 | cat3 53 | .. 54 | cat4 55 | .. 56 | cat5 57 | .. 58 | cat6 59 | .. 60 | cat7 61 | .. 62 | cat8 63 | .. 64 | cat9 65 | .. 66 | catl 67 | .. 68 | catn 69 | .. 70 | de.ISO8859-1 uname=root 71 | cat1 72 | .. 73 | cat2 74 | .. 75 | cat3 76 | .. 77 | cat4 78 | .. 79 | cat5 80 | .. 81 | cat6 82 | .. 83 | cat7 84 | .. 85 | cat8 86 | .. 87 | cat9 88 | .. 89 | catl 90 | .. 91 | catn 92 | .. 93 | /set uname=root 94 | man1 95 | .. 96 | man2 97 | .. 98 | man3 99 | .. 100 | man4 101 | .. 102 | man5 103 | .. 104 | man6 105 | .. 106 | man7 107 | .. 108 | man8 109 | .. 110 | man9 111 | .. 112 | manl 113 | .. 114 | mann 115 | .. 116 | .. 117 | en.ISO8859-1 118 | /set uname=man 119 | cat1 120 | .. 121 | cat1aout 122 | .. 123 | cat2 124 | .. 125 | cat3 126 | .. 127 | cat4 128 | i386 129 | .. 130 | .. 131 | cat5 132 | .. 133 | cat6 134 | .. 135 | cat7 136 | .. 137 | cat8 138 | i386 139 | .. 140 | .. 141 | cat9 142 | i386 143 | .. 144 | .. 145 | catn 146 | .. 147 | .. 148 | ja uname=root 149 | cat1 150 | .. 151 | cat2 152 | .. 153 | cat3 154 | .. 155 | cat4 156 | .. 157 | cat5 158 | .. 159 | cat6 160 | .. 161 | cat7 162 | .. 163 | cat8 164 | .. 165 | cat9 166 | .. 167 | catl 168 | .. 169 | catn 170 | .. 171 | /set uname=root 172 | man1 173 | .. 174 | man2 175 | .. 176 | man3 177 | .. 178 | man4 179 | .. 180 | man5 181 | .. 182 | man6 183 | .. 184 | man7 185 | .. 186 | man8 187 | .. 188 | man9 189 | .. 190 | manl 191 | .. 192 | mann 193 | .. 194 | .. 195 | man1 196 | .. 197 | man2 198 | .. 199 | man3 200 | .. 201 | man4 202 | .. 203 | man5 204 | .. 205 | man6 206 | .. 207 | man7 208 | .. 209 | man8 210 | .. 211 | man9 212 | .. 213 | manl 214 | .. 215 | mann 216 | .. 217 | ru.KOI8-R 218 | /set uname=man 219 | cat1 220 | .. 221 | cat2 222 | .. 223 | cat3 224 | .. 225 | cat4 226 | .. 227 | cat5 228 | .. 229 | cat6 230 | .. 231 | cat7 232 | .. 233 | cat8 234 | .. 235 | cat9 236 | .. 237 | catl 238 | .. 239 | catn 240 | .. 241 | /set uname=root 242 | man1 243 | .. 244 | man2 245 | .. 246 | man3 247 | .. 248 | man4 249 | .. 250 | man5 251 | .. 252 | man6 253 | .. 254 | man7 255 | .. 256 | man8 257 | .. 258 | man9 259 | .. 260 | manl 261 | .. 262 | mann 263 | .. 264 | .. 265 | .. 266 | sbin 267 | .. 268 | share 269 | aclocal 270 | .. 271 | dict 272 | .. 273 | doc 274 | ja 275 | .. 276 | .. 277 | emacs 278 | site-lisp 279 | .. 280 | .. 281 | examples 282 | .. 283 | java 284 | classes 285 | .. 286 | .. 287 | locale 288 | af 289 | LC_MESSAGES 290 | .. 291 | .. 292 | am 293 | LC_MESSAGES 294 | .. 295 | .. 296 | ar 297 | LC_MESSAGES 298 | .. 299 | .. 300 | az 301 | LC_MESSAGES 302 | .. 303 | .. 304 | be 305 | LC_MESSAGES 306 | .. 307 | .. 308 | bg 309 | LC_MESSAGES 310 | .. 311 | .. 312 | bn 313 | LC_MESSAGES 314 | .. 315 | .. 316 | br 317 | LC_MESSAGES 318 | .. 319 | .. 320 | bs 321 | LC_MESSAGES 322 | .. 323 | .. 324 | ca 325 | LC_MESSAGES 326 | .. 327 | .. 328 | cs 329 | LC_MESSAGES 330 | .. 331 | .. 332 | cy 333 | LC_MESSAGES 334 | .. 335 | .. 336 | da 337 | LC_MESSAGES 338 | .. 339 | .. 340 | de 341 | LC_MESSAGES 342 | .. 343 | .. 344 | de_AT 345 | LC_MESSAGES 346 | .. 347 | .. 348 | dk 349 | LC_MESSAGES 350 | .. 351 | .. 352 | ee 353 | LC_MESSAGES 354 | .. 355 | .. 356 | el 357 | LC_MESSAGES 358 | .. 359 | .. 360 | en 361 | LC_MESSAGES 362 | .. 363 | .. 364 | en_AU 365 | LC_MESSAGES 366 | .. 367 | .. 368 | en_CA 369 | LC_MESSAGES 370 | .. 371 | .. 372 | en_GB 373 | LC_MESSAGES 374 | .. 375 | .. 376 | eo 377 | LC_MESSAGES 378 | .. 379 | .. 380 | es 381 | LC_MESSAGES 382 | .. 383 | .. 384 | es_ES 385 | LC_MESSAGES 386 | .. 387 | .. 388 | es_MX 389 | LC_MESSAGES 390 | .. 391 | .. 392 | et 393 | LC_MESSAGES 394 | .. 395 | .. 396 | eu 397 | LC_MESSAGES 398 | .. 399 | .. 400 | fa 401 | LC_MESSAGES 402 | .. 403 | .. 404 | fa_IR 405 | LC_MESSAGES 406 | .. 407 | .. 408 | fi 409 | LC_MESSAGES 410 | .. 411 | .. 412 | fr 413 | LC_MESSAGES 414 | .. 415 | .. 416 | fr_FR 417 | LC_MESSAGES 418 | .. 419 | .. 420 | ga 421 | LC_MESSAGES 422 | .. 423 | .. 424 | gl 425 | LC_MESSAGES 426 | .. 427 | .. 428 | gu 429 | LC_MESSAGES 430 | .. 431 | .. 432 | he 433 | LC_MESSAGES 434 | .. 435 | .. 436 | hi 437 | LC_MESSAGES 438 | .. 439 | .. 440 | hr 441 | LC_MESSAGES 442 | .. 443 | .. 444 | hu 445 | LC_MESSAGES 446 | .. 447 | .. 448 | id 449 | LC_MESSAGES 450 | .. 451 | .. 452 | is 453 | LC_MESSAGES 454 | .. 455 | .. 456 | it 457 | LC_MESSAGES 458 | .. 459 | .. 460 | ja 461 | LC_MESSAGES 462 | .. 463 | .. 464 | ka 465 | LC_MESSAGES 466 | .. 467 | .. 468 | kn 469 | LC_MESSAGES 470 | .. 471 | .. 472 | ko 473 | LC_MESSAGES 474 | .. 475 | .. 476 | li 477 | LC_MESSAGES 478 | .. 479 | .. 480 | lt 481 | LC_MESSAGES 482 | .. 483 | .. 484 | lv 485 | LC_MESSAGES 486 | .. 487 | .. 488 | mk 489 | LC_MESSAGES 490 | .. 491 | .. 492 | ml 493 | LC_MESSAGES 494 | .. 495 | .. 496 | mn 497 | LC_MESSAGES 498 | .. 499 | .. 500 | ms 501 | LC_MESSAGES 502 | .. 503 | .. 504 | mt 505 | LC_MESSAGES 506 | .. 507 | .. 508 | nb 509 | LC_MESSAGES 510 | .. 511 | .. 512 | ne 513 | LC_MESSAGES 514 | .. 515 | .. 516 | nl 517 | LC_MESSAGES 518 | .. 519 | .. 520 | nn 521 | LC_MESSAGES 522 | .. 523 | .. 524 | no 525 | LC_MESSAGES 526 | .. 527 | .. 528 | or 529 | LC_MESSAGES 530 | .. 531 | .. 532 | pa 533 | LC_MESSAGES 534 | .. 535 | .. 536 | pl 537 | LC_MESSAGES 538 | .. 539 | .. 540 | pt 541 | LC_MESSAGES 542 | .. 543 | .. 544 | pt_BR 545 | LC_MESSAGES 546 | .. 547 | .. 548 | pt_PT 549 | LC_MESSAGES 550 | .. 551 | .. 552 | ro 553 | LC_MESSAGES 554 | .. 555 | .. 556 | ru 557 | LC_MESSAGES 558 | .. 559 | .. 560 | sk 561 | LC_MESSAGES 562 | .. 563 | .. 564 | sl 565 | LC_MESSAGES 566 | .. 567 | .. 568 | sq 569 | LC_MESSAGES 570 | .. 571 | .. 572 | sr 573 | LC_MESSAGES 574 | .. 575 | .. 576 | sr@Latn 577 | LC_MESSAGES 578 | .. 579 | .. 580 | sv 581 | LC_MESSAGES 582 | .. 583 | .. 584 | ta 585 | LC_MESSAGES 586 | .. 587 | .. 588 | tg 589 | LC_MESSAGES 590 | .. 591 | .. 592 | th 593 | LC_MESSAGES 594 | .. 595 | .. 596 | tk 597 | LC_MESSAGES 598 | .. 599 | .. 600 | tr 601 | LC_MESSAGES 602 | .. 603 | .. 604 | uk 605 | LC_MESSAGES 606 | .. 607 | .. 608 | uz 609 | LC_MESSAGES 610 | .. 611 | .. 612 | vi 613 | LC_MESSAGES 614 | .. 615 | .. 616 | wa 617 | LC_MESSAGES 618 | .. 619 | .. 620 | zh 621 | LC_MESSAGES 622 | .. 623 | .. 624 | zh_CN 625 | LC_MESSAGES 626 | .. 627 | .. 628 | zh_CN.GB2312 629 | LC_MESSAGES 630 | .. 631 | .. 632 | zh_TW 633 | LC_MESSAGES 634 | .. 635 | .. 636 | zh_TW.Big5 637 | LC_MESSAGES 638 | .. 639 | .. 640 | .. 641 | misc 642 | .. 643 | nls 644 | C 645 | .. 646 | af_ZA.ISO8859-1 647 | .. 648 | af_ZA.ISO8859-15 649 | .. 650 | af_ZA.UTF-8 651 | .. 652 | am_ET.UTF-8 653 | .. 654 | be_BY.CP1131 655 | .. 656 | be_BY.CP1251 657 | .. 658 | be_BY.ISO8859-5 659 | .. 660 | be_BY.UTF-8 661 | .. 662 | bg_BG.CP1251 663 | .. 664 | bg_BG.UTF-8 665 | .. 666 | ca_ES.ISO8859-1 667 | .. 668 | ca_ES.ISO8859-15 669 | .. 670 | ca_ES.UTF-8 671 | .. 672 | cs_CZ.ISO8859-2 673 | .. 674 | cs_CZ.UTF-8 675 | .. 676 | da_DK.ISO8859-1 677 | .. 678 | da_DK.ISO8859-15 679 | .. 680 | da_DK.UTF-8 681 | .. 682 | de_AT.ISO8859-1 683 | .. 684 | de_AT.ISO8859-15 685 | .. 686 | de_AT.UTF-8 687 | .. 688 | de_CH.ISO8859-1 689 | .. 690 | de_CH.ISO8859-15 691 | .. 692 | de_CH.UTF-8 693 | .. 694 | de_DE.ISO8859-1 695 | .. 696 | de_DE.ISO8859-15 697 | .. 698 | de_DE.UTF-8 699 | .. 700 | el_GR.ISO8859-7 701 | .. 702 | el_GR.UTF-8 703 | .. 704 | en_AU.ISO8859-1 705 | .. 706 | en_AU.ISO8859-15 707 | .. 708 | en_AU.US-ASCII 709 | .. 710 | en_AU.UTF-8 711 | .. 712 | en_CA.ISO8859-1 713 | .. 714 | en_CA.ISO8859-15 715 | .. 716 | en_CA.US-ASCII 717 | .. 718 | en_CA.UTF-8 719 | .. 720 | en_GB.ISO8859-1 721 | .. 722 | en_GB.ISO8859-15 723 | .. 724 | en_GB.US-ASCII 725 | .. 726 | en_GB.UTF-8 727 | .. 728 | en_IE.UTF-8 729 | .. 730 | en_NZ.ISO8859-1 731 | .. 732 | en_NZ.ISO8859-15 733 | .. 734 | en_NZ.US-ASCII 735 | .. 736 | en_NZ.UTF-8 737 | .. 738 | en_US.ISO8859-1 739 | .. 740 | en_US.ISO8859-15 741 | .. 742 | en_US.UTF-8 743 | .. 744 | es_ES.ISO8859-1 745 | .. 746 | es_ES.ISO8859-15 747 | .. 748 | es_ES.UTF-8 749 | .. 750 | et_EE.ISO8859-15 751 | .. 752 | et_EE.UTF-8 753 | .. 754 | fi_FI.ISO8859-1 755 | .. 756 | fi_FI.ISO8859-15 757 | .. 758 | fi_FI.UTF-8 759 | .. 760 | fr_BE.ISO8859-1 761 | .. 762 | fr_BE.ISO8859-15 763 | .. 764 | fr_BE.UTF-8 765 | .. 766 | fr_CA.ISO8859-1 767 | .. 768 | fr_CA.ISO8859-15 769 | .. 770 | fr_CA.UTF-8 771 | .. 772 | fr_CH.ISO8859-1 773 | .. 774 | fr_CH.ISO8859-15 775 | .. 776 | fr_CH.UTF-8 777 | .. 778 | fr_FR.ISO8859-1 779 | .. 780 | fr_FR.ISO8859-15 781 | .. 782 | fr_FR.UTF-8 783 | .. 784 | he_IL.UTF-8 785 | .. 786 | hi_IN.ISCII-DEV 787 | .. 788 | hr_HR.ISO8859-2 789 | .. 790 | hr_HR.UTF-8 791 | .. 792 | hu_HU.ISO8859-2 793 | .. 794 | hu_HU.UTF-8 795 | .. 796 | hy_AM.ARMSCII-8 797 | .. 798 | hy_AM.UTF-8 799 | .. 800 | is_IS.ISO8859-1 801 | .. 802 | is_IS.ISO8859-15 803 | .. 804 | is_IS.UTF-8 805 | .. 806 | it_CH.ISO8859-1 807 | .. 808 | it_CH.ISO8859-15 809 | .. 810 | it_CH.UTF-8 811 | .. 812 | it_IT.ISO8859-1 813 | .. 814 | it_IT.ISO8859-15 815 | .. 816 | it_IT.UTF-8 817 | .. 818 | ja_JP.SJIS 819 | .. 820 | ja_JP.UTF-8 821 | .. 822 | ja_JP.eucJP 823 | .. 824 | kk_KZ.PT154 825 | .. 826 | kk_KZ.UTF-8 827 | .. 828 | ko_KR.CP949 829 | .. 830 | ko_KR.UTF-8 831 | .. 832 | ko_KR.eucKR 833 | .. 834 | la_LN.ISO8859-1 835 | .. 836 | la_LN.ISO8859-15 837 | .. 838 | la_LN.ISO8859-2 839 | .. 840 | la_LN.ISO8859-4 841 | .. 842 | la_LN.US-ASCII 843 | .. 844 | lt_LT.ISO8859-13 845 | .. 846 | lt_LT.ISO8859-4 847 | .. 848 | lt_LT.UTF-8 849 | .. 850 | nl_BE.ISO8859-1 851 | .. 852 | nl_BE.ISO8859-15 853 | .. 854 | nl_BE.UTF-8 855 | .. 856 | nl_NL.ISO8859-1 857 | .. 858 | nl_NL.ISO8859-15 859 | .. 860 | nl_NL.UTF-8 861 | .. 862 | no_NO.ISO8859-1 863 | .. 864 | no_NO.ISO8859-15 865 | .. 866 | no_NO.UTF-8 867 | .. 868 | pl_PL.ISO8859-2 869 | .. 870 | pl_PL.UTF-8 871 | .. 872 | pt_BR.ISO8859-1 873 | .. 874 | pt_BR.UTF-8 875 | .. 876 | pt_PT.ISO8859-1 877 | .. 878 | pt_PT.ISO8859-15 879 | .. 880 | pt_PT.UTF-8 881 | .. 882 | ro_RO.ISO8859-2 883 | .. 884 | ro_RO.UTF-8 885 | .. 886 | ru_RU.CP1251 887 | .. 888 | ru_RU.CP866 889 | .. 890 | ru_RU.ISO8859-5 891 | .. 892 | ru_RU.KOI8-R 893 | .. 894 | ru_RU.UTF-8 895 | .. 896 | sk_SK.ISO8859-2 897 | .. 898 | sk_SK.UTF-8 899 | .. 900 | sl_SI.ISO8859-2 901 | .. 902 | sl_SI.UTF-8 903 | .. 904 | sr_YU.ISO8859-2 905 | .. 906 | sr_YU.ISO8859-5 907 | .. 908 | sr_YU.UTF-8 909 | .. 910 | sv_SE.ISO8859-1 911 | .. 912 | sv_SE.ISO8859-15 913 | .. 914 | sv_SE.UTF-8 915 | .. 916 | tr_TR.ISO8859-9 917 | .. 918 | tr_TR.UTF-8 919 | .. 920 | uk_UA.ISO8859-5 921 | .. 922 | uk_UA.KOI8-U 923 | .. 924 | uk_UA.UTF-8 925 | .. 926 | zh_CN.GB18030 927 | .. 928 | zh_CN.GB2312 929 | .. 930 | zh_CN.GBK 931 | .. 932 | zh_CN.UTF-8 933 | .. 934 | zh_CN.eucCN 935 | .. 936 | zh_HK.Big5HKSCS 937 | .. 938 | zh_HK.UTF-8 939 | .. 940 | zh_TW.Big5 941 | .. 942 | zh_TW.UTF-8 943 | .. 944 | .. 945 | pixmaps 946 | .. 947 | sgml 948 | .. 949 | skel 950 | .. 951 | xml 952 | .. 953 | .. 954 | www 955 | .. 956 | .. 957 | --------------------------------------------------------------------------------