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