A few updates:

- Re-enabling support for ARM builds in `build.py`.
- Improved `build.py`'s iteration and package version.
- Fixed minor bug with logrotate file path in `build.py`.
- Improved installation pre and post install/uninstall scripts by adding distribution-specific logic to account for quirks between the different package managers.
- Added post-install as post-trans script for RPM builds due to the order of RPM upgrade commands (issue where init scripts were removed when upgrading).
- Added explicit backup to pre-install script to ensure legacy configuration survive an upgrade.
pull/4948/head
Ross McDonald 2015-11-24 17:53:48 -06:00
parent bd63489ef0
commit 560f691096
4 changed files with 178 additions and 104 deletions

116
build.py
View File

@ -3,7 +3,6 @@
# This is the InfluxDB build script.
#
# Current caveats:
# - Does not currently build ARM builds/packages
# - Does not checkout the correct commit/branch (for now, you will need to do so manually)
# - Has external dependencies for packaging (fpm) and uploading (boto)
#
@ -43,9 +42,9 @@ DEFAULT_CONFIG = "etc/config.sample.toml"
# META-PACKAGE VARIABLES
PACKAGE_LICENSE = "MIT"
PACKAGE_URL = "https://github.com/influxdb/influxdb"
MAINTAINER = "InfluxData"
MAINTAINER = "support@influxdb.com"
VENDOR = "InfluxData"
DESCRIPTION = "A distributed time-series database."
DESCRIPTION = "Distributed time-series database."
# SCRIPT START
prereqs = [ 'git', 'go' ]
@ -61,34 +60,37 @@ fpm_common_args = "-f -s dir --log error \
--maintainer {} \
--config-files {} \
--config-files {} \
--directories {} \
--directories {} \
--description \"{}\"".format(
VENDOR,
PACKAGE_URL,
POSTINST_SCRIPT,
PREINST_SCRIPT,
POSTUNINST_SCRIPT,
PACKAGE_LICENSE,
MAINTAINER,
CONFIG_DIR,
LOGROTATE_DIR,
DESCRIPTION)
VENDOR,
PACKAGE_URL,
POSTINST_SCRIPT,
PREINST_SCRIPT,
POSTUNINST_SCRIPT,
PACKAGE_LICENSE,
MAINTAINER,
CONFIG_DIR + '/influxdb.conf',
LOGROTATE_DIR + '/influxdb',
LOG_DIR,
DATA_DIR,
DESCRIPTION)
targets = {
'influx' : './cmd/influx/main.go',
'influxd' : './cmd/influxd/main.go',
'influx_stress' : './cmd/influx_stress/influx_stress.go',
'influx_inspect' : './cmd/influx_inspect/*.go',
'influx_tsm' : './cmd/influx_tsm/main.go',
'influx_tsm' : './cmd/influx_tsm/*.go',
}
supported_builds = {
# TODO(rossmcdonald): Add support for multiple GOARM values
'darwin': [ "amd64", "386" ],
# Windows is not currently supported in InfluxDB 0.9.5 due to use of mmap
# 'windows': [ "amd64", "386", "arm" ],
'linux': [ "amd64", "386", "arm" ]
}
supported_go = [ '1.5.1', '1.4.2' ]
supported_packages = {
"darwin": [ "tar", "zip" ],
"linux": [ "deb", "rpm", "tar", "zip" ],
@ -103,18 +105,20 @@ def run(command, allow_failure=False, shell=False):
else:
out = subprocess.check_output(command.split(), stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print ""
print ""
print "Executed command failed!"
print "-- Command run was: {}".format(command)
print "-- Failure was: {}".format(e.output)
if allow_failure:
print "Continuing..."
return out
return None
else:
print ""
print "Stopping."
sys.exit(1)
except OSError as e:
print ""
print ""
print "Invalid command!"
print "-- Command run was: {}".format(command)
@ -152,7 +156,10 @@ def get_current_branch():
return out.strip()
def get_system_arch():
return os.uname()[4]
arch = os.uname()[4]
if arch == "x86_64":
arch = "amd64"
return arch
def get_system_platform():
if sys.platform.startswith("linux"):
@ -179,12 +186,12 @@ def check_path_for(b):
def check_environ(build_dir = None):
print "\nChecking environment:"
for v in [ "GOPATH", "GOBIN" ]:
for v in [ "GOPATH", "GOBIN", "GOROOT" ]:
print "\t- {} -> {}".format(v, os.environ.get(v))
cwd = os.getcwd()
if build_dir == None and os.environ.get("GOPATH") and os.environ.get("GOPATH") not in cwd:
print "\n!! WARNING: Your current directory is not under your GOPATH! This probably won't work."
print "\n!! WARNING: Your current directory is not under your GOPATH. This may lead to build failures."
def check_prereqs():
print "\nChecking for dependencies:"
@ -282,7 +289,8 @@ def build(version=None,
rc=None,
race=False,
clean=False,
outdir="."):
outdir=".",
goarm_version="6"):
print "-------------------------"
print ""
print "Build plan:"
@ -293,6 +301,8 @@ def build(version=None,
print "\t- branch: {}".format(branch)
print "\t- platform: {}".format(platform)
print "\t- arch: {}".format(arch)
if arch == 'arm' and goarm_version:
print "\t- ARM version: {}".format(goarm_version)
print "\t- nightly? {}".format(str(nightly).lower())
print "\t- race enabled? {}".format(str(race).lower())
print ""
@ -312,10 +322,11 @@ def build(version=None,
for b, c in targets.iteritems():
print "\t- Building '{}'...".format(os.path.join(outdir, b)),
build_command = ""
build_command += "GOOS={} GOOARCH={} ".format(platform, arch)
if arch == "arm":
# TODO(rossmcdonald): Add GOARM variables for ARM builds
build_command += "GOOARM={} ".format(6)
build_command += "GOOS={} GOARCH={} ".format(platform, arch)
if arch == "arm" and goarm_version:
if goarm_version not in ["5", "6", "7", "arm64"]:
print "!! Invalid ARM build version: {}".format(goarm_version)
build_command += "GOARM={} ".format(goarm_version)
build_command += "go build -o {} ".format(os.path.join(outdir, b))
if race:
build_command += "-race "
@ -331,7 +342,7 @@ def build(version=None,
build_command += "-X main.branch={} ".format(branch)
build_command += "-X main.commit={}\" ".format(get_current_commit())
build_command += c
out = run(build_command, shell=True)
run(build_command, shell=True)
print "[ DONE ]"
print ""
@ -373,8 +384,8 @@ def package_scripts(build_root):
os.chmod(os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1]), 0644)
shutil.copyfile(SYSTEMD_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], SYSTEMD_SCRIPT.split('/')[1]))
os.chmod(os.path.join(build_root, SCRIPT_DIR[1:], SYSTEMD_SCRIPT.split('/')[1]), 0644)
shutil.copyfile(LOGROTATE_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], LOGROTATE_SCRIPT.split('/')[1]))
os.chmod(os.path.join(build_root, SCRIPT_DIR[1:], LOGROTATE_SCRIPT.split('/')[1]), 0644)
shutil.copyfile(LOGROTATE_SCRIPT, os.path.join(build_root, LOGROTATE_DIR[1:], "influxdb"))
os.chmod(os.path.join(build_root, LOGROTATE_DIR[1:], "influxdb"), 0644)
shutil.copyfile(DEFAULT_CONFIG, os.path.join(build_root, CONFIG_DIR[1:], "influxdb.conf"))
os.chmod(os.path.join(build_root, CONFIG_DIR[1:], "influxdb.conf"), 0644)
@ -426,6 +437,8 @@ def build_packages(build_output, version, nightly=False, rc=None, iteration=1):
for package_type in supported_packages[p]:
print "\t- Packaging directory '{}' as '{}'...".format(build_root, package_type),
name = "influxdb"
package_version = version
package_iteration = iteration
if package_type in ['zip', 'tar']:
if nightly:
name = '{}-nightly_{}_{}'.format(name, p, a)
@ -434,25 +447,19 @@ def build_packages(build_output, version, nightly=False, rc=None, iteration=1):
if package_type == 'tar':
# Add `tar.gz` to path to ensure a small package size
current_location = os.path.join(current_location, name + '.tar.gz')
if package_type == 'deb' and rc:
# For debs with an RC, just append to version number
version += "-rc{}".format(rc)
fpm_command = "fpm {} --name {} -a {} -t {} --version {} -C {} -p {} ".format(
if rc is not None:
package_iteration = "0.rc{}".format(rc)
fpm_command = "fpm {} --name {} -a {} -t {} --version {} --iteration {} -C {} -p {} ".format(
fpm_common_args,
name,
a,
package_type,
version,
package_version,
package_iteration,
build_root,
current_location)
if package_type == "rpm":
fpm_command += "--depends coreutils "
# For rpms with RC, add to iteration for adherence to Fedora packaging standard:
# http://fedoraproject.org/wiki/Packaging%3aNamingGuidelines#NonNumericRelease
if rc:
fpm_command += "--iteration 0.{}.rc{} ".format(iteration, rc)
else:
fpm_command += "--iteration 1 ".format(iteration)
fpm_command += "--depends coreutils --rpm-posttrans {}".format(POSTINST_SCRIPT)
out = run(fpm_command, shell=True)
matches = re.search(':path=>"(.*)"', out)
outfile = None
@ -462,10 +469,8 @@ def build_packages(build_output, version, nightly=False, rc=None, iteration=1):
print "[ COULD NOT DETERMINE OUTPUT ]"
else:
# Strip nightly version (the unix epoch) from filename
if nightly and package_type == 'deb':
outfile = rename_file(outfile, outfile.replace("{}".format(version), "nightly"))
elif nightly and package_type == 'rpm':
outfile = rename_file(outfile, outfile.replace("{}-1".format(version), "nightly"))
if nightly and package_type in ['deb', 'rpm']:
outfile = rename_file(outfile, outfile.replace("{}-{}".format(version, iteration), "nightly"))
outfiles.append(os.path.join(os.getcwd(), outfile))
print "[ DONE ]"
# Display MD5 hash for generated package
@ -482,18 +487,20 @@ def print_usage():
print "Options:"
print "\t --outdir=<path> \n\t\t- Send build output to a specified path. Defaults to ./build."
print "\t --arch=<arch> \n\t\t- Build for specified architecture. Acceptable values: x86_64|amd64, 386, arm, or all"
print "\t --goarm=<arm version> \n\t\t- Build for specified ARM version (when building for ARM). Default value is: 6"
print "\t --platform=<platform> \n\t\t- Build for specified platform. Acceptable values: linux, windows, darwin, or all"
print "\t --version=<version> \n\t\t- Version information to apply to build metadata. If not specified, will be pulled from repo tag."
print "\t --commit=<commit> \n\t\t- Use specific commit for build (currently a NOOP)."
print "\t --branch=<branch> \n\t\t- Build from a specific branch (currently a NOOP)."
print "\t --rc=<rc number> \n\t\t- Whether or not the build is a release candidate (affects version information)."
print "\t --iteration=<iteration number> \n\t\t- The iteration to display on the package output (defaults to 0 for RC's, and 1 otherwise)."
print "\t --race \n\t\t- Whether the produced build should have race detection enabled."
print "\t --package \n\t\t- Whether the produced builds should be packaged for the target platform(s)."
print "\t --nightly \n\t\t- Whether the produced build is a nightly (affects version information)."
print "\t --update \n\t\t- Whether dependencies should be updated prior to building."
print "\t --test \n\t\t- Run Go tests. Will not produce a build."
print "\t --parallel \n\t\t- Run Go tests in parallel up to the count specified."
print "\t --timeout \n\t\t- Timeout for Go tests. Default 480s"
print "\t --timeout \n\t\t- Timeout for Go tests. Defaults to 480s."
print "\t --clean \n\t\t- Clean the build output directory prior to creating build."
print ""
@ -520,6 +527,7 @@ def main():
timeout = None
iteration = 1
no_vet = False
goarm_version = "6"
for arg in sys.argv[1:]:
if '--outdir' in arg:
@ -574,6 +582,9 @@ def main():
iteration = arg.split("=")[1]
elif '--no-vet' in arg:
no_vet = True
elif '--goarm' in arg:
# Signifies GOARM flag to pass to build command when compiling for ARM
goarm_version = arg.split("=")[1]
elif '--help' in arg:
print_usage()
return 0
@ -599,12 +610,16 @@ def main():
if not branch:
branch = get_current_branch()
if not target_arch:
target_arch = get_system_arch()
if 'arm' in get_system_arch():
# Prevent uname from reporting ARM arch (eg 'armv7l')
target_arch = "arm"
else:
target_arch = get_system_arch()
if not target_platform:
target_platform = get_system_platform()
if target_arch == "x86_64":
target_arch = "amd64"
if rc or nightly:
# If a release candidate or nightly, set iteration to 0 (instead of 1)
iteration = 0
build_output = {}
# TODO(rossmcdonald): Prepare git repo for build (checking out correct branch/commit, etc.)
@ -645,7 +660,8 @@ def main():
rc=rc,
race=race,
clean=clean,
outdir=od)
outdir=od,
goarm_version=goarm_version)
build_output.get(platform).update( { arch : od } )
# Build packages

View File

@ -1,43 +1,66 @@
#!/bin/sh
#!/bin/bash
BIN_DIR=/usr/bin
DATA_DIR=/var/lib/influxdb
LOG_DIR=/var/log/influxdb
SCRIPT_DIR=/usr/lib/influxdb/scripts
LOGROTATE_DIR=/etc/logrotate.d
if ! id influxdb >/dev/null 2>&1; then
useradd --system -U -M influxdb -s /bin/false -d $DATA_DIR
fi
chmod a+rX $BIN_DIR/influx*
mkdir -p $LOG_DIR
chown -R -L influxdb:influxdb $LOG_DIR
mkdir -p $DATA_DIR
chown -R -L influxdb:influxdb $DATA_DIR
test -f /etc/default/influxdb || touch /etc/default/influxdb
# Remove legacy logrotate file
test -f $LOGROTATE_DIR/influxd && rm -f $LOGROTATE_DIR/influxd
# Remove legacy symlink
test -h /etc/init.d/influxdb && rm -f /etc/init.d/influxdb
# Systemd
if which systemctl > /dev/null 2>&1 ; then
cp $SCRIPT_DIR/influxdb.service /lib/systemd/system/influxdb.service
systemctl enable influxdb
# Sysv
else
function install_init {
cp -f $SCRIPT_DIR/init.sh /etc/init.d/influxdb
chmod +x /etc/init.d/influxdb
if which update-rc.d > /dev/null 2>&1 ; then
update-rc.d -f influxdb remove
update-rc.d influxdb defaults
else
chkconfig --add influxdb
fi
}
function install_systemd {
cp -f $SCRIPT_DIR/influxdb.service /lib/systemd/system/influxdb.service
systemctl enable influxdb
}
function install_update_rcd {
update-rc.d influxdb defaults
}
function install_chkconfig {
chkconfig --add influxdb
}
id influxdb &>/dev/null
if [[ $? -ne 0 ]]; then
useradd --system -U -M influxdb -s /bin/false -d $DATA_DIR
fi
exit
chown -R -L influxdb:influxdb $DATA_DIR
chown -R -L influxdb:influxdb $LOG_DIR
# Add defaults file, if it doesn't exist
if [[ ! -f /etc/default/influxdb ]]; then
touch /etc/default/influxdb
fi
# Remove legacy symlink, if it exists
if [[ -L /etc/init.d/influxdb ]]; then
rm -f /etc/init.d/influxdb
fi
# Distribution-specific logic
if [[ -f /etc/redhat-release ]]; then
# RHEL-variant logic
which systemctl &>/dev/null
if [[ $? -eq 0 ]]; then
install_systemd
else
# Assuming sysv
install_init
install_chkconfig
fi
elif [[ -f /etc/lsb-release ]]; then
# Debian/Ubuntu logic
which systemctl &>/dev/null
if [[ $? -eq 0 ]]; then
install_systemd
else
# Assuming sysv
install_init
install_update_rcd
fi
fi

View File

@ -1,17 +1,46 @@
#!/bin/sh
rm -f /etc/default/influxdb
#!/bin/bash
# Systemd
if which systemctl > /dev/null 2>&1 ; then
function disable_systemd {
systemctl disable influxdb
rm -f /lib/systemd/system/influxdb.service
# Sysv
else
if which update-rc.d > /dev/null 2>&1 ; then
update-rc.d -f influxdb remove
else
chkconfig --del influxdb
fi
rm -f /etc/init.d/influxdb
fi
}
function disable_update_rcd {
update-rc.d -f influxdb remove
rm -f /etc/init.d/influxdb
}
function disable_chkconfig {
chkconfig --del influxdb
rm -f /etc/init.d/influxdb
}
if [[ -f /etc/redhat-release ]]; then
# RHEL-variant logic
if [[ "$1" = "0" ]]; then
# InfluxDB is no longer installed, remove from init system
rm -f /etc/default/influxdb
which systemctl &>/dev/null
if [[ $? -eq 0 ]]; then
disable_systemd
else
# Assuming sysv
disable_chkconfig
fi
fi
elif [[ -f /etc/lsb-release ]]; then
# Debian/Ubuntu logic
if [[ "$1" != "upgrade" ]]; then
# Remove/purge
rm -f /etc/default/influxdb
which systemctl &>/dev/null
if [[ $? -eq 0 ]]; then
disable_systemd
else
# Assuming sysv
disable_update_rcd
fi
fi
fi

View File

@ -1,10 +1,16 @@
#!/bin/sh
#!/bin/bash
# Copy existing configuration if pre-existing installation is found
test -f /etc/opt/influxdb/influxdb.conf
if [ $? -eq 0 ]; then
mkdir /etc/influxdb
cp -a /etc/opt/influxdb/* /etc/influxdb/
if [[ -d /etc/opt/influxdb ]]; then
# Legacy configuration found
if [[ ! -d /etc/influxdb ]]; then
# New configuration does not exist, move legacy configuration to new location
echo -e "Please note, InfluxDB's configuration is now located at '/etc/influxdb' (previously '/etc/opt/influxdb')."
mv -vn /etc/opt/influxdb /etc/influxdb
if [[ -f /etc/influxdb/influxdb.conf ]]; then
backup_name="influxdb.conf.$(date +%s).backup"
echo "A backup of your current configuration can be found at: /etc/influxdb/$backup_name"
cp -a /etc/influxdb/influxdb.conf /etc/influxdb/$backup_name
fi
fi
fi
exit