pdns-recursor: add package 9230/head
authorJames Taylor <james@jtaylor.id.au>
Fri, 14 Jun 2019 11:08:38 +0000 (21:08 +1000)
committerJames Taylor <james@jtaylor.id.au>
Wed, 3 Jul 2019 11:19:30 +0000 (21:19 +1000)
Maintainer: me

Compile tested: armv7l, OpenWRT SDK
Run tested: armv7l Linksys WRT1900ACS, OpenWrt SNAPSHOT, r9987-655fff1571 -
confirmed PowerDNS recursor links correctly against libraries and runs on my
target environment.

Description:
PowerDNS Recursor is a high-performance resolving name server, utilizing
multiple processor and including Lua scripting capabilities.

This commit includes the recursive nameserver

https://www.powerdns.com/recursor.html

Signed-off-by: James Taylor <james@jtaylor.id.au>
net/pdns-recursor/Makefile [new file with mode: 0644]
net/pdns-recursor/files/pdns-recursor.init [new file with mode: 0644]
net/pdns-recursor/files/recursor.conf-dist [new file with mode: 0644]
net/pdns-recursor/patches/100-disable-recursor.conf-dist.patch [new file with mode: 0644]
net/pdns-recursor/patches/200-libatomic-detect.patch [new file with mode: 0644]
net/pdns-recursor/patches/300-gen-version.patch [new file with mode: 0644]

diff --git a/net/pdns-recursor/Makefile b/net/pdns-recursor/Makefile
new file mode 100644 (file)
index 0000000..f7cc879
--- /dev/null
@@ -0,0 +1,62 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=pdns-recursor
+PKG_VERSION:=4.1.14
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/
+PKG_HASH:=7fceb8fa3bea693aad49d137c801bb3ecc15525cc5a7dc84380321546e87bf14
+
+PKG_MAINTAINER:=James Taylor <james@jtaylor.id.au>
+PKG_LICENCE:=GPL-2.0-only
+PKG_LICENCE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:powerdns:recursor
+
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/pdns-recursor
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=IP Addresses and Names
+  USERID:=pdns:pdns
+  TITLE:=PowerDNS Recursor
+  DEPENDS:=+boost +boost-context +libatomic +liblua +libopenssl +protobuf
+  URL:=https://www.powerdns.com/recursor.html
+endef
+
+define Package/pdns-recursor/description
+  High-performance resolving name server, utilizing multiple
+  processor and including Lua scripting capabilities.
+endef
+
+define Package/pdns-recursor/conffiles
+/etc/powerdns/pdns-recursor.conf
+/etc/init.d/pdns-recursor
+endef
+
+CONFIGURE_ARGS+= \
+       --sysconfdir=/etc/powerdns \
+       --with-lua \
+       --without-luajit \
+       --disable-libsodium \
+       --with-protobuf \
+       --without-net-snmp \
+       --disable-silent-rules
+
+define Package/pdns-recursor/install
+       $(INSTALL_DIR) $(1)/etc/powerdns
+       $(INSTALL_CONF) ./files/recursor.conf-dist $(1)/etc/powerdns/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/pdns-recursor.init $(1)/etc/init.d/pdns-recursor
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rec_control $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pdns_recursor $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,pdns-recursor))
diff --git a/net/pdns-recursor/files/pdns-recursor.init b/net/pdns-recursor/files/pdns-recursor.init
new file mode 100644 (file)
index 0000000..26fbea1
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh /etc/rc.common
+START=99
+
+USE_PROCD=1
+
+start_service() {
+       [ -e /etc/powerdns/recursor.conf ] || return 1
+
+       procd_open_instance
+       procd_set_param command /usr/sbin/pdns_recursor --daemon=no
+       procd_set_param file /etc/powerdns/recursor.conf
+       procd_set_param respawn
+       procd_close_instance
+}
diff --git a/net/pdns-recursor/files/recursor.conf-dist b/net/pdns-recursor/files/recursor.conf-dist
new file mode 100644 (file)
index 0000000..d30e238
--- /dev/null
@@ -0,0 +1,560 @@
+# Autogenerated configuration file template
+#################################
+# allow-from   If set, only allow these comma separated netmasks to recurse
+#
+# allow-from=127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10
+
+#################################
+# allow-from-file      If set, load allowed netmasks from this file
+#
+# allow-from-file=
+
+#################################
+# any-to-tcp   Answer ANY queries with tc=1, shunting to TCP
+#
+# any-to-tcp=no
+
+#################################
+# api-config-dir       Directory where REST API stores config and zones
+#
+# api-config-dir=
+
+#################################
+# api-key      Static pre-shared authentication key for access to the REST API
+#
+# api-key=
+
+#################################
+# api-logfile  Location of the server logfile (used by the REST API)
+#
+# api-logfile=/var/log/pdns.log
+
+#################################
+# api-readonly Disallow data modification through the REST API when set
+#
+# api-readonly=no
+
+#################################
+# auth-zones   Zones for which we have authoritative data, comma separated domain=file pairs 
+#
+# auth-zones=
+
+#################################
+# carbon-interval      Number of seconds between carbon (graphite) updates
+#
+# carbon-interval=30
+
+#################################
+# carbon-ourname       If set, overrides our reported hostname for carbon stats
+#
+# carbon-ourname=
+
+#################################
+# carbon-server        If set, send metrics in carbon (graphite) format to this server IP address
+#
+# carbon-server=
+
+#################################
+# chroot       switch to chroot jail
+#
+# chroot=
+
+#################################
+# client-tcp-timeout   Timeout in seconds when talking to TCP clients
+#
+# client-tcp-timeout=2
+
+#################################
+# config-dir   Location of configuration directory (recursor.conf)
+#
+# config-dir=/usr/local/etc
+
+#################################
+# config-name  Name of this virtual configuration - will rename the binary image
+#
+# config-name=
+
+#################################
+# cpu-map      Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs
+#
+# cpu-map=
+
+#################################
+# daemon       Operate as a daemon
+#
+# daemon=no
+
+#################################
+# delegation-only      Which domains we only accept delegations from
+#
+# delegation-only=
+
+#################################
+# disable-packetcache  Disable packetcache
+#
+# disable-packetcache=no
+
+#################################
+# disable-real-memory-usage    Disable expensive real-memory-usage metric
+#
+# disable-real-memory-usage=no
+
+#################################
+# disable-syslog       Disable logging to syslog, useful when running inside a supervisor that logs stdout
+#
+# disable-syslog=no
+
+#################################
+# distribution-load-factor     The load factor used when PowerDNS is distributing queries to worker threads
+#
+# distribution-load-factor=0.0
+
+#################################
+# dnssec       DNSSEC mode: off/process-no-validate (default)/process/log-fail/validate
+#
+# dnssec=process-no-validate
+
+#################################
+# dnssec-log-bogus     Log DNSSEC bogus validations
+#
+# dnssec-log-bogus=no
+
+#################################
+# dont-query   If set, do not query these netmasks for DNS data
+#
+# dont-query=127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32
+
+#################################
+# ecs-cache-limit-ttl  Minimum TTL to cache ECS response
+#
+# ecs-cache-limit-ttl=0
+
+#################################
+# ecs-ipv4-bits        Number of bits of IPv4 address to pass for EDNS Client Subnet
+#
+# ecs-ipv4-bits=24
+
+#################################
+# ecs-ipv4-cache-bits  Maximum number of bits of IPv4 mask to cache ECS response
+#
+# ecs-ipv4-cache-bits=24
+
+#################################
+# ecs-ipv6-bits        Number of bits of IPv6 address to pass for EDNS Client Subnet
+#
+# ecs-ipv6-bits=56
+
+#################################
+# ecs-ipv6-cache-bits  Maximum number of bits of IPv6 mask to cache ECS response
+#
+# ecs-ipv6-cache-bits=56
+
+#################################
+# ecs-scope-zero-address       Address to send to whitelisted authoritative servers for incoming queries with ECS prefix-length source of 0
+#
+# ecs-scope-zero-address=
+
+#################################
+# edns-outgoing-bufsize        Outgoing EDNS buffer size
+#
+# edns-outgoing-bufsize=1680
+
+#################################
+# edns-subnet-whitelist        List of netmasks and domains that we should enable EDNS subnet for
+#
+# edns-subnet-whitelist=
+
+#################################
+# entropy-source       If set, read entropy from this file
+#
+# entropy-source=/dev/urandom
+
+#################################
+# etc-hosts-file       Path to 'hosts' file
+#
+# etc-hosts-file=/etc/hosts
+
+#################################
+# export-etc-hosts     If we should serve up contents from /etc/hosts
+#
+# export-etc-hosts=off
+
+#################################
+# export-etc-hosts-search-suffix       Also serve up the contents of /etc/hosts with this suffix
+#
+# export-etc-hosts-search-suffix=
+
+#################################
+# forward-zones        Zones for which we forward queries, comma separated domain=ip pairs
+#
+# forward-zones=
+
+#################################
+# forward-zones-file   File with (+)domain=ip pairs for forwarding
+#
+# forward-zones-file=
+
+#################################
+# forward-zones-recurse        Zones for which we forward queries with recursion bit, comma separated domain=ip pairs
+#
+# forward-zones-recurse=
+
+#################################
+# gettag-needs-edns-options    If EDNS Options should be extracted before calling the gettag() hook
+#
+# gettag-needs-edns-options=no
+
+#################################
+# hint-file    If set, load root hints from this file
+#
+# hint-file=
+
+#################################
+# include-dir  Include *.conf files from this directory
+#
+# include-dir=
+
+#################################
+# latency-statistic-size       Number of latency values to calculate the qa-latency average
+#
+# latency-statistic-size=10000
+
+#################################
+# local-address        IP addresses to listen on, separated by spaces or commas. Also accepts ports.
+#
+# local-address=127.0.0.1
+
+#################################
+# local-port   port to listen on
+#
+# local-port=53
+
+#################################
+# log-common-errors    If we should log rather common errors
+#
+# log-common-errors=no
+
+#################################
+# log-rpz-changes      Log additions and removals to RPZ zones at Info level
+#
+# log-rpz-changes=no
+
+#################################
+# log-timestamp        Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already
+#
+# log-timestamp=yes
+
+#################################
+# logging-facility     Facility to log messages as. 0 corresponds to local0
+#
+# logging-facility=
+
+#################################
+# loglevel     Amount of logging. Higher is more. Do not set below 3
+#
+# loglevel=6
+
+#################################
+# lowercase-outgoing   Force outgoing questions to lowercase
+#
+# lowercase-outgoing=no
+
+#################################
+# lua-config-file      More powerful configuration options
+#
+# lua-config-file=
+
+#################################
+# lua-dns-script       Filename containing an optional 'lua' script that will be used to modify dns answers
+#
+# lua-dns-script=
+
+#################################
+# max-cache-entries    If set, maximum number of entries in the main cache
+#
+# max-cache-entries=1000000
+
+#################################
+# max-cache-ttl        maximum number of seconds to keep a cached entry in memory
+#
+# max-cache-ttl=86400
+
+#################################
+# max-mthreads Maximum number of simultaneous Mtasker threads
+#
+# max-mthreads=2048
+
+#################################
+# max-negative-ttl     maximum number of seconds to keep a negative cached entry in memory
+#
+# max-negative-ttl=3600
+
+#################################
+# max-packetcache-entries      maximum number of entries to keep in the packetcache
+#
+# max-packetcache-entries=500000
+
+#################################
+# max-qperq    Maximum outgoing queries per query
+#
+# max-qperq=50
+
+#################################
+# max-recursion-depth  Maximum number of internal recursion calls per query, 0 for unlimited
+#
+# max-recursion-depth=40
+
+#################################
+# max-tcp-clients      Maximum number of simultaneous TCP clients
+#
+# max-tcp-clients=128
+
+#################################
+# max-tcp-per-client   If set, maximum number of TCP sessions per client (IP address)
+#
+# max-tcp-per-client=0
+
+#################################
+# max-tcp-queries-per-connection       If set, maximum number of TCP queries in a TCP connection
+#
+# max-tcp-queries-per-connection=0
+
+#################################
+# max-total-msec       Maximum total wall-clock time per query in milliseconds, 0 for unlimited
+#
+# max-total-msec=7000
+
+#################################
+# max-udp-queries-per-round    Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing
+#
+# max-udp-queries-per-round=10000
+
+#################################
+# minimum-ttl-override Set under adverse conditions, a minimum TTL
+#
+# minimum-ttl-override=0
+
+#################################
+# network-timeout      Wait this number of milliseconds for network i/o
+#
+# network-timeout=1500
+
+#################################
+# no-shuffle   Don't change
+#
+# no-shuffle=off
+
+#################################
+# non-local-bind       Enable binding to non-local addresses by using FREEBIND / BINDANY socket options
+#
+# non-local-bind=no
+
+#################################
+# nsec3-max-iterations Maximum number of iterations allowed for an NSEC3 record
+#
+# nsec3-max-iterations=2500
+
+#################################
+# packetcache-servfail-ttl     maximum number of seconds to keep a cached servfail entry in packetcache
+#
+# packetcache-servfail-ttl=60
+
+#################################
+# packetcache-ttl      maximum number of seconds to keep a cached entry in packetcache
+#
+# packetcache-ttl=3600
+
+#################################
+# pdns-distributes-queries     If PowerDNS itself should distribute queries over threads
+#
+# pdns-distributes-queries=yes
+
+#################################
+# processes    Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)
+#
+# processes=1
+
+#################################
+# query-local-address  Source IP address for sending queries
+#
+# query-local-address=0.0.0.0
+
+#################################
+# query-local-address6 Source IPv6 address for sending queries. IF UNSET, IPv6 WILL NOT BE USED FOR OUTGOING QUERIES
+#
+# query-local-address6=
+
+#################################
+# quiet        Suppress logging of questions and answers
+#
+# quiet=
+
+#################################
+# reuseport    Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address
+#
+# reuseport=no
+
+#################################
+# root-nx-trust        If set, believe that an NXDOMAIN from the root means the TLD does not exist
+#
+# root-nx-trust=yes
+
+#################################
+# security-poll-suffix Domain name from which to query security update notifications
+#
+# security-poll-suffix=secpoll.powerdns.com.
+
+#################################
+# serve-rfc1918        If we should be authoritative for RFC 1918 private IP space
+#
+# serve-rfc1918=yes
+
+#################################
+# server-down-max-fails        Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )
+#
+# server-down-max-fails=64
+
+#################################
+# server-down-throttle-time    Number of seconds to throttle all queries to a server after being marked as down
+#
+# server-down-throttle-time=60
+
+#################################
+# server-id    Returned when queried for 'id.server' TXT or NSID, defaults to hostname
+#
+# server-id=
+
+#################################
+# setgid       If set, change group id to this gid for more security
+#
+# setgid=
+
+#################################
+# setuid       If set, change user id to this uid for more security
+#
+# setuid=
+
+#################################
+# signature-inception-skew     Allow the signture inception to be off by this number of seconds
+#
+# signature-inception-skew=0
+
+#################################
+# single-socket        If set, only use a single socket for outgoing queries
+#
+# single-socket=off
+
+#################################
+# snmp-agent   If set, register as an SNMP agent
+#
+# snmp-agent=no
+
+#################################
+# snmp-master-socket   If set and snmp-agent is set, the socket to use to register to the SNMP master
+#
+# snmp-master-socket=
+
+#################################
+# soa-minimum-ttl      Don't change
+#
+# soa-minimum-ttl=0
+
+#################################
+# socket-dir   Where the controlsocket will live, /var/run when unset and not chrooted
+#
+# socket-dir=
+
+#################################
+# socket-group Group of socket
+#
+# socket-group=
+
+#################################
+# socket-mode  Permissions for socket
+#
+# socket-mode=
+
+#################################
+# socket-owner Owner of socket
+#
+# socket-owner=
+
+#################################
+# spoof-nearmiss-max   If non-zero, assume spoofing after this many near misses
+#
+# spoof-nearmiss-max=20
+
+#################################
+# stack-size   stack size per mthread
+#
+# stack-size=200000
+
+#################################
+# statistics-interval  Number of seconds between printing of recursor statistics, 0 to disable
+#
+# statistics-interval=1800
+
+#################################
+# stats-ringbuffer-entries     maximum number of packets to store statistics for
+#
+# stats-ringbuffer-entries=10000
+
+#################################
+# tcp-fast-open        Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size
+#
+# tcp-fast-open=0
+
+#################################
+# threads      Launch this number of threads
+#
+# threads=2
+
+#################################
+# trace        if we should output heaps of logging. set to 'fail' to only log failing domains
+#
+# trace=off
+
+#################################
+# udp-truncation-threshold     Maximum UDP response size before we truncate
+#
+# udp-truncation-threshold=1680
+
+#################################
+# use-incoming-edns-subnet     Pass along received EDNS Client Subnet information
+#
+# use-incoming-edns-subnet=no
+
+#################################
+# version-string       string reported on version.pdns or version.bind
+#
+# version-string=PowerDNS Recursor 4.1.13 (built Jun 14 2019 10:58:59 by xreaper@nimbus.for-no-reason.net)
+
+#################################
+# webserver    Start a webserver (for REST API)
+#
+# webserver=no
+
+#################################
+# webserver-address    IP Address of webserver to listen on
+#
+# webserver-address=127.0.0.1
+
+#################################
+# webserver-allow-from Webserver access is only allowed from these subnets
+#
+# webserver-allow-from=127.0.0.1,::1
+
+#################################
+# webserver-password   Password required for accessing the webserver
+#
+# webserver-password=
+
+#################################
+# webserver-port       Port of webserver to listen on
+#
+# webserver-port=8082
+
+#################################
+# write-pid    Write a PID file
+#
+# write-pid=yes
diff --git a/net/pdns-recursor/patches/100-disable-recursor.conf-dist.patch b/net/pdns-recursor/patches/100-disable-recursor.conf-dist.patch
new file mode 100644 (file)
index 0000000..6bd1a0d
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -357,12 +357,6 @@
+ pubsuffix.cc: $(srcdir)/effective_tld_names.dat
+       $(AM_V_GEN)./mkpubsuffixcc
+
+-## Config file
+-sysconf_DATA = recursor.conf-dist
+-
+-recursor.conf-dist: pdns_recursor
+-      $(AM_V_GEN)./pdns_recursor --config > $@
+-
+ ## Manpages
+ MANPAGES=pdns_recursor.1 \
+        rec_control.1
diff --git a/net/pdns-recursor/patches/200-libatomic-detect.patch b/net/pdns-recursor/patches/200-libatomic-detect.patch
new file mode 100644 (file)
index 0000000..29881cc
--- /dev/null
@@ -0,0 +1,34 @@
+--- a/m4/pdns_check_os.m4
++++ b/m4/pdns_check_os.m4
+@@ -35,16 +35,21 @@
+   AM_CONDITIONAL([HAVE_LINUX], [test "x$have_linux" = "xyes"])
+   AM_CONDITIONAL([HAVE_SOLARIS], [test "x$have_solaris" = "xyes"])
+
+-  case "$host" in
+-  mips* | powerpc-* )
+-    AC_MSG_CHECKING([whether the linker accepts -latomic])
+-    LDFLAGS="-latomic $LDFLAGS"
+-    AC_LINK_IFELSE([m4_default([],[AC_LANG_PROGRAM()])],
+-      [AC_MSG_RESULT([yes])],
+-      [AC_MSG_ERROR([Unable to link against libatomic, cannot continue])]
+-    )
+-    ;;
+-  esac
++  AC_MSG_CHECKING([whether -latomic is needed for __atomic builtins])
++  AC_LINK_IFELSE(
++    [AC_LANG_PROGRAM([[#include <stdint.h>]],
++       [[uint64_t val = 0; __atomic_add_fetch(&val, 1, __ATOMIC_RELAXED);]]
++    )],
++    [AC_MSG_RESULT([no])],
++    [LIBS="$LIBS -latomic"
++     AC_LINK_IFELSE(
++       [AC_LANG_PROGRAM([[#include <stdint.h>]],
++               [[uint64_t val = 0; __atomic_add_fetch(&val, 1, __ATOMIC_RELAXED);]]
++       )],
++       [AC_MSG_RESULT([yes])],
++       [AC_MSG_FAILURE([libatomic needed, but linking with -latomic failed, cannot continue])]
++    )]
++  )
+
+   AC_SUBST(THREADFLAGS)
+   AC_SUBST([DYNLINKFLAGS], [-export-dynamic])
diff --git a/net/pdns-recursor/patches/300-gen-version.patch b/net/pdns-recursor/patches/300-gen-version.patch
new file mode 100644 (file)
index 0000000..52d138f
--- /dev/null
@@ -0,0 +1,43 @@
+--- a/build-aux/gen-version
++++ b/build-aux/gen-version
+@@ -1,39 +1,4 @@
+ #!/bin/sh
+-VERSION="unknown"
+-
+-DIRTY=""
+-git status | grep -q clean || DIRTY='.dirty'
+-
+-# Special environment variable to signal that we are building a release, as this
+-# has consequences for the version number.
+-if [ "${IS_RELEASE}" = "YES" ]; then
+-  TAG="$(git describe --tags --exact-match 2> /dev/null | cut -d- -f 2-)"
+-  if [ -n "${TAG}" ]; then
+-    # We're on a tag
+-    echo "${TAG}${DIRTY}" > .version
+-    printf "${TAG}${DIRTY}"
+-    exit 0
+-  fi
+-  echo 'This is not a tag, either tag this commit or do not set $IS_RELEASE' >&2
+-  exit 1
+-fi
+-
+-#
+-# Generate the version number based on the branch
+-#
+-if [ ! -z "$(git rev-parse --abbrev-ref HEAD 2> /dev/null)" ]; then
+-  if $(git rev-parse --abbrev-ref HEAD | grep -q 'rel/'); then
+-    REL_TYPE="$(git rev-parse --abbrev-ref HEAD | cut -d/ -f 2 | cut -d- -f 1)"
+-    VERSION="$(git describe --match=${REL_TYPE}-* --tags --dirty=.dirty | cut -d- -f 2-)"
+-  else
+-    GIT_VERSION=$(git show --no-patch --format=format:%h HEAD)
+-    BRANCH=".$(git rev-parse --abbrev-ref HEAD | perl -p -e 's/[^[:alnum:]]//g;')"
+-    [ "${BRANCH}" = ".master" ] && BRANCH=''
+-    VERSION="0.0${BRANCH}.${PDNS_BUILD_NUMBER}g${GIT_VERSION}${DIRTY}"
+-  fi
+-  echo "$VERSION" > .version
+-elif [ -f .version ]; then
+-  VERSION="$(cat .version)"
+-fi
++VERSION="$(cat .version)"
+
+ printf $VERSION