diff --git a/.circleci/config.yml b/.circleci/config.yml index 4c49d051178..075105dd0d1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -552,6 +552,21 @@ jobs: name: Update RPM repository command: './scripts/build/update_repo/update-rpm.sh "oss" "$GPG_KEY_PASSWORD" "$CIRCLE_TAG" "dist"' + build-oss-msi: + docker: + - image: grafana/wix-toolset-ci:v3 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Build OSS MSI + command: './scripts/build/ci-msi-build/ci-msi-build-oss.sh' + - persist_to_workspace: + root: . + paths: + - dist/grafana-*.msi + store-build-artifacts: docker: - image: circleci/node:8 @@ -590,6 +605,7 @@ workflows: - backend-lint - mysql-integration-test - postgres-integration-test + - build-oss-msi filters: *filter-only-master - grafana-docker-master: requires: @@ -613,6 +629,16 @@ workflows: - postgres-integration-test - build-all-enterprise filters: *filter-only-master + - build-oss-msi: + requires: + - build-all + - test-backend + - test-frontend + - codespell + - backend-lint + - mysql-integration-test + - postgres-integration-test + filters: *filter-only-master release: jobs: @@ -641,6 +667,7 @@ workflows: - backend-lint - mysql-integration-test - postgres-integration-test + - build-oss-msi filters: *filter-only-release - deploy-enterprise-release: requires: @@ -664,6 +691,16 @@ workflows: - mysql-integration-test - postgres-integration-test filters: *filter-only-release + - build-oss-msi: + requires: + - build-all + - test-backend + - test-frontend + - codespell + - backend-lint + - mysql-integration-test + - postgres-integration-test + filters: *filter-only-master build-branches-and-prs: jobs: diff --git a/scripts/build/ci-msi-build/README.md b/scripts/build/ci-msi-build/README.md new file mode 100644 index 00000000000..903113c660e --- /dev/null +++ b/scripts/build/ci-msi-build/README.md @@ -0,0 +1,44 @@ +# Grafana MSI Generator + +Creates a docker image that can be included within CircleCI or run locally to generate an MSI for Grafana. + +## Docker Image + +The docker image is created and published via CircleCI, and can also be built locally. + +The image is self contained with all of the code in `/master`. +The detection process expects a zip file in `/master/dist`. + +There are two patterns that will be matched for a build in the dist directory: +``` +grafana-6.0.0-ca0bc2c5pre3.windows-amd64.zip +grafana-5.4.3.windows-amd64.zip +``` + +### Building an MSI + +The process is automated to expect a dist directory, and will build an msi for first matching grafana-*.windows-amd64.zip file found. + +``` +grafana-5.4.3.windows-amd64.zip +``` + +## CircleCI + + + +## Manual + +A wrapper script takes a single argument for the path to a zip file, or searches for a file in dist. + +A manual build can be initiated using docker-compose +``` +cd oss +docker-compose up --build +``` +## Automated + +## Testing + +## Change Log +v1.0.0 - initial commit diff --git a/scripts/build/ci-msi-build/ci-msi-build-oss.sh b/scripts/build/ci-msi-build/ci-msi-build-oss.sh new file mode 100755 index 00000000000..74ba4b001a3 --- /dev/null +++ b/scripts/build/ci-msi-build/ci-msi-build-oss.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e +WORKING_DIRECTORY=`pwd` +# copy zip file to /tmp/dist +mkdir -p /tmp/dist +cp ./dist/*.zip /tmp/dist +echo "Contents of /tmp/dist" +ls -al /tmp/dist + +# nssm download has been unreliable, use a cached copy of it +echo "Caching NSSM" +mkdir -p /tmp/cache +cp ./scripts/build/ci-msi-build/oss/cache/nssm-2.24.zip /tmp/cache +# a build can be specified, which will be pulled down +#python3 generator/build.py --build 5.4.3 +#echo "LIGHT config" +#ls -al /home/xclient/wix/light.exe.config +#cat /home/xclient/wix/light.exe.config +#cp ./scripts/build/ci-msi-build/oss/light.exe.config /home/xclient/wix/light.exe.config +#cat /home/xclient/wix/light.exe.config +cd ./scripts/build/ci-msi-build/oss +echo "Building MSI" +python3 generator/build.py "$@" +chmod a+x /tmp/scratch/*.msi +echo "MSI: Copy to $WORKING_DIRECTORY/dist" +cp /tmp/scratch/*.msi $WORKING_DIRECTORY/dist +echo "MSI: contents of $WORKING_DIRECTORY/dist" +ls -al $WORKING_DIRECTORY/dist diff --git a/scripts/build/ci-msi-build/oss/Makefile b/scripts/build/ci-msi-build/oss/Makefile new file mode 100644 index 00000000000..cb72b3abde2 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/Makefile @@ -0,0 +1,5 @@ +all: build + +build: + pip3 install -r requirements.txt + python3 generator/build.py diff --git a/scripts/build/ci-msi-build/oss/cache/nssm-2.24.zip b/scripts/build/ci-msi-build/oss/cache/nssm-2.24.zip new file mode 100755 index 00000000000..3cc5b51790b Binary files /dev/null and b/scripts/build/ci-msi-build/oss/cache/nssm-2.24.zip differ diff --git a/scripts/build/ci-msi-build/oss/ci-wrapper.sh b/scripts/build/ci-msi-build/oss/ci-wrapper.sh new file mode 100755 index 00000000000..b91b323191d --- /dev/null +++ b/scripts/build/ci-msi-build/oss/ci-wrapper.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Build will be found in ./dist and ./dist-enterprise +# integrated circleci will have all of the code in /master +# and the builds will be found in $HOME +mkdir -p /tmp/dist +if [ -d '/home/xclient/repo/dist/' ]; then + ls -al /home/xclient/repo/dist/ + cp /home/xclient/repo/dist/*.zip /tmp/dist/ + echo "Contents of /tmp/dist" + ls -al /tmp/dist +fi +# nssm download has been unreliable, use a cached copy of it +echo "Caching NSSM" +mkdir -p /tmp/cache +cp /master/cache/nssm-2.24.zip /tmp/cache +# a build can be specified, which will be pulled down +#python3 generator/build.py --build 5.4.3 +echo "LIGHT config" +ls -al /home/xclient/wix/light.exe.config +cat /home/xclient/wix/light.exe.config +cp /master/light.exe.config /home/xclient/wix/light.exe.config +cat /home/xclient/wix/light.exe.config +cd /master +echo "Building MSI" +python3 generator/build.py "$@" +# +# diff --git a/scripts/build/ci-msi-build/oss/docker-compose.yml b/scripts/build/ci-msi-build/oss/docker-compose.yml new file mode 100644 index 00000000000..b6547ac2bd6 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + wix: + build: './docker' + command: /oss/wrapper.sh + # important: wine is setup for the user xclient + user: xclient + volumes: + - ../oss:/oss + - ../master/templates:/oss/templates + - ../master/resources:/oss/resources + environment: + - TERM=linux diff --git a/scripts/build/ci-msi-build/oss/generator/build.py b/scripts/build/ci-msi-build/oss/generator/build.py new file mode 100755 index 00000000000..d776f11e279 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/generator/build.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python +# +# Creates .wxs files to be used to generate multiple MSI targets +# +# by default the script will check for dist and enterprise-dist, and parse +# the version as needed options are provided to give a build version that will +# download the zip, drop in to dist/enterprise-dist and do the same thing +# +# Expected paths and names +# /tmp/dist/grafana-6.0.0-ca0bc2c5pre3.windows-amd64.zip +# /tmp/enterprise-dist/grafana-enterprise-6.0.0-29b28127pre3.windows-amd64.zip +# +# Optionally (mainly for testing), pass arguments to pull a specific build +# -b,--build 5.4.3 +# -e,--enterprise add this flag to specify enterprise +# -p,--premium, add this flag to include premium plugins +# +# When using the build option, the zip file is created in either dist or +# dist-enterprise according to the -e flag toggle. +# +# https://s3-us-west-2.amazonaws.com/grafana-releases/release/ +# grafana-{}.windows-amd64.zip +# +# https://dl.grafana.com/enterprise/release/ +# grafana-enterprise-{}.windows-amd64.zip +# +import os +import shutil +import argparse +from jinja2 import Template, Environment, FileSystemLoader + +from utils import * + +############################# +# Constants - DO NOT CHANGE # +############################# +OSS_UPGRADE_VERSION = '35c7d2a9-6e23-4645-b975-e8693a1cef10' +OSS_PRODUCT_NAME = 'Grafana OSS' +ENTERPRISE_UPGRADE_VERSION = 'd534ec50-476b-4edc-a25e-fe854c949f4f' +ENTERPRISE_PRODUCT_NAME = 'Grafana Enterprise' + +############################# +# CONSTANTS +############################# +MSI_GENERATOR_VERSION = '1.0.0' +############################# +# PATHS +############################# +WIX_HOME = '/home/xclient/wix' +WINE_CMD = '/usr/bin/wine64' # or just wine for 32bit +CANDLE = '{} {}/candle.exe'.format(WINE_CMD, WIX_HOME) +LIGHT = '{} {}/light.exe'.format(WINE_CMD, WIX_HOME) +HEAT = '{} {}/heat.exe'.format(WINE_CMD, WIX_HOME) +NSSM_VERSION = '2.24' +DIST_LOCATION = '/tmp/dist' +############################# +# +############################# +grafana_oss = { + 'feature_component_group_refs': [ + 'GrafanaX64', + 'GrafanaServiceX64', + 'GrafanaFirewallExceptionsGroup' + ], + 'directory_refs': [ + 'GrafanaX64Dir' + ], + 'components': [ + 'grafana.wxs', + 'grafana-service.wxs', + 'grafana-firewall.wxs' + ] +} + + +# +# Grafana 6 includes new datasources with long paths +# +def remove_long_paths(): + print('Removing long pathed files - these are not needed to run grafana') + long_files = [ + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts', + '/tmp/a/grafana/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.ts' + ] + for file in long_files: + if os.path.isfile(file): + print('Removing: {}'.format(file)) + os.remove(file) + else: + print('Skipped: {}'.format(file)) + + +def build_oss(zip_file, extracted_name, PRODUCT_VERSION, config, features): + # keep reference to source directory, will need to switch back and + # forth during the process + src_dir = os.getcwd() + # target_dir = tempfile.TemporaryDirectory() + if not os.path.isdir('/tmp/a'): + os.mkdir('/tmp/a') + target_dir_name = '/tmp/a' + extract_zip(zip_file, target_dir_name) + # the zip file contains a version, which will not work when upgrading, + # and ends up with paths longer + # than light.exe can parse (windows issue) + # Once extracted, rename it to grafana without the version included + zip_file_path = '{}/{}'.format(target_dir_name, extracted_name) + rename_to = '{}/grafana'.format(target_dir_name) + print('Renaming extracted path {} to {}'.format(zip_file_path, rename_to)) + os.system('ls -al /tmp/a') + print('Before:') + os.rename(zip_file_path, rename_to) + print('After:') + os.system('ls -al /tmp/a') + # cleanup due to MSI API limitation + remove_long_paths() + # + # HEAT + # + # Collects the files from the path given and generates wxs file + # + print('Heat Harvesting') + cgname = 'GrafanaX64' + cgdir = 'GrafanaX64Dir' + if not os.path.isdir('/tmp/scratch'): + os.mkdir('/tmp/scratch') + os.chdir('/tmp/scratch') + outfile = 'grafana-oss.wxs' + # important flags + # -srd - prevents the parent directory name from being included in the + # harvest + # -cg - component group to be referenced in main wxs file + # -fr - directory ref to be used in main wxs file + try: + cmd = ''' + {} dir {} \ + -platform x64 \ + -sw5150 \ + -srd \ + -cg {} \ + -gg \ + -sfrag \ + -dr {} \ + -template fragment \ + -out {}'''.strip().format(HEAT, target_dir_name, cgname, cgdir, outfile) + print(cmd) + os.system(cmd) + except Exception as ex: + print(ex) + + shutil.copy2(outfile, target_dir_name) + nssm_file = get_nssm('/tmp/cache', NSSM_VERSION) + if not os.path.isdir(target_dir_name + '/nssm'): + os.mkdir(target_dir_name + '/nssm') + extract_zip(nssm_file, target_dir_name + '/nssm') + print('HARVEST COMPLETE') + os.chdir(src_dir) + generate_firewall_wxs(env, PRODUCT_VERSION, '/tmp/scratch/grafana-firewall.wxs', target_dir_name) + generate_service_wxs(env, PRODUCT_VERSION, '/tmp/scratch/grafana-service.wxs', target_dir_name, NSSM_VERSION) + generate_product_wxs(env, config, features, '/tmp/scratch/product.wxs', target_dir_name) + print('GENERATE COMPLETE') + copy_static_files(target_dir_name) + print('COPY STATIC COMPLETE') + # + # CANDLE needs to run in the scratch dir + os.chdir('/tmp/scratch') + try: + filename = 'grafana-service.wxs' + cmd = '{} -ext WixFirewallExtension -ext WixUtilExtension -v -arch x64 {}'.format(CANDLE, filename) + print(cmd) + os.system(cmd) + shutil.copy2('grafana-service.wixobj', target_dir_name) + # + filename = 'grafana-firewall.wxs' + cmd = '{} -ext WixFirewallExtension -ext WixUtilExtension -v -arch x64 {}'.format( + CANDLE, + filename) + print(cmd) + os.system(cmd) + shutil.copy2('grafana-firewall.wixobj', target_dir_name) + # + filename = 'grafana-oss.wxs' + cmd = '{} -ext WixFirewallExtension -ext WixUtilExtension -v -arch x64 {}'.format( + CANDLE, + filename) + print(cmd) + os.system(cmd) + shutil.copy2('grafana-oss.wixobj', target_dir_name) + # + filename = 'product.wxs' + cmd = '{} -ext WixFirewallExtension -ext WixUtilExtension -v -arch x64 {}'.format( + CANDLE, + filename) + print(cmd) + os.system(cmd) + shutil.copy2('product.wixobj', target_dir_name) + except Exception as ex: + print(ex) + print('CANDLE COMPLETE') + ############################ + # LIGHT - Assemble the MSI + ############################ + os.chdir(target_dir_name) + os.system('cp -pr nssm/nssm-2.24 .') + try: + cmd = ''' + {} \ + -cultures:en-US \ + -ext WixUIExtension.dll -ext WixFirewallExtension -ext WixUtilExtension \ + -v -sval -spdb \ + grafana-service.wixobj \ + grafana-firewall.wixobj \ + grafana-oss.wixobj \ + product.wixobj \ + -out grafana.msi'''.strip().format(LIGHT) + print(cmd) + os.system(cmd) + except Exception as ex: + print(ex) + # copy to scratch with version included + msi_filename = '/tmp/scratch/{}.windows-amd64.msi'.format(extracted_name) + shutil.copy2('grafana.msi', msi_filename) + os.system('ls -al /tmp/scratch') + print('LIGHT COMPLETE') + # finally cleanup + # extract_dir.cleanup() + + +def main(file_loader, env, grafana_version, zip_file, extracted_name): + UPGRADE_VERSION = OSS_UPGRADE_VERSION + GRAFANA_VERSION = grafana_version + PRODUCT_NAME = OSS_PRODUCT_NAME + # PRODUCT_VERSION=GRAFANA_VERSION + # MSI version cannot have anything other + # than a x.x.x.x format, numbers only + PRODUCT_VERSION = GRAFANA_VERSION.split('-')[0] + + config = { + 'grafana_version': PRODUCT_VERSION, + 'upgrade_code': UPGRADE_VERSION, + 'product_name': PRODUCT_NAME, + 'manufacturer': 'Grafana Labs' + } + features = [ + { + 'name': 'GrafanaOSS', + 'title': PRODUCT_NAME, + 'component_groups': [ + { + 'ref_id': 'GrafanaX64', + 'directory': 'GrafanaX64Dir' + } + ] + }, + { + 'name': 'GrafanaService', + 'title': 'Run Grafana as a Service', + 'component_groups': [ + { + 'ref_id': 'GrafanaServiceX64', + 'directory': 'GrafanaServiceX64Dir' + } + ] + } + ] + build_oss(zip_file, extracted_name, PRODUCT_VERSION, config, features) + + +if __name__ == '__main__': + print('MSI Generator Version: {}'.format(MSI_GENERATOR_VERSION)) + + parser = argparse.ArgumentParser( + description='Grafana MSI Generator', + formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=90, width=110), add_help=True) + parser.add_argument( + '-p', + '--premium', + help='Include premium plugins', + dest='premium', action='store_true') + parser.add_argument( + '-e', + '--enterprise', + help='Use Enterprise build', + dest='enterprise', + action='store_true') + parser.set_defaults(enterprise=False, premium=False) + parser.add_argument('-b', '--build', help='build to download') + args = parser.parse_args() + file_loader = FileSystemLoader('templates') + env = Environment(loader=file_loader) + grafana_version = None + grafana_hash = None + is_enterprise = False + if not os.path.isdir(DIST_LOCATION): + os.mkdir(DIST_LOCATION) + # if a build version is specified, pull it + if args.build: + grafana_version = args.build + print('Version Specified: {}'.format(grafana_version)) + else: + grafana_version, grafana_hash, is_enterprise = detect_version(DIST_LOCATION) + + # check for enterprise flag + if args.enterprise: + grafana_version = 'enterprise-{}'.format(args.build) + # + print('Detected Version: {}'.format(grafana_version)) + if grafana_hash: + print('Detected Hash: {}'.format(grafana_hash)) + print('Enterprise: {}'.format(is_enterprise)) + if is_enterprise: + zip_file = '{}/grafana-enterprise-{}.windows-amd64.zip'.format(DIST_LOCATION, grafana_version) + extracted_name = 'grafana-enterprise-{}'.format(grafana_version) + else: + # the file can have a build hash + if grafana_hash: + zip_file = '{}/grafana-{}-{}.windows-amd64.zip'.format(DIST_LOCATION, grafana_version, grafana_hash) + extracted_name = 'grafana-{}-{}'.format(grafana_version, grafana_hash) + else: + zip_file = '{}/grafana-{}.windows-amd64.zip'.format(DIST_LOCATION, grafana_version) + extracted_name = 'grafana-{}'.format(grafana_version) + print('ZipFile: {}'.format(zip_file)) + # check if file downloaded + + if not os.path.isfile(zip_file): + zip_file = get_zip(grafana_version, zip_file) + main(file_loader, env, grafana_version, zip_file, extracted_name) diff --git a/scripts/build/ci-msi-build/oss/generator/utils.py b/scripts/build/ci-msi-build/oss/generator/utils.py new file mode 100644 index 00000000000..da4a00f89fc --- /dev/null +++ b/scripts/build/ci-msi-build/oss/generator/utils.py @@ -0,0 +1,123 @@ +import zipfile +import os +import glob +import re +import shutil +import wget +from jinja2 import Template, Environment, FileSystemLoader + + + +def extract_zip(filename, target_dir): + with zipfile.ZipFile(filename, 'r') as zip_ref: + zip_ref.extractall(target_dir) + + +def get_nssm(tmpPath, version): + if not os.path.isdir(tmpPath): + os.mkdir(tmpPath) + target_filename = '{}/nssm-{}.zip'.format(tmpPath, version) + exists = os.path.isfile(target_filename) + if exists: + return target_filename + url = 'https://nssm.cc/release/nssm-{}.zip'.format(version) + print('NSSM url is {}'.format(url)) + filename = wget.download(url, out=target_filename, bar=wget.bar_thermometer) + return filename + + +def get_zip(version, target_filename): + exists = os.path.isfile(target_filename) + if exists: + return target_filename + url = 'https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-{}.windows-amd64.zip'.format(version) + #url = 'https://dl.grafana.com/enterprise/release/grafana-enterprise-{}.windows-amd64.zip'.format(version) + filename = wget.download(url, out=target_filename, bar=wget.bar_thermometer) + return filename + + +# +# +# +def detect_version(dist_path): + detectedVersion = '' + detectedHash = '' + isEnterprise = False + print("Detecting Version...") + # grafana-6.0.0-ca0bc2c5pre3.windows-amd64.zip + # get files in directory matching pattern + fileList = glob.glob(dist_path + '/grafana*.windows-amd64.zip') + print(fileList) + if len(fileList) == 0: + print('Skipping detection, no matches') + return + firstFile = fileList[0] + p1 = re.search(r'grafana-(\d\.\d\.\d)\.windows-amd64.zip$', firstFile) + p2 = re.search(r'grafana-(\d\.\d\.\d)-(.*)\.windows-amd64.zip$', firstFile) + if p1: + detectedVersion = p1.group(1) + if p2: + detectedVersion = p2.group(1) + detectedHash = p2.group(2) + return detectedVersion, detectedHash, isEnterprise + + #if os.path.isdir(dist_path + 'enterprise-dist'): + # # grafana-enterprise-6.0.0-29b28127pre3.windows-amd64.zip + # # get files in directory matching pattern + # fileList = glob.glob(dist_path + '/enterprise-dist/grafana*.windows-amd64.zip') + # firstFile = fileList[0] + # p1 = re.search(r'grafana-enterprise-(\d\.\d\.\d)\.windows-amd64.zip$', firstFile) + # p2 = re.search(r'grafana-enterprise-(\d\.\d\.\d)-(.*)\.windows-amd64.zip$', firstFile) + # if p1: + # detectedVersion = p1.group(1) + # isEnterprise = True + # if p2: + # detectedVersion = p2.group(1) + # detectedHash = p2.group(2) + # isEnterprise = True + # return detectedVersion, detectedHash, isEnterprise + + +def generate_product_wxs(env, config, features, scratch_file, target_dir): + template = env.get_template('common/product.wxs.j2') + output = template.render(config=config, features=features) + fh = open(scratch_file, 'w') + fh.write(output) + fh.close() + shutil.copy2(scratch_file, target_dir) + +def generate_service_wxs(env, grafana_version, scratch_file, target_dir, nssm_version='2.24'): + template = env.get_template('common/grafana-service.wxs.j2') + output = template.render(grafana_version=grafana_version, nssm_version=nssm_version) + fh = open(scratch_file, 'w') + fh.write(output) + fh.close() + shutil.copy2(scratch_file, target_dir) + +def generate_firewall_wxs(env, grafana_version, scratch_file, target_dir): + os.system("ls -al templates") + template = env.get_template('common/grafana-firewall.wxs.j2') + output = template.render(grafana_version=grafana_version) + fh = open(scratch_file, 'w') + fh.write(output) + fh.close() + shutil.copy2(scratch_file, target_dir) + + +def generate_oracle_environment_wxs(env, instant_client_version, scratch_file, target_dir): + template = env.get_template('oracle/oracle-environment.wxs.j2') + output = template.render(instant_client_version=instant_client_version) + fh = open(scratch_file, 'w') + fh.write(output) + fh.close() + shutil.copy2(scratch_file, target_dir) + +def copy_static_files(target_dir): + for item in os.listdir('resources/images'): + s = os.path.join('resources/images', item) + d = os.path.join(target_dir, item) + shutil.copy2(s, d) + for item in os.listdir('resources/license'): + s = os.path.join('resources/license', item) + d = os.path.join(target_dir, item) + shutil.copy2(s, d) diff --git a/scripts/build/ci-msi-build/oss/light.exe.config b/scripts/build/ci-msi-build/oss/light.exe.config new file mode 100644 index 00000000000..af2cf98d0e1 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/light.exe.config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/build/ci-msi-build/oss/requirements.txt b/scripts/build/ci-msi-build/oss/requirements.txt new file mode 100644 index 00000000000..0b793f8c109 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/requirements.txt @@ -0,0 +1,3 @@ +Jinja2>=2.10 +MarkupSafe>=1.1.0 +wget>=3.2 diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.bmp b/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.bmp new file mode 100644 index 00000000000..1975e7a492e Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.bmp differ diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.png b/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.png new file mode 100644 index 00000000000..ab262097128 Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_dialog_background.png differ diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_icon.ico b/scripts/build/ci-msi-build/oss/resources/images/grafana_icon.ico new file mode 100644 index 00000000000..6f13cb3210a Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_icon.ico differ diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.bmp b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.bmp new file mode 100644 index 00000000000..b4faabb92de Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.bmp differ diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.png b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.png new file mode 100644 index 00000000000..905d54414f2 Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner.png differ diff --git a/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner_white.bmp b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner_white.bmp new file mode 100644 index 00000000000..c72380151d2 Binary files /dev/null and b/scripts/build/ci-msi-build/oss/resources/images/grafana_top_banner_white.bmp differ diff --git a/scripts/build/ci-msi-build/oss/resources/license/LICENSE.md b/scripts/build/ci-msi-build/oss/resources/license/LICENSE.md new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/resources/license/LICENSE.md @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/scripts/build/ci-msi-build/oss/resources/license/LICENSE.rtf b/scripts/build/ci-msi-build/oss/resources/license/LICENSE.rtf new file mode 100644 index 00000000000..45155af0adf --- /dev/null +++ b/scripts/build/ci-msi-build/oss/resources/license/LICENSE.rtf @@ -0,0 +1,206 @@ +{\rtf1\ansi\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Courier New;}} +{\*\generator Riched20 6.3.9600}\viewkind4\uc1 +\pard\f0\fs22\lang1033\par + Apache License\par + Version 2.0, January 2004\par + http://www.apache.org/licenses/\par +\par + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\par +\par + 1. Definitions.\par +\par + "License" shall mean the terms and conditions for use, reproduction,\par + and distribution as defined by Sections 1 through 9 of this document.\par +\par + "Licensor" shall mean the copyright owner or entity authorized by\par + the copyright owner that is granting the License.\par +\par + "Legal Entity" shall mean the union of the acting entity and all\par + other entities that control, are controlled by, or are under common\par + control with that entity. For the purposes of this definition,\par + "control" means (i) the power, direct or indirect, to cause the\par + direction or management of such entity, whether by contract or\par + otherwise, or (ii) ownership of fifty percent (50%) or more of the\par + outstanding shares, or (iii) beneficial ownership of such entity.\par +\par + "You" (or "Your") shall mean an individual or Legal Entity\par + exercising permissions granted by this License.\par +\par + "Source" form shall mean the preferred form for making modifications,\par + including but not limited to software source code, documentation\par + source, and configuration files.\par +\par + "Object" form shall mean any form resulting from mechanical\par + transformation or translation of a Source form, including but\par + not limited to compiled object code, generated documentation,\par + and conversions to other media types.\par +\par + "Work" shall mean the work of authorship, whether in Source or\par + Object form, made available under the License, as indicated by a\par + copyright notice that is included in or attached to the work\par + (an example is provided in the Appendix below).\par +\par + "Derivative Works" shall mean any work, whether in Source or Object\par + form, that is based on (or derived from) the Work and for which the\par + editorial revisions, annotations, elaborations, or other modifications\par + represent, as a whole, an original work of authorship. For the purposes\par + of this License, Derivative Works shall not include works that remain\par + separable from, or merely link (or bind by name) to the interfaces of,\par + the Work and Derivative Works thereof.\par +\par + "Contribution" shall mean any work of authorship, including\par + the original version of the Work and any modifications or additions\par + to that Work or Derivative Works thereof, that is intentionally\par + submitted to Licensor for inclusion in the Work by the copyright owner\par + or by an individual or Legal Entity authorized to submit on behalf of\par + the copyright owner. For the purposes of this definition, "submitted"\par + means any form of electronic, verbal, or written communication sent\par + to the Licensor or its representatives, including but not limited to\par + communication on electronic mailing lists, source code control systems,\par + and issue tracking systems that are managed by, or on behalf of, the\par + Licensor for the purpose of discussing and improving the Work, but\par + excluding communication that is conspicuously marked or otherwise\par + designated in writing by the copyright owner as "Not a Contribution."\par +\par + "Contributor" shall mean Licensor and any individual or Legal Entity\par + on behalf of whom a Contribution has been received by Licensor and\par + subsequently incorporated within the Work.\par +\par + 2. Grant of Copyright License. Subject to the terms and conditions of\par + this License, each Contributor hereby grants to You a perpetual,\par + worldwide, non-exclusive, no-charge, royalty-free, irrevocable\par + copyright license to reproduce, prepare Derivative Works of,\par + publicly display, publicly perform, sublicense, and distribute the\par + Work and such Derivative Works in Source or Object form.\par +\par + 3. Grant of Patent License. Subject to the terms and conditions of\par + this License, each Contributor hereby grants to You a perpetual,\par + worldwide, non-exclusive, no-charge, royalty-free, irrevocable\par + (except as stated in this section) patent license to make, have made,\par + use, offer to sell, sell, import, and otherwise transfer the Work,\par + where such license applies only to those patent claims licensable\par + by such Contributor that are necessarily infringed by their\par + Contribution(s) alone or by combination of their Contribution(s)\par + with the Work to which such Contribution(s) was submitted. If You\par + institute patent litigation against any entity (including a\par + cross-claim or counterclaim in a lawsuit) alleging that the Work\par + or a Contribution incorporated within the Work constitutes direct\par + or contributory patent infringement, then any patent licenses\par + granted to You under this License for that Work shall terminate\par + as of the date such litigation is filed.\par +\par + 4. Redistribution. You may reproduce and distribute copies of the\par + Work or Derivative Works thereof in any medium, with or without\par + modifications, and in Source or Object form, provided that You\par + meet the following conditions:\par +\par + (a) You must give any other recipients of the Work or\par + Derivative Works a copy of this License; and\par +\par + (b) You must cause any modified files to carry prominent notices\par + stating that You changed the files; and\par +\par + (c) You must retain, in the Source form of any Derivative Works\par + that You distribute, all copyright, patent, trademark, and\par + attribution notices from the Source form of the Work,\par + excluding those notices that do not pertain to any part of\par + the Derivative Works; and\par +\par + (d) If the Work includes a "NOTICE" text file as part of its\par + distribution, then any Derivative Works that You distribute must\par + include a readable copy of the attribution notices contained\par + within such NOTICE file, excluding those notices that do not\par + pertain to any part of the Derivative Works, in at least one\par + of the following places: within a NOTICE text file distributed\par + as part of the Derivative Works; within the Source form or\par + documentation, if provided along with the Derivative Works; or,\par + within a display generated by the Derivative Works, if and\par + wherever such third-party notices normally appear. The contents\par + of the NOTICE file are for informational purposes only and\par + do not modify the License. You may add Your own attribution\par + notices within Derivative Works that You distribute, alongside\par + or as an addendum to the NOTICE text from the Work, provided\par + that such additional attribution notices cannot be construed\par + as modifying the License.\par +\par + You may add Your own copyright statement to Your modifications and\par + may provide additional or different license terms and conditions\par + for use, reproduction, or distribution of Your modifications, or\par + for any such Derivative Works as a whole, provided Your use,\par + reproduction, and distribution of the Work otherwise complies with\par + the conditions stated in this License.\par +\par + 5. Submission of Contributions. Unless You explicitly state otherwise,\par + any Contribution intentionally submitted for inclusion in the Work\par + by You to the Licensor shall be under the terms and conditions of\par + this License, without any additional terms or conditions.\par + Notwithstanding the above, nothing herein shall supersede or modify\par + the terms of any separate license agreement you may have executed\par + with Licensor regarding such Contributions.\par +\par + 6. Trademarks. This License does not grant permission to use the trade\par + names, trademarks, service marks, or product names of the Licensor,\par + except as required for reasonable and customary use in describing the\par + origin of the Work and reproducing the content of the NOTICE file.\par +\par + 7. Disclaimer of Warranty. Unless required by applicable law or\par + agreed to in writing, Licensor provides the Work (and each\par + Contributor provides its Contributions) on an "AS IS" BASIS,\par + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\par + implied, including, without limitation, any warranties or conditions\par + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\par + PARTICULAR PURPOSE. You are solely responsible for determining the\par + appropriateness of using or redistributing the Work and assume any\par + risks associated with Your exercise of permissions under this License.\par +\par + 8. Limitation of Liability. In no event and under no legal theory,\par + whether in tort (including negligence), contract, or otherwise,\par + unless required by applicable law (such as deliberate and grossly\par + negligent acts) or agreed to in writing, shall any Contributor be\par + liable to You for damages, including any direct, indirect, special,\par + incidental, or consequential damages of any character arising as a\par + result of this License or out of the use or inability to use the\par + Work (including but not limited to damages for loss of goodwill,\par + work stoppage, computer failure or malfunction, or any and all\par + other commercial damages or losses), even if such Contributor\par + has been advised of the possibility of such damages.\par +\par + 9. Accepting Warranty or Additional Liability. While redistributing\par + the Work or Derivative Works thereof, You may choose to offer,\par + and charge a fee for, acceptance of support, warranty, indemnity,\par + or other liability obligations and/or rights consistent with this\par + License. However, in accepting such obligations, You may act only\par + on Your own behalf and on Your sole responsibility, not on behalf\par + of any other Contributor, and only if You agree to indemnify,\par + defend, and hold each Contributor harmless for any liability\par + incurred by, or claims asserted against, such Contributor by reason\par + of your accepting any such warranty or additional liability.\par +\par + END OF TERMS AND CONDITIONS\par +\par + APPENDIX: How to apply the Apache License to your work.\par +\par + To apply the Apache License to your work, attach the following\par + boilerplate notice, with the fields enclosed by brackets "[]"\par + replaced with your own identifying information. (Don't include\par + the brackets!) The text should be enclosed in the appropriate\par + comment syntax for the file format. We also recommend that a\par + file or class name and description of purpose be included on the\par + same "printed page" as the copyright notice for easier\par + identification within third-party archives.\par +\par + Copyright [yyyy] [name of copyright owner]\par +\par + Licensed under the Apache License, Version 2.0 (the "License");\par + you may not use this file except in compliance with the License.\par + You may obtain a copy of the License at\par +\par + http://www.apache.org/licenses/LICENSE-2.0\par +\par + Unless required by applicable law or agreed to in writing, software\par + distributed under the License is distributed on an "AS IS" BASIS,\par + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\par + See the License for the specific language governing permissions and\par + limitations under the License.\par +} + \ No newline at end of file diff --git a/scripts/build/ci-msi-build/oss/templates/common/grafana-firewall.wxs.j2 b/scripts/build/ci-msi-build/oss/templates/common/grafana-firewall.wxs.j2 new file mode 100644 index 00000000000..9dd0c0396ef --- /dev/null +++ b/scripts/build/ci-msi-build/oss/templates/common/grafana-firewall.wxs.j2 @@ -0,0 +1,19 @@ + + + + + + + + + + + + diff --git a/scripts/build/ci-msi-build/oss/templates/common/grafana-service.wxs.j2 b/scripts/build/ci-msi-build/oss/templates/common/grafana-service.wxs.j2 new file mode 100644 index 00000000000..7fec83be3c5 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/templates/common/grafana-service.wxs.j2 @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + LOG_LEVEL=DEBUG + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/build/ci-msi-build/oss/templates/common/product.wxs.j2 b/scripts/build/ci-msi-build/oss/templates/common/product.wxs.j2 new file mode 100644 index 00000000000..cd464804ef1 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/templates/common/product.wxs.j2 @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + {% for feature in features %} + {% for component_group in feature.component_groups %} + + {% endfor %} + {% endfor %} + + + + + + {% for feature in features %} + + {% for component_group in feature.component_groups %} + + {% endfor %} + + {% endfor %} + + + + + + + diff --git a/scripts/build/ci-msi-build/oss/templates/oracle/oracle-environment.wxs.j2 b/scripts/build/ci-msi-build/oss/templates/oracle/oracle-environment.wxs.j2 new file mode 100644 index 00000000000..65c9a2be2c9 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/templates/oracle/oracle-environment.wxs.j2 @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/scripts/build/ci-msi-build/oss/wrapper.sh b/scripts/build/ci-msi-build/oss/wrapper.sh new file mode 100755 index 00000000000..c92835a4b45 --- /dev/null +++ b/scripts/build/ci-msi-build/oss/wrapper.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd /oss +make