Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[build] update install package paths, centralize config #7308

Merged
merged 15 commits into from
Jun 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module.exports = function (grunt) {

grunt.config.merge(config);

config.userScriptsDir = __dirname + '/build/userScripts';
config.packageScriptsDir = __dirname + '/tasks/build/package_scripts';
// ensure that these run first, other configs need them
config.services = require('./tasks/config/services')(grunt);
config.platforms = require('./tasks/config/platforms')(grunt);
Expand Down
103 changes: 61 additions & 42 deletions tasks/build/os_packages.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,74 @@
module.exports = function (grunt) {
const { resolve } = require('path');
const { indexBy } = require('lodash');
import { resolve } from 'path';
import { indexBy } from 'lodash';
import exec from '../utils/exec';

const { config } = grunt;
const exec = require('../utils/exec');
const targetDir = config.get('target');
const version = config.get('pkg.version');
const userScriptsDir = config.get('userScriptsDir');
const servicesByName = indexBy(config.get('services'), 'name');
export default (grunt) => {
const targetDir = grunt.config.get('target');
const packageScriptsDir = grunt.config.get('packageScriptsDir');
const servicesByName = indexBy(grunt.config.get('services'), 'name');
const config = grunt.config.get('packages');
const fpm = args => exec('fpm', args);

grunt.registerTask('_build:osPackages', function () {
grunt.config.get('platforms').forEach(({ name, buildDir }) => {
// TODO(sissel): Check if `fpm` is available
if (!(/linux-x(86|64)$/.test(name))) return;

const arch = /x64$/.test(name) ? 'x86_64' : 'i386';
const fpm = args => exec('fpm', args);

const args = [
grunt.config.get('platforms')
.filter(({ name }) => /linux-x(86|64)$/.test(name))
.map(({ name, buildDir }) => {
const architecture = /x64$/.test(name) ? 'x86_64' : 'i386';
return {
buildDir,
architecture
};
})
.forEach(({ buildDir, architecture }) => {
const baseOptions = [
'--force',
'--package', targetDir,
'-s', 'dir', // input type
'--name', 'kibana',
'--description', 'Explore\ and\ visualize\ your\ Elasticsearch\ data.',
'--version', version,
'--url', 'https://www.elastic.co',
'--vendor', 'Elasticsearch,\ Inc.',
'--maintainer', 'Kibana Team\ \<info@elastic.co\>',
'--license', 'Apache\ 2.0',
'--after-install', resolve(userScriptsDir, 'installer.sh'),
'--after-remove', resolve(userScriptsDir, 'remover.sh'),
'--config-files', '/opt/kibana/config/kibana.yml'
];
'--architecture', architecture,
'--name', config.name,
'--description', config.description,
'--version', config.version,
'--url', config.site,
'--vendor', config.vendor,
'--maintainer', config.maintainer,
'--license', config.license,
'--after-install', resolve(packageScriptsDir, 'post_install.sh'),
'--before-install', resolve(packageScriptsDir, 'pre_install.sh'),
'--before-remove', resolve(packageScriptsDir, 'pre_remove.sh'),
'--after-remove', resolve(packageScriptsDir, 'post_remove.sh'),
'--config-files', config.path.kibanaConfig,
'--template-value', `user=${config.user}`,
'--template-value', `group=${config.group}`,
'--template-value', `optimizeDir=${config.path.home}/optimize`,

const files = buildDir + '/=/opt/kibana';
const sysv = servicesByName.sysv.outputDir + '/etc/=/etc/';
const systemd = servicesByName.systemd.outputDir + '/lib/=/lib/';
//config folder is moved to path.conf, exclude {path.home}/config
//uses relative path to --prefix, strip the leading /
'--exclude', `${config.path.home.slice(1)}/config`
];
const debOptions = [
'-t', 'deb',
'--deb-priority', 'optional'
];
const rpmOptions = [
'-t', 'rpm',
'--rpm-os', 'linux'
];
const args = [
`${buildDir}/=${config.path.home}/`,
`${buildDir}/config/=${config.path.conf}/`,
`${servicesByName.sysv.outputDir}/etc/=/etc/`,
`${servicesByName.systemd.outputDir}/lib/=/lib/`
];

//Manually find flags, multiple args without assignment are not entirely parsed
var flags = grunt.option.flags().join(',');

const buildDeb = !!flags.match('deb');
const buildRpm = !!flags.match('rpm');
const noneSpecified = !buildRpm && !buildDeb;

grunt.file.mkdir(targetDir);
if (buildDeb || noneSpecified) {
fpm(args.concat('-t', 'deb', '--deb-priority', 'optional', '-a', arch, files, sysv, systemd));
const flags = grunt.option.flags().filter(flag => /deb|rpm/.test(flag)).join(',');
const buildDeb = flags.includes('deb') || !flags.length;
const buildRpm = flags.includes('rpm') || !flags.length;
if (buildDeb) {
fpm([...baseOptions, ...debOptions, ...args]);
}
if (buildRpm || noneSpecified) {
fpm(args.concat('-t', 'rpm', '-a', arch, '--rpm-os', 'linux', files, sysv, systemd));
if (buildRpm) {
fpm([...baseOptions, ...rpmOptions, ...args]);
}

});
Expand Down
17 changes: 17 additions & 0 deletions tasks/build/package_scripts/post_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh
set -e

user_check() {
getent passwd "$1" > /dev/null 2>&1
}

user_create() {
# Create a system user. A system user is one within the system uid range and
# has no expiration
useradd -r "$1"
}

if ! user_check "<%= user %>" ; then
user_create "<%= user %>"
fi
chown -R <%= user %>:<%= group %> <%= optimizeDir %>
42 changes: 42 additions & 0 deletions tasks/build/package_scripts/post_remove.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/sh
set -e

user_check() {
getent passwd "$1" > /dev/null 2>&1
}

user_remove() {
userdel "$1"
}

REMOVE_USER=false

case $1 in
# Includes cases for all valid arguments, exit 1 otherwise
# Debian
purge)
REMOVE_USER=true
;;

remove|failed-upgrade|abort-install|abort-upgrade|disappear|upgrade|disappear)
;;

# Red Hat
0)
REMOVE_USER=true
;;

1)
;;

*)
echo "post remove script called with unknown argument \`$1'" >&2
exit 1
;;
esac

if [ "$REMOVE_USER" = "true" ]; then
if user_check "<%= user %>" ; then
user_remove "<%= user %>"
fi
fi
14 changes: 14 additions & 0 deletions tasks/build/package_scripts/pre_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
set -e

if command -v systemctl >/dev/null && systemctl is-active kibana.service >/dev/null; then
systemctl --no-reload stop kibana.service
elif [ -x /etc/init.d/kibana ]; then
if command -v invoke-rc.d >/dev/null; then
invoke-rc.d kibana stop
elif command -v service >/dev/null; then
service kibana stop
else
/etc/init.d/kibana stop
fi
fi
16 changes: 16 additions & 0 deletions tasks/build/package_scripts/pre_remove.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
set -e

echo -n "Stopping kibana service..."
if command -v systemctl >/dev/null && systemctl is-active kibana.service >/dev/null; then
systemctl --no-reload stop kibana.service
elif [ -x /etc/init.d/kibana ]; then
if command -v invoke-rc.d >/dev/null; then
invoke-rc.d kibana stop
elif command -v service >/dev/null; then
service kibana stop
else
/etc/init.d/kibana stop
fi
fi
echo " OK"
30 changes: 14 additions & 16 deletions tasks/build/pleaserun.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
module.exports = function createServices(grunt) {
const { resolve } = require('path');
const { appendFileSync } = require('fs');
const exec = require('../utils/exec');
import { resolve } from 'path';
import { appendFileSync } from 'fs';
import exec from '../utils/exec';

export default (grunt) => {
const userScriptsDir = grunt.config.get('userScriptsDir');
const { path, user, group, name, description } = grunt.config.get('packages');

grunt.registerTask('_build:pleaseRun', function () {
// TODO(sissel): Detect if 'pleaserun' is found, and provide a useful error
// to the user if it is missing.

grunt.config.get('services').forEach(function (service) {
grunt.config.get('services').forEach((service) => {
grunt.file.mkdir(service.outputDir);
exec('pleaserun', [
'--install',
'--no-install-actions',
'--install-prefix', service.outputDir,
'--overwrite',
'--user', 'kibana',
'--group', 'kibana',
'--sysv-log-path', '/var/log/kibana/',
'--name', name,
'--description', description,
'--user', user,
'--group', group,
'--sysv-log-path', path.logs,
'-p', service.name,
'-v', service.version,
'/opt/kibana/bin/kibana'
path.kibanaBin,
`-c ${path.kibanaConfig}`
]);
});

grunt.file.mkdir(userScriptsDir);
exec('please-manage-user', ['--output', userScriptsDir, 'kibana']);
appendFileSync(resolve(userScriptsDir, 'installer.sh'), 'chown kibana:kibana /opt/kibana/optimize');
});
};
58 changes: 45 additions & 13 deletions tasks/config/packages.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
export default (grunt) => {
const version = grunt.config.get('pkg.version');
const productionPath = `kibana/${version.match(/\d\.\d/)[0]}`;
const stagingPath = `kibana/staging/${version.match(/\d\.\d\.\d/)[0]}-XXXXXXX/repos/${version.match(/\d\./)[0]}x`;
const rpmFolder = 'centos';
const debFolder = 'debian';
const VERSION = grunt.config.get('pkg.version');

const FOLDER_STAGING = `kibana/staging/${VERSION.match(/\d\.\d\.\d/)[0]}-XXXXXXX/repos/${VERSION.match(/\d\./)[0]}x`;
const FOLDER_PRODUCTION = `kibana/${VERSION.match(/\d\.\d/)[0]}`;

const FOLDERNAME_DEB = 'debian';
const FOLDERNAME_RPM = 'centos';

const PREFIX_STAGING_DEB = `${FOLDER_STAGING}/${FOLDERNAME_DEB}`;
const PREFIX_STAGING_RPM = `${FOLDER_STAGING}/${FOLDERNAME_RPM}`;
const PREFIX_PRODUCTION_DEB = `${FOLDER_PRODUCTION}/${FOLDERNAME_DEB}`;
const PREFIX_PRODUCTION_RPM = `${FOLDER_PRODUCTION}/${FOLDERNAME_RPM}`;

const FOLDER_CONFIG = '/etc/kibana';
const FOLDER_LOGS = '/var/log/kibana';
const FOLDER_HOME = '/usr/share/kibana';

const FILE_KIBANA_CONF = `${FOLDER_CONFIG}/kibana.yml`;
const FILE_KIBANA_BINARY = `${FOLDER_HOME}/bin/kibana`;

return {
staging: {
bucket: 'download.elasticsearch.org',
debPrefix: `${stagingPath}/${debFolder}`,
rpmPrefix: `${stagingPath}/${rpmFolder}`
publish: {
staging: {
bucket: 'download.elasticsearch.org',
debPrefix: PREFIX_STAGING_DEB,
rpmPrefix: PREFIX_STAGING_RPM
},
production: {
bucket: 'packages.elasticsearch.org',
debPrefix: PREFIX_STAGING_DEB,
rpmPrefix: PREFIX_STAGING_RPM
}
},
production: {
bucket: 'packages.elasticsearch.org',
debPrefix: `${productionPath}/${debFolder}`,
rpmPrefix: `${productionPath}/${rpmFolder}`
user: 'kibana',
group: 'kibana',
name: 'kibana',
description: 'Explore\ and\ visualize\ your\ Elasticsearch\ data',
site: 'https://www.elastic.co',
vendor: 'Elasticsearch,\ Inc.',
maintainer: 'Kibana Team\ \<info@elastic.co\>',
license: 'Apache\ 2.0',
version: VERSION,
path: {
conf: FOLDER_CONFIG,
logs: FOLDER_LOGS,
home: FOLDER_HOME,
kibanaBin: FILE_KIBANA_BINARY,
kibanaConfig: FILE_KIBANA_CONF
}
};
};
10 changes: 5 additions & 5 deletions tasks/release_packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { promisify } from 'bluebird';
import readline from 'readline';

export default (grunt) => {
const packages = grunt.config.get('packages');
const publishConfig = grunt.config.get('packages').publish;
const platforms = grunt.config.get('platforms');

function debS3(deb) {
Expand Down Expand Up @@ -87,8 +87,8 @@ export default (grunt) => {
if (platform.debPath) {
debS3({
filePath: platform.debPath,
bucket: packages[environment].bucket,
prefix: packages[environment].debPrefix.replace('XXXXXXX', trimmedHash),
bucket: publishConfig[environment].bucket,
prefix: publishConfig[environment].debPrefix.replace('XXXXXXX', trimmedHash),
signatureKeyId: signature.id,
arch: platform.name.match('x64') ? 'amd64' : 'i386',
awsKey: aws.key,
Expand All @@ -99,8 +99,8 @@ export default (grunt) => {
if (platform.rpmPath) {
rpmS3({
filePath: platform.rpmPath,
bucket: packages[environment].bucket,
prefix: packages[environment].rpmPrefix.replace('XXXXXXX', trimmedHash),
bucket: publishConfig[environment].bucket,
prefix: publishConfig[environment].rpmPrefix.replace('XXXXXXX', trimmedHash),
signingKeyName: signature.name,
awsKey: aws.key,
awsSecret: aws.secret
Expand Down