diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f84419b93..1ec485ed02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,17 @@ ## v0.9.5 [unreleased] ### Release Notes + - Field names for the internal stats have been changed to be more inline with Go style. - 0.9.5 is reverting to Go 1.4.2 due to unresolved issues with Go 1.5.1. +There are breaking changes in this release: +- The filesystem hierarchy for packages has been changed, namely: + - Binaries are now located in `/usr/bin` (previously `/opt/influxdb`) + - Configuration files are now located in `/etc/influxdb` (previously `/etc/opt/influxdb`) + - Data directories are now located in `/var/lib/influxdb` (previously `/var/opt/influxdb`) + - Scripts are now located in `/usr/lib/influxdb/scripts` (previously `/opt/influxdb`) + ### Features - [#4098](https://github.com/influxdb/influxdb/pull/4702): Support 'history' command at CLI - [#4098](https://github.com/influxdb/influxdb/issues/4098): Enable `golint` on the code base - uuid subpackage diff --git a/build.py b/build.py new file mode 100755 index 0000000000..6aaa50139e --- /dev/null +++ b/build.py @@ -0,0 +1,612 @@ +#!/usr/bin/env python2.7 +# +# 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) +# + +import sys +import os +import subprocess +import time +import datetime +import shutil +import tempfile +import hashlib +import re + +try: + import boto + from boto.s3.key import Key +except ImportError: + pass + +# PACKAGING VARIABLES +INSTALL_ROOT_DIR = "/usr/bin" +LOG_DIR = "/var/log/influxdb" +DATA_DIR = "/var/lib/influxdb" +SCRIPT_DIR = "/usr/lib/influxdb/scripts" +CONFIG_DIR = "/etc/influxdb" +LOGROTATE_DIR = "/etc/logrotate.d" + +INIT_SCRIPT = "scripts/init.sh" +SYSTEMD_SCRIPT = "scripts/influxdb.service" +PREINST_SCRIPT = "scripts/pre-install.sh" +POSTINST_SCRIPT = "scripts/post-install.sh" +PREUNINST_SCRIPT = "scripts/pre-uninstall.sh" +POSTUNINST_SCRIPT = "scripts/post-uninstall.sh" +LOGROTATE_SCRIPT = "scripts/logrotate" +DEFAULT_CONFIG = "etc/config.sample.toml" + +# META-PACKAGE VARIABLES +PACKAGE_LICENSE = "MIT" +PACKAGE_URL = "github.com/influxdb/influxdb" +MAINTAINER = "support@influxdb.com" +VENDOR = "InfluxData" +DESCRIPTION = "A distributed time-series database" + +# SCRIPT START +prereqs = [ 'git', 'go' ] +optional_prereqs = [ 'gvm', 'fpm', 'rpmbuild' ] + +fpm_common_args = "-f -s dir --log error \ + --vendor {} \ + --url {} \ + --after-install {} \ + --before-install {} \ + --after-remove {} \ + --before-remove {} \ + --license {} \ + --maintainer {} \ + --config-files {} \ + --config-files {} \ + --description \"{}\"".format( + VENDOR, + PACKAGE_URL, + POSTINST_SCRIPT, + PREINST_SCRIPT, + POSTUNINST_SCRIPT, + PREUNINST_SCRIPT, + PACKAGE_LICENSE, + MAINTAINER, + CONFIG_DIR, + LOGROTATE_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', +} + +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" ] +} +supported_go = [ '1.5.1' ] +supported_packages = { + "darwin": [ "tar", "zip" ], + "linux": [ "deb", "rpm", "tar", "zip" ], + "windows": [ "tar", "zip" ], +} + +def run(command, allow_failure=False, shell=False): + out = None + try: + if shell: + out = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell) + else: + out = subprocess.check_output(command.split(), stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + print "" + print "Executed command failed!" + print "-- Command run was: {}".format(command) + print "-- Failure was: {}".format(e.output) + if allow_failure: + print "Continuing..." + return out + else: + print "" + print "Stopping." + sys.exit(1) + except OSError as e: + print "" + print "Invalid command!" + print "-- Command run was: {}".format(command) + print "-- Failure was: {}".format(e) + if allow_failure: + print "Continuing..." + return out + else: + print "" + print "Stopping." + sys.exit(1) + else: + return out + +def create_temp_dir(): + return tempfile.mkdtemp(prefix="influxdb-build.") + +def get_current_version(): + command = "git describe --always --tags --abbrev=0" + out = run(command) + return out.strip() + +def get_current_commit(short=False): + command = None + if short: + command = "git log --pretty=format:'%h' -n 1" + else: + command = "git rev-parse HEAD" + out = run(command) + return out.strip('\'\n\r ') + +def get_current_branch(): + command = "git rev-parse --abbrev-ref HEAD" + out = run(command) + return out.strip() + +def get_system_arch(): + return os.uname()[4] + +def get_system_platform(): + if sys.platform.startswith("linux"): + return "linux" + else: + return sys.platform + +def get_go_version(): + out = run("go version") + matches = re.search('go version go(\S+)', out) + if matches is not None: + return matches.groups()[0].strip() + return None + +def check_path_for(b): + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + full_path = os.path.join(path, b) + if os.path.isfile(full_path) and os.access(full_path, os.X_OK): + return full_path + +def check_environ(build_dir = None): + print "\nChecking environment:" + for v in [ "GOPATH", "GOBIN" ]: + 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." + +def check_prereqs(): + print "\nChecking for dependencies:" + for req in prereqs: + print "\t- {} ->".format(req), + path = check_path_for(req) + if path: + print "{}".format(path) + else: + print "?" + for req in optional_prereqs: + print "\t- {} (optional) ->".format(req), + path = check_path_for(req) + if path: + print "{}".format(path) + else: + print "?" + print "" + +def upload_packages(packages, nightly=False): + print "Uploading packages to S3..." + print "" + c = boto.connect_s3() + # TODO(rossmcdonald) - Set to different S3 bucket for release vs nightly + bucket = c.get_bucket('influxdb-nightly') + for p in packages: + name = os.path.basename(p) + if bucket.get_key(name) is None or nightly: + print "\t - Uploading {}...".format(name), + k = Key(bucket) + k.key = name + if nightly: + n = k.set_contents_from_filename(p, replace=True) + else: + n = k.set_contents_from_filename(p, replace=False) + k.make_public() + print "[ DONE ]" + else: + print "\t - Not uploading {}, already exists.".format(p) + print "" + +def run_tests(): + get_command = "go get -d -t ./..." + print "Retrieving Go dependencies...", + run(get_command) + print "done." + print "Running tests..." + code = os.system("go test ./...") + if code != 0: + print "Tests Failed" + return False + else: + print "Tests Passed" + return True + +def build(version=None, + branch=None, + commit=None, + platform=None, + arch=None, + nightly=False, + rc=None, + race=False, + clean=False, + outdir="."): + print "-------------------------" + print "" + print "Build plan:" + print "\t- version: {}".format(version) + if rc: + print "\t- release candidate: {}".format(rc) + print "\t- commit: {}".format(commit) + print "\t- branch: {}".format(branch) + print "\t- platform: {}".format(platform) + print "\t- arch: {}".format(arch) + print "\t- nightly? {}".format(str(nightly).lower()) + print "\t- race enabled? {}".format(str(race).lower()) + print "" + + if not os.path.exists(outdir): + os.makedirs(outdir) + elif clean and outdir != '/': + print "Cleaning build directory..." + shutil.rmtree(outdir) + os.makedirs(outdir) + + if rc: + # If a release candidate, update the version information accordingly + version = "{}rc{}".format(version, rc) + + print "Starting build..." + 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 += "go build -o {} ".format(os.path.join(outdir, b)) + if race: + build_command += "-race " + go_version = get_go_version() + if "1.4" in go_version: + build_command += "-ldflags=\"-X main.buildTime '{}' ".format(datetime.datetime.utcnow().isoformat()) + build_command += "-X main.version {} ".format(version) + build_command += "-X main.branch {} ".format(branch) + build_command += "-X main.commit {}\" ".format(get_current_commit()) + else: + build_command += "-ldflags=\"-X main.buildTime='{}' ".format(datetime.datetime.utcnow().isoformat()) + build_command += "-X main.version={} ".format(version) + 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) + print "[ DONE ]" + print "" + +def create_dir(path): + try: + os.makedirs(path) + except OSError as e: + print e + +def rename_file(fr, to): + try: + os.rename(fr, to) + except OSError as e: + print e + # Return the original filename + return fr + else: + # Return the new filename + return to + +def copy_file(fr, to): + try: + shutil.copy(fr, to) + except OSError as e: + print e + +def create_package_fs(build_root): + print "\t- Creating a filesystem hierarchy from directory: {}".format(build_root) + # Using [1:] for the path names due to them being absolute + # (will overwrite previous paths, per 'os.path.join' documentation) + create_dir(os.path.join(build_root, INSTALL_ROOT_DIR[1:])) + create_dir(os.path.join(build_root, LOG_DIR[1:])) + create_dir(os.path.join(build_root, DATA_DIR[1:])) + create_dir(os.path.join(build_root, SCRIPT_DIR[1:])) + create_dir(os.path.join(build_root, CONFIG_DIR[1:])) + create_dir(os.path.join(build_root, LOGROTATE_DIR[1:])) + +def package_scripts(build_root): + print "\t- Copying scripts and sample configuration to build directory" + shutil.copyfile(INIT_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1])) + shutil.copyfile(SYSTEMD_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], SYSTEMD_SCRIPT.split('/')[1])) + shutil.copyfile(LOGROTATE_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], LOGROTATE_SCRIPT.split('/')[1])) + shutil.copyfile(DEFAULT_CONFIG, os.path.join(build_root, CONFIG_DIR[1:], "influxdb.conf")) + +def go_get(update=False): + get_command = None + if update: + get_command = "go get -u -f -d ./..." + else: + get_command = "go get -d ./..." + print "Retrieving Go dependencies...", + run(get_command) + print "done.\n" + +def generate_md5_from_file(path): + m = hashlib.md5() + with open(path, 'rb') as f: + for chunk in iter(lambda: f.read(4096), b""): + m.update(chunk) + return m.hexdigest() + +def build_packages(build_output, version, nightly=False, rc=None): + outfiles = [] + tmp_build_dir = create_temp_dir() + try: + print "-------------------------" + print "" + print "Packaging..." + for p in build_output: + # Create top-level folder displaying which platform (linux, etc) + create_dir(os.path.join(tmp_build_dir, p)) + for a in build_output[p]: + current_location = build_output[p][a] + # Create second-level directory displaying the architecture (amd64, etc)p + build_root = os.path.join(tmp_build_dir, p, a) + # Create directory tree to mimic file system of package + create_dir(build_root) + create_package_fs(build_root) + # Copy in packaging and miscellaneous scripts + package_scripts(build_root) + # Copy newly-built binaries to packaging directory + for b in targets: + if p == 'windows': + b = b + '.exe' + fr = os.path.join(current_location, b) + to = os.path.join(build_root, INSTALL_ROOT_DIR[1:], b) + print "\t- [{}][{}] - Moving from '{}' to '{}'".format(p, a, fr, to) + copy_file(fr, to) + # Package the directory structure + for package_type in supported_packages[p]: + print "\t- Packaging directory '{}' as '{}'...".format(build_root, package_type), + name = "influxdb" + if package_type in ['zip', 'tar']: + if nightly: + name = '{}-nightly_{}_{}'.format(name, p, a) + else: + name = '{}-{}_{}_{}'.format(name, version, p, a) + 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') + fpm_command = "fpm {} --name {} -a {} -t {} --version {} -C {} -p {} ".format( + fpm_common_args, + name, + a, + package_type, + version, + build_root, + current_location) + if package_type == "rpm": + fpm_command += "--depends coreutils " + if rc: + fpm_command += "--iteration {} ".format(rc) + else: + fpm_command += "--iteration 1 " + out = run(fpm_command, shell=True) + matches = re.search(':path=>"(.*)"', out) + outfile = None + if matches is not None: + outfile = matches.groups()[0] + if outfile is None: + 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")) + outfiles.append(os.path.join(os.getcwd(), outfile)) + print "[ DONE ]" + # Display MD5 hash for generated package + print "\t\tMD5 = {}".format(generate_md5_from_file(outfile)) + print "" + return outfiles + finally: + # Cleanup + shutil.rmtree(tmp_build_dir) + +def print_usage(): + print "Usage: ./build.py [options]" + print "" + print "Options:" + print "\t --outdir= \n\t\t- Send build output to a specified path. Defaults to ./build." + print "\t --arch= \n\t\t- Build for specified architecture. Acceptable values: x86_64|amd64, 386, arm, or all" + print "\t --platform= \n\t\t- Build for specified platform. Acceptable values: linux, windows, darwin, or all" + print "\t --version= \n\t\t- Version information to apply to build metadata. If not specified, will be pulled from repo tag." + print "\t --commit= \n\t\t- Use specific commit for build (currently a NOOP)." + print "\t --branch= \n\t\t- Build from a specific branch (currently a NOOP)." + print "\t --rc= \n\t\t- Whether or not the build is a release candidate (affects version information)." + 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 --clean \n\t\t- Clean the build output directory prior to creating build." + print "" + +def print_package_summary(packages): + print packages + +def main(): + # Command-line arguments + outdir = "build" + commit = None + target_platform = None + target_arch = None + nightly = False + race = False + branch = None + version = get_current_version() + rc = None + package = False + update = False + clean = False + upload = False + test = False + + for arg in sys.argv[1:]: + if '--outdir' in arg: + # Output directory. If none is specified, then builds will be placed in the same directory. + output_dir = arg.split("=")[1] + if '--commit' in arg: + # Commit to build from. If none is specified, then it will build from the most recent commit. + commit = arg.split("=")[1] + if '--branch' in arg: + # Branch to build from. If none is specified, then it will build from the current branch. + branch = arg.split("=")[1] + elif '--arch' in arg: + # Target architecture. If none is specified, then it will build for the current arch. + target_arch = arg.split("=")[1] + elif '--platform' in arg: + # Target platform. If none is specified, then it will build for the current platform. + target_platform = arg.split("=")[1] + elif '--version' in arg: + # Version to assign to this build (0.9.5, etc) + version = arg.split("=")[1] + elif '--rc' in arg: + # Signifies that this is a release candidate build. + rc = arg.split("=")[1] + elif '--race' in arg: + # Signifies that race detection should be enabled. + race = True + elif '--package' in arg: + # Signifies that race detection should be enabled. + package = True + elif '--nightly' in arg: + # Signifies that this is a nightly build. + nightly = True + elif '--update' in arg: + # Signifies that race detection should be enabled. + update = True + elif '--upload' in arg: + # Signifies that the resulting packages should be uploaded to S3 + upload = True + elif '--test' in arg: + # Run tests and exit + test = True + elif '--clean' in arg: + # Signifies that the outdir should be deleted before building + clean = True + elif '--help' in arg: + print_usage() + return 0 + else: + print "!! Unknown argument: {}".format(arg) + print_usage() + return 1 + + if nightly: + if rc: + print "!! Cannot be both nightly and a release candidate! Stopping." + return 1 + # In order to support nightly builds on the repository, we are adding the epoch timestamp + # to the version so that seamless upgrades are possible. + version = "{}.n{}".format(version, int(time.time())) + + # Pre-build checks + check_environ() + check_prereqs() + + if not commit: + commit = get_current_commit(short=True) + if not branch: + branch = get_current_branch() + if not target_arch: + target_arch = get_system_arch() + if not target_platform: + target_platform = get_system_platform() + + if target_arch == "x86_64": + target_arch = "amd64" + + build_output = {} + # TODO(rossmcdonald): Prepare git repo for build (checking out correct branch/commit, etc.) + # prepare(branch=branch, commit=commit) + if test: + if not run_tests(): + return 1 + return 0 + + go_get(update=update) + + platforms = [] + single_build = True + if target_platform == 'all': + platforms = supported_builds.keys() + single_build = False + else: + platforms = [target_platform] + + for platform in platforms: + build_output.update( { platform : {} } ) + archs = [] + if target_arch == "all": + single_build = False + archs = supported_builds.get(platform) + else: + archs = [target_arch] + for arch in archs: + od = outdir + if not single_build: + od = os.path.join(outdir, platform, arch) + build(version=version, + branch=branch, + commit=commit, + platform=platform, + arch=arch, + nightly=nightly, + rc=rc, + race=race, + clean=clean, + outdir=od) + build_output.get(platform).update( { arch : od } ) + + # Build packages + if package: + if not check_path_for("fpm"): + print "!! Cannot package without command 'fpm'. Stopping." + return 1 + packages = build_packages(build_output, version, nightly=nightly, rc=rc) + # TODO(rossmcdonald): Add nice output for print_package_summary() + # print_package_summary(packages) + # Optionally upload to S3 + if upload: + upload_packages(packages, nightly=nightly) + return 0 + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/etc/config.sample.toml b/etc/config.sample.toml index 848a0647aa..e73e1ec6f3 100644 --- a/etc/config.sample.toml +++ b/etc/config.sample.toml @@ -25,7 +25,7 @@ reporting-disabled = false ### [meta] - dir = "/var/opt/influxdb/meta" + dir = "/var/lib/influxdb/meta" hostname = "localhost" bind-address = ":8088" retention-autocreate = true @@ -52,7 +52,7 @@ reporting-disabled = false ### [data] - dir = "/var/opt/influxdb/data" + dir = "/var/lib/influxdb/data" # Controls the engine type for new shards. Options are b1, bz1, or tsm1. # b1 is the 0.9.2 storage engine, bz1 is the 0.9.3 and 0.9.4 engine. @@ -68,7 +68,7 @@ reporting-disabled = false wal-partition-flush-delay = "2s" # The delay time between each WAL partition being flushed. # These are the WAL settings for the storage engine >= 0.9.3 - wal-dir = "/var/opt/influxdb/wal" + wal-dir = "/var/lib/influxdb/wal" wal-enable-logging = true # When a series in the WAL in-memory cache reaches this size in bytes it is marked as ready to @@ -105,7 +105,7 @@ reporting-disabled = false [hinted-handoff] enabled = true - dir = "/var/opt/influxdb/hh" + dir = "/var/lib/influxdb/hh" max-size = 1073741824 max-age = "168h" retry-rate-limit = 0 diff --git a/package.sh b/package.sh index 70e41c4268..ff84bcf4c7 100755 --- a/package.sh +++ b/package.sh @@ -36,10 +36,11 @@ AWS_FILE=~/aws.conf -INSTALL_ROOT_DIR=/opt/influxdb +INSTALL_ROOT_DIR=/usr/bin INFLUXDB_LOG_DIR=/var/log/influxdb -INFLUXDB_DATA_DIR=/var/opt/influxdb -CONFIG_ROOT_DIR=/etc/opt/influxdb +INFLUXDB_DATA_DIR=/var/lib/influxdb +INFLUXDB_SCRIPT_DIR=/usr/lib/influxdb +CONFIG_ROOT_DIR=/etc/influxdb LOGROTATE_DIR=/etc/logrotate.d SAMPLE_CONFIGURATION=etc/config.sample.toml @@ -213,9 +214,11 @@ check_tag_exists () { make_dir_tree() { work_dir=$1 version=$2 - mkdir -p $work_dir/$INSTALL_ROOT_DIR/versions/$version/scripts + + mkdir -p $work_dir/$INSTALL_ROOT_DIR + mkdir -p $work_dir/$INFLUXDB_SCRIPT_DIR/scripts if [ $? -ne 0 ]; then - echo "Failed to create installation directory -- aborting." + echo "Failed to create script directory -- aborting." cleanup_exit 1 fi mkdir -p $work_dir/$CONFIG_ROOT_DIR @@ -281,29 +284,34 @@ generate_postinstall_script() { version=$1 cat <$POST_INSTALL_PATH #!/bin/sh -rm -f $INSTALL_ROOT_DIR/influxd -rm -f $INSTALL_ROOT_DIR/influx -rm -f $INSTALL_ROOT_DIR/init.sh -ln -s $INSTALL_ROOT_DIR/versions/$version/influxd $INSTALL_ROOT_DIR/influxd -ln -s $INSTALL_ROOT_DIR/versions/$version/influx $INSTALL_ROOT_DIR/influx -ln -s $INSTALL_ROOT_DIR/versions/$version/influx_inspect $INSTALL_ROOT_DIR/influx_inspect -ln -s $INSTALL_ROOT_DIR/versions/$version/influx_stress $INSTALL_ROOT_DIR/influx_stress -ln -s $INSTALL_ROOT_DIR/versions/$version/scripts/init.sh $INSTALL_ROOT_DIR/init.sh if ! id influxdb >/dev/null 2>&1; then - useradd --system -U -M influxdb + useradd --system -U -M influxdb -s /bin/false -d $INFLUXDB_DATA_DIR fi +chown influxdb:influxdb $INSTALL_ROOT_DIR/influx* +chmod a+rX $INSTALL_ROOT_DIR/influx* + +mkdir -p $INFLUXDB_LOG_DIR +chown -R -L influxdb:influxdb $INFLUXDB_LOG_DIR +mkdir -p $INFLUXDB_DATA_DIR +chown -R -L influxdb: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 $INSTALL_ROOT_DIR/versions/$version/scripts/influxdb.service \ - /lib/systemd/system/influxdb.service + cp $INFLUXDB_SCRIPT_DIR/$SYSTEMD_SCRIPT /lib/systemd/system/influxdb.service systemctl enable influxdb # Sysv else - rm -f /etc/init.d/influxdb - ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/influxdb + cp -f $INFLUXDB_SCRIPT_DIR/$INITD_SCRIPT /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 @@ -312,14 +320,6 @@ else chkconfig --add influxdb fi fi - -chown -R -L influxdb:influxdb $INSTALL_ROOT_DIR -chmod -R a+rX $INSTALL_ROOT_DIR - -mkdir -p $INFLUXDB_LOG_DIR -chown -R -L influxdb:influxdb $INFLUXDB_LOG_DIR -mkdir -p $INFLUXDB_DATA_DIR -chown -R -L influxdb:influxdb $INFLUXDB_DATA_DIR EOF echo "Post-install script created successfully at $POST_INSTALL_PATH" } @@ -387,7 +387,8 @@ do usage 1 fi - echo $VERSION | grep -i '[r|c]' 2>&1 >/dev/null + + echo $VERSION | grep -i '[r|rc]' 2>&1 >/dev/null if [ $? -ne 1 -a -z "$NIGHTLY_BUILD" ]; then echo echo "$VERSION contains reference to RC - specify RC separately" @@ -443,27 +444,27 @@ make_dir_tree $TMP_WORK_DIR `full_version $VERSION $RC` # Copy the assets to the installation directories. for b in ${BINS[*]}; do - cp $GOPATH_INSTALL/bin/$b $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC` + cp $GOPATH_INSTALL/bin/$b $TMP_WORK_DIR/$INSTALL_ROOT_DIR/ if [ $? -ne 0 ]; then - echo "Failed to copy binaries to packaging directory -- aborting." + echo "Failed to copy binaries to packaging directory ($TMP_WORK_DIR/$INSTALL_ROOT_DIR/) -- aborting." cleanup_exit 1 fi done -echo "${BINS[*]} copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC`" +echo "${BINS[*]} copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/" -cp $INITD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC`/scripts +cp $INITD_SCRIPT $TMP_WORK_DIR/$INFLUXDB_SCRIPT_DIR/$INITD_SCRIPT if [ $? -ne 0 ]; then - echo "Failed to copy init.d script to packaging directory -- aborting." + echo "Failed to copy init.d script to packaging directory ($TMP_WORK_DIR/$INFLUXDB_SCRIPT_DIR/) -- aborting." cleanup_exit 1 fi -echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC`/scripts" +echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INFLUXDB_SCRIPT_DIR" -cp $SYSTEMD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC`/scripts +cp $SYSTEMD_SCRIPT $TMP_WORK_DIR/$INFLUXDB_SCRIPT_DIR/$SYSTEMD_SCRIPT if [ $? -ne 0 ]; then echo "Failed to copy systemd script to packaging directory -- aborting." cleanup_exit 1 fi -echo "$SYSTEMD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/`full_version $VERSION $RC`/scripts" +echo "$SYSTEMD_SCRIPT copied to $TMP_WORK_DIR/$INFLUXDB_SCRIPT_DIR" cp $SAMPLE_CONFIGURATION $TMP_WORK_DIR/$CONFIG_ROOT_DIR/influxdb.conf if [ $? -ne 0 ]; then diff --git a/scripts/influxdb.service b/scripts/influxdb.service index e8633acb05..603a27df5f 100644 --- a/scripts/influxdb.service +++ b/scripts/influxdb.service @@ -9,9 +9,11 @@ After=network.target User=influxdb Group=influxdb LimitNOFILE=65536 +Environment='STDOUT=/dev/null' +Environment='STDERR=/var/log/influxdb/influxd.log' EnvironmentFile=-/etc/default/influxdb -ExecStart=/opt/influxdb/influxd -config /etc/opt/influxdb/influxdb.conf $INFLUXD_OPTS -KillMode=process +ExecStart=/bin/sh -c "/usr/bin/influxd -config /etc/influxdb/influxdb.conf ${INFLUXD_OPTS} >> ${STDOUT} 2>> ${STDERR}" +KillMode=control-group Restart=on-failure [Install] diff --git a/scripts/init.sh b/scripts/init.sh index cbee4ce3a6..111f1508da 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -34,11 +34,11 @@ GROUP=influxdb # Daemon name, where is the actual executable # If the daemon is not there, then exit. -DAEMON=/opt/influxdb/influxd +DAEMON=/usr/bin/influxd [ -x $DAEMON ] || exit 5 # Configuration file -CONFIG=/etc/opt/influxdb/influxdb.conf +CONFIG=/etc/influxdb/influxdb.conf # PID file for the daemon PIDFILE=/var/run/influxdb/influxd.pid @@ -131,15 +131,15 @@ case $1 in start) # Check if config file exist if [ ! -r $CONFIG ]; then - log_failure_msg "config file doesn't exists" + log_failure_msg "config file doesn't exist (or you don't have permission to view)" exit 4 fi # Checked the PID file exists and check the actual status of process if [ -e $PIDFILE ]; then - pidofproc -p $PIDFILE $DAEMON > /dev/null 2>&1 && STATUS="0" || STATUS="$?" - # If the status is SUCCESS then don't need to start again. - if [ "x$STATUS" = "x0" ]; then + PID="$(pgrep -f $PIDFILE)" + if test ! -z $PID && kill -0 "$PID" &>/dev/null; then + # If the status is SUCCESS then don't need to start again. log_failure_msg "$NAME process is running" exit 0 # Exit fi @@ -172,8 +172,8 @@ case $1 in stop) # Stop the daemon. if [ -e $PIDFILE ]; then - pidofproc -p $PIDFILE $DAEMON > /dev/null 2>&1 && STATUS="0" || STATUS="$?" - if [ "$STATUS" = 0 ]; then + PID="$(pgrep -f $PIDFILE)" + if test ! -z $PID && kill -0 "$PID" &>/dev/null; then if killproc -p $PIDFILE SIGTERM && /bin/rm -rf $PIDFILE; then log_success_msg "$NAME process was stopped" else @@ -193,7 +193,8 @@ case $1 in status) # Check the status of the process. if [ -e $PIDFILE ]; then - if pidofproc -p $PIDFILE $DAEMON > /dev/null; then + PID="$(pgrep -f $PIDFILE)" + if test ! -z $PID && test -d "/proc/$PID" &>/dev/null; then log_success_msg "$NAME Process is running" exit 0 else diff --git a/scripts/post-install.sh b/scripts/post-install.sh new file mode 100644 index 0000000000..606a438e34 --- /dev/null +++ b/scripts/post-install.sh @@ -0,0 +1,44 @@ +#!/bin/sh +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 +chown influxdb:influxdb $BIN_DIR/influx* +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 + 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 +fi + +exit diff --git a/scripts/post-uninstall.sh b/scripts/post-uninstall.sh new file mode 100644 index 0000000000..6003b291fa --- /dev/null +++ b/scripts/post-uninstall.sh @@ -0,0 +1,17 @@ +#!/bin/sh +rm -f /etc/default/influxdb + +# Systemd +if which systemctl > /dev/null 2>&1 ; then + 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 + diff --git a/scripts/pre-install.sh b/scripts/pre-install.sh new file mode 100755 index 0000000000..85a51f309b --- /dev/null +++ b/scripts/pre-install.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Copy existing configuration if pre-existing installation is found +test -f /etc/opt/influxdb/influxdb.conf +if [ $? -eq 0 ]; then + cp -a /etc/opt/influxdb /etc/influxdb +fi + +exit diff --git a/scripts/pre-uninstall.sh b/scripts/pre-uninstall.sh new file mode 100644 index 0000000000..1aaac4fd8c --- /dev/null +++ b/scripts/pre-uninstall.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +echo "Stopping the InfluxDB process..." +if which systemctl > /dev/null 2>&1; then + systemctl stop influxdb +elif which service >/dev/null 2>&1; then + service influxdb stop +else + /etc/init.d/influxdb stop +fi +