Last active
September 26, 2022 17:19
-
-
Save LukeMurphey/8fd02337805ae8762afb to your computer and use it in GitHub Desktop.
A basic Ant build file that contains targets useful for building Splunk apps that managed with Git. Tags: #splunk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This Ant build script contains operations that are useful for building Splunk apps from source-code. | |
See the following page for some more documentation: https://github.com/LukeMurphey/splunk-ant-build-script/blob/master/README.md | |
This is licensed under the Apache License Version 2.0 | |
See https://www.apache.org/licenses/LICENSE-2.0.html | |
To use it with you app, do the following: | |
1) Run the start_project build target like this: | |
ant -f basebuild.xml start_project | |
2) Test your build by running the new build script that has been made: | |
ant | |
This should produce a file in the tmp/packages directory. From now on, re-run the "ant" command (no argument needed) to produce a fresh package. | |
====================================================== | |
Syncing your source code to a local Splunk install | |
====================================================== | |
The build script provides some tools to help you send your code to a local Splunk install for testing. This allows you to send the code from the | |
app you are writing to a live Splunk install to see the running changes. To use this, edit the "local.properties" file and declare the location of your | |
Splunk install, like this: | |
value.deploy.splunk_home=/Users/luke_murphey/Applications/Splunk | |
Once you do that, run the following build target to have your code sent to your Splunk install: | |
ant deploy | |
See the section on build targets below for some other useful targets. | |
====================================================== | |
Defining build properties | |
====================================================== | |
You can set override the default behavior of the build script by setting the parameters in a local.properties file. Additionally, you can set them | |
via environment variables (useful when running tests in a continuous integration environment). | |
Here are the most important parameters: | |
╔═════════════════════════════════════╦══════════════════════╦══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╦═══════════════╦════════════════════════╗ | |
║ Property file ║ Environment variable ║ Description ║ Default value ║ Example Value ║ | |
╠═════════════════════════════════════╬══════════════════════╬══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╬═══════════════╬════════════════════════╣ | |
║ value.deploy.splunk_home ║ SPLUNK_HOME ║ Indicates where the Splunk install is to use for testing ║ ║ /Applications/Splunk/ ║ | |
║ value.build.packageoutput.directory ║ OUTPUT_DIRECTORY ║ Indicates where the place the created package; set when you don't want the created package to be in the /tmp directory ║ /tmp/packages ║ /Users/luke/Desktop/ ║ | |
║ value.version.number ║ ║ Indicates the version number to use (if you want to ${value.version.number} to be substituted in the txt and conf files) ║ ║ 2.0.1 ║ | |
║ value.deploy.splunkweb_url ║ SPLUNKWEB_URL ║ Indicates the base URL for Splunk Web ║ ║ http://127.0.0.1:8000 ║ | |
║ value.deploy.splunkd_url ║ SPLUNKD_URL ║ Indicates the base URL for Splunkd ║ ║ https://127.0.0.1:8089 ║ | |
║ value.deploy.splunk_username ║ SPLUNK_USERNAME ║ Indicates the username to use for authenticating with Splunk ║ ║ admin ║ | |
║ value.deploy.splunk_password ║ SPLUNK_PASSWORD ║ Indicates the password to use for authenticating with Splunk ║ ║ changeme ║ | |
╚═════════════════════════════════════╩══════════════════════╩══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩═══════════════╩════════════════════════╝ | |
Here are some other supported variables: | |
╔══════════════════════════════╦══════════════════════╦═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╦══════════════════════════════════════════════╗ | |
║ Property file ║ Environment variable ║ Description ║ Default value ║ | |
╠══════════════════════════════╬══════════════════════╬═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╬══════════════════════════════════════════════╣ | |
║ value.build.minimize ║ BUILD_MINIMIZED ║ If set to 1 or true, the JS and CSS in the package will be minimized ║ true (code is minified automatically) ║ | |
║ value.deploy.minimize ║ ║ If set to 1 or true, the JS and CSS will be minimized when copying to your local Splunk build for testing ║ true (code is minified automatically) ║ | |
║ value.src.directory ║ ║ The directory containing the source-code ║ /src ║ | |
║ value.build.number ║ ║ The build number to use (if you want to ${value.build.number} to be substituted in the txt and conf files) ║ Generated the date of the last change in git ║ | |
║ value.build.package.file ║ PACKAGE_FILE ║ The resulting file that will be created or the file that will be installed via splunk.install ║ A file in tmp/packages ║ | |
║ value.build.package.username ║ PACKAGE_USERNAME ║ The username to use when downloading the package (if it was a URL) ║ ║ | |
║ value.build.package.password ║ PACKAGE_PASSWORD ║ The password to use when downloading the package ║ ║ | |
║ skip_bump ║ ║ Indicates if the build script shouldn't try to bump the web-server in order to prevent SplunkWeb from returning old files ║ ║ | |
║ value.build.test.directory ║ TEST_DIRECTORY ║ Indicates where the tests reside ║ ║ | |
║ value.build.app_bin ║ ║ Indicates the directory where Python libraries from a requirements.txt ought to be placed ║ src/bin ║ | |
╚══════════════════════════════╩══════════════════════╩═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╩══════════════════════════════════════════════╝ | |
====================================================== | |
Build targets | |
====================================================== | |
Below are the main build targets you should consider using: | |
╔════════════════════════════╦═════════════════════════════════════════════════════════════════════════════╦══════════════════════════╗ | |
║ Build Target ║ Description ║ Required Properties ║ | |
╠════════════════════════════╬═════════════════════════════════════════════════════════════════════════════╬══════════════════════════╣ | |
║ package ║ Create an installable Splunk package ║ ║ | |
║ deploy ║ Exports the app to a live Splunk install ║ value.deploy.splunk_home ║ | |
║ splunk.refresh ║ Tells Splunk to refresh itself so that changes to views appear ║ value.deploy.splunk_home ║ | |
║ splunk.start ║ Starts Splunk ║ value.deploy.splunk_home ║ | |
║ splunk.stop ║ Stops Splunk ║ value.deploy.splunk_home ║ | |
║ splunk.restart ║ Restarts Splunk ║ value.deploy.splunk_home ║ | |
║ splunk.restart_web ║ Restarts SplunkWeb ║ value.deploy.splunk_home ║ | |
║ test ║ Runs tests and btool for the given app ║ value.deploy.splunk_home ║ | |
║ test.deploy_and_test ║ Same as above but deploys to Splunk first so that it has the latest changes ║ value.deploy.splunk_home ║ | |
╚════════════════════════════╩═════════════════════════════════════════════════════════════════════════════╩══════════════════════════╝ | |
====================================================== | |
Having the build script set your version & build numbers | |
====================================================== | |
To use the generated build number, put ${value.build.number} in your file where you want the string replacement to occur. For example, below a | |
snippet from app.conf that will be populated with the build number: | |
[install] | |
build = ${value.build.number} | |
You can also use ${value.version.number} to substitute your version number in app.conf: | |
[launcher] | |
version = ${value.version.number} | |
--> | |
<project default="start_project" name="basebuild"> | |
<!-- Define some things so that we can import things from environment variables --> | |
<property environment="env" /> | |
<macrodef name="import_environment_var"> | |
<attribute name="property" /> | |
<attribute name="variable" /> | |
<sequential> | |
<condition property="@{property}" value="${env.@{variable}}"> | |
<isset property="env.@{variable}" /> | |
</condition> | |
</sequential> | |
</macrodef> | |
<!-- ================================= | |
target: download_git_ignore | |
================================= --> | |
<target name="download_git_ignore" depends="initialize_properties" description="Download a default gitignore tailored for Splunk apps"> | |
<get src="https://gist.githubusercontent.com/LukeMurphey/410031b0a1e9df33853e3b605fd0e46d/raw/.gitignore" | |
dest="${basedir}/.gitignore" | |
verbose="true" | |
skipexisting="true" /> | |
</target> | |
<!-- ================================= | |
target: start_project | |
================================= --> | |
<target name="start_project" depends="initialize" description="Start a new Splunk app project; initialize a build script, download dependencies, etc."> | |
<!-- Make sure that the build script doesn't already exist --> | |
<fail message="A build script already seems to exist"> | |
<condition> | |
<available file="${basedir}/build.xml" type="dir"/> | |
</condition> | |
</fail> | |
<!-- Get the app name --> | |
<input | |
message="Please enter the name of the Splunk app you are creating. This should be the directory name and shouldn't include a space (e.g. website_monitoring):" | |
addproperty="app_name" | |
/> | |
<condition property="app_name_empty"> | |
<equals arg1="" arg2="${app_name}"/> | |
</condition> | |
<fail if="app_name_empty">No app name was provided, cannot proceed</fail> | |
<!-- Make the build script --> | |
<echo file="${basedir}/build.xml"> | |
<![CDATA[<project default="package" name="${app_name}"> | |
<import file="basebuild.xml"/> | |
</project>]]> | |
</echo> | |
<!-- Make the source code directory (if necessary) --> | |
<mkdir dir="${value.src.directory}" /> | |
<!-- Make the default.properties file --> | |
<echo file="${basedir}/default.properties"> | |
value.build.packageoutput.directory=tmp/packages | |
value.build.optimize=true | |
</echo> | |
<!-- Make the local.properties file --> | |
<echo file="${basedir}/local.properties"> | |
# Uncomment the file below and define the location of your Splunk installation in local.properties so that you | |
# can deploy the application to a Splunk installation automatically: | |
# value.deploy.splunk_home=C:/Program Files/Splunk | |
# Change the following to match your install of Splunk if you want the build script to force Splunk to recognize new web-content automatically | |
value.deploy.splunkd_url=https://127.0.0.1:8089 | |
value.deploy.splunkweb_url=http://127.0.0.1:8000 | |
value.deploy.splunk_username=admin | |
value.deploy.splunk_password=changeme | |
</echo> | |
<antcall target="download_libraries" /> | |
<antcall target="download_git_ignore" /> | |
<echo>Success! | |
A build script has been setup. To run your build run the following: | |
ant | |
Place the source-code of your app in the following "src" directory, a.k.a: | |
${absolute_src_path} | |
You can customize the build process by placing properties in the default.properties file or the local.properties files.</echo> | |
</target> | |
<!-- ================================= | |
target: download_libraries | |
================================= --> | |
<target name="download_libraries" depends="initialize_properties"> | |
<!-- Make sure the directory to store the library files exists --> | |
<mkdir dir="${absolute_lib_path}" /> | |
<get src="https://lukemurphey.net/attachments/download/402/ant-contrib-0.6.jar" | |
dest="${absolute_lib_path}/ant-contrib-0.6.jar" | |
verbose="true" | |
skipexisting="true" /> | |
<get src="https://lukemurphey.net/attachments/download/403/yuicompressor-2.4.7.jar" | |
dest="${absolute_lib_path}/yuicompressor-2.4.7.jar" | |
verbose="true" | |
skipexisting="true" /> | |
<get src="https://lukemurphey.net/attachments/download/404/yuicompressor-2.4.8.jar" | |
dest="${absolute_lib_path}/yuicompressor-2.4.8.jar" | |
verbose="true" | |
skipexisting="true" /> | |
<get src="https://github.com/LukeMurphey/splunk-ant-build-script/releases/download/1.1/splunkdevtools-1.1.jar" | |
dest="${absolute_lib_path}/splunkdevtools-1.1.jar" | |
verbose="true" | |
skipexisting="true" /> | |
</target> | |
<!-- ================================= | |
target: initialize_libraries | |
================================= --> | |
<target name="initialize_libraries" depends="download_libraries"> | |
<taskdef resource="net/sf/antcontrib/antlib.xml"> | |
<classpath> | |
<pathelement location="${absolute_lib_path}/ant-contrib-0.6.jar"/> | |
</classpath> | |
</taskdef> | |
<taskdef name="splunkwebbump" classname="net.lukemurphey.splunkbuild.SplunkWebBump" classpath="${absolute_lib_path}/splunkdevtools-1.1.jar" /> | |
<taskdef name="splunkrestart" classname="net.lukemurphey.splunkbuild.SplunkRestart" classpath="${absolute_lib_path}/splunkdevtools-1.1.jar" /> | |
<taskdef name="splunkappinstall" classname="net.lukemurphey.splunkbuild.SplunkAppInstall" classpath="${absolute_lib_path}/splunkdevtools-1.1.jar" /> | |
</target> | |
<!-- ================================= | |
target: initialize | |
================================= --> | |
<target name="initialize" depends="initialize_properties,download_libraries,initialize_libraries" /> | |
<!-- ================================= | |
target: make_package_name | |
================================= --> | |
<target name="make_package_name"> | |
<property name="value.build.package.file" value="${value.build.packageoutput.directory}/${value.build.appname}.tar.gz" /> | |
</target> | |
<!-- ================================= | |
target: initialize_local_properties | |
================================= --> | |
<target name="initialize_local_properties"> | |
<!-- | |
Load the properties files, local is loaded first since properties are immutable (cannot be changed | |
by later property files) and we want the local properties to override the default properties | |
--> | |
<property file="local.properties" /> | |
</target> | |
<!-- ================================= | |
target: initialize_environment_properties | |
================================= --> | |
<target name="initialize_environment_properties"> | |
<!-- Import some parameters from environment variables --> | |
<import_environment_var property="value.deploy.splunk_home" variable="SPLUNK_HOME" /> | |
<import_environment_var property="value.deploy.splunkweb_url" variable="SPLUNKWEB_URL" /> | |
<import_environment_var property="value.deploy.splunkd_url" variable="SPLUNKD_URL" /> | |
<import_environment_var property="value.deploy.splunk_username" variable="SPLUNK_USERNAME" /> | |
<import_environment_var property="value.deploy.splunk_password" variable="SPLUNK_PASSWORD" /> | |
<import_environment_var property="value.build.packageoutput.directory" variable="OUTPUT_DIRECTORY" /> | |
<import_environment_var property="value.build.minimize" variable="BUILD_MINIMIZED" /> | |
<import_environment_var property="value.deploy.minimize" variable="DEPLOY_MINIMIZED" /> | |
<import_environment_var property="value.build.package.file" variable="PACKAGE_FILE" /> | |
<import_environment_var property="value.build.package.username" variable="PACKAGE_USERNAME" /> | |
<import_environment_var property="value.build.package.password" variable="PACKAGE_PASSWORD" /> | |
<import_environment_var property="value.build.test.directory" variable="TEST_DIRECTORY" /> | |
</target> | |
<!-- ================================= | |
target: initialize_default_properties | |
================================= --> | |
<target name="initialize_default_properties"> | |
<property file="default.properties" /> | |
</target> | |
<!-- ================================= | |
target: initialize_property_defaults | |
================================= --> | |
<target name="initialize_property_defaults"> | |
<!-- Set some default values in case they were not set in the default.properties file --> | |
<property name="value.build.packageoutput.directory" value="tmp/packages" /> | |
<property name="value.build.optimize" value="true" /> | |
<property name="value.deploy.splunkweb_url" value="http://127.0.0.1:8000" /> | |
<property name="value.deploy.splunkd_url" value="https://127.0.0.1:8089" /> | |
<property name="value.deploy.splunk_username" value="admin" /> | |
<property name="value.deploy.splunk_password" value="changeme" /> | |
<property name="value.build.test.directory" value="tests" /> | |
<!-- Set up some basic properties that are internal to this build script --> | |
<property name="value.src.directory" value="src" /> | |
<property name="absolute_src_path" location="${value.src.directory}"/> <!-- This is an absolute version of the file path for error messages --> | |
<property name="value.temp.directory" value="${java.io.tmpdir}/${user.name}" /> | |
<property name="value.build.appname" value="${ant.project.name}" /> | |
<property name="value.build.libraries" value="${basedir}/lib" /> | |
<property name="absolute_lib_path" location="${value.build.libraries}"/> | |
<property name="value.build.app_bin" value="${value.src.directory}/bin/${value.build.appname}_app" /> | |
</target> | |
<!-- ================================= | |
target: initialize_properties | |
================================= --> | |
<target name="initialize_properties" depends="initialize_local_properties,initialize_environment_properties,initialize_default_properties,initialize_property_defaults,make_package_name"> | |
<!-- | |
Properties will be loaded in the following order with the first one taking precedence: | |
* local.properties | |
* Environment variables | |
* default.properties | |
--> | |
<!-- Set up the ant classpath --> | |
<path id="ant.classpath"> | |
<fileset dir="ant"> | |
<include name="*.jar" /> | |
</fileset> | |
</path> | |
</target> | |
<!-- ================================= | |
target: clean | |
================================= --> | |
<target name="clean" depends="initialize_properties" description="Clean up temporary files and directories created by this build script" > | |
<!-- Delete the temporary directory --> | |
<delete quiet="true" includeEmptyDirs="true"> | |
<fileset dir="${value.temp.directory}" /> | |
</delete> | |
<!-- Delete the local directory where packages are placed --> | |
<delete quiet="true" includeEmptyDirs="true"> | |
<fileset dir="tmp" /> | |
</delete> | |
<!-- Delete the downloaded build dependencies --> | |
<delete file="${absolute_lib_path}/ant-contrib-0.6.jar" /> | |
<delete file="${absolute_lib_path}/yuicompressor-2.4.7.jar" /> | |
<delete file="${absolute_lib_path}/yuicompressor-2.4.8.jar" /> | |
<delete file="${absolute_lib_path}/splunkdevtools-1.1.jar" /> | |
</target> | |
<!-- ================================= | |
target: get_build_number | |
================================= --> | |
<target name="get_build_number" depends="initialize"> | |
<macrodef name="get_build_info"> | |
<attribute name="path" default="${user.dir}" /> | |
<attribute name="format" default="ct" /> | |
<attribute name="outputproperty" /> | |
<sequential> | |
<exec failonerror="true" executable="git" outputproperty="@{outputproperty}"> <!-- Fail on error is set to true in order to prevent a bad build number from being included --> | |
<arg value="log"/> | |
<arg value="-1"/> | |
<arg value="--pretty=format:%@{format}"/> | |
<arg value="--abbrev-commit"/> | |
<arg value="@{path}"/> | |
</exec> | |
</sequential> | |
</macrodef> | |
<!-- Determine if this project is using Git and get the build info accordingly --> | |
<if> | |
<available file=".git" type="dir" /> | |
<!-- Run git to get the revision number and date --> | |
<then> | |
<get_build_info outputproperty="value.build.number" /> | |
<get_build_info format="cD" outputproperty="value.build.date" /> | |
</then> | |
<!-- Generate the revision number and date --> | |
<else> | |
<echo message=".git directory does not exist; build date will be set to the current date" /> | |
<tstamp> | |
<!-- 1492116038 (Thu, 13 Apr 2017 15:40:38 -0500) --> | |
<format property="value.build.date" pattern="E, d MMM YYYY HH:mm:ss Z" unit="hour" /> | |
</tstamp> | |
<script language="javascript"> | |
<![CDATA[ | |
property = project.setProperty("value.build.number",Math.floor((new Date()).getTime()/1000)); | |
]]> | |
</script> | |
</else> | |
</if> | |
<echo>Revision number is: ${value.build.number} (${value.build.date})</echo> | |
</target> | |
<!-- ================================= | |
target: clean.packages | |
================================= --> | |
<target name="clean.packages" depends="initialize_properties" description="Clean up the packages created by this build script"> | |
<delete quiet="true" includeEmptyDirs="true"> | |
<fileset dir="tmp/packages" /> | |
</delete> | |
</target> | |
<!-- ================================= | |
target: link (links the src directory to the Splunk install) | |
================================= --> | |
<target name="link" depends="initialize_libraries"> | |
<shellscript shell="bash" dir="${value.src.directory}"> | |
ln -s $PWD ${value.deploy.splunk_home}/etc/apps/${value.build.appname} | |
</shellscript> | |
</target> | |
<!-- ================================= | |
target: setup_tmp_directory_for_export | |
================================= --> | |
<target name="setup_tmp_directory_for_export" depends="initialize_properties"> | |
<!-- Create a temporary directory to send the files to --> | |
<property name="export_dir" value="${value.temp.directory}/package" /> | |
<!-- Create the temporary directory --> | |
<mkdir dir="${export_dir}"/> | |
</target> | |
<patternset id="substituted_files"> | |
<include name="**/*.conf" /> | |
<include name="**/*.txt" /> | |
<include name="**/*.xml" /> | |
</patternset> | |
<patternset id="exclude_substituted_files"> | |
<exclude name="**/*.conf" /> | |
<exclude name="**/*.txt" /> | |
<exclude name="**/*.xml" /> | |
</patternset> | |
<patternset id="minified_files"> | |
<include name="**/*.js" /> | |
<include name="**/*.css" /> | |
</patternset> | |
<patternset id="exclude_minified_files"> | |
<exclude name="**/*.js" /> | |
<exclude name="**/*.css" /> | |
</patternset> | |
<!-- ================================= | |
target: does_requirementstxt_exist | |
================================= --> | |
<target name="does_requirementstxt_exist"> | |
<condition property="requirements_txt_exists"> | |
<available file="${basedir}/requirements.txt" type="file"/> | |
</condition> | |
</target> | |
<!-- ================================= | |
target: install_reqs | |
================================= --> | |
<target name="install_reqs" depends="initialize_properties,does_requirementstxt_exist" if="requirements_txt_exists" description="Installs Python libraries per the requirements.txt."> | |
<echo file="${value.build.app_bin}/__init__.py"></echo> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="cmd" /> | |
<arg line="python" /> | |
<arg line="-m" /> | |
<arg line="pip" /> | |
<arg line="install" /> | |
<arg value="-r"/> | |
<arg value="requirements.txt"/> | |
<arg value="-t"/> | |
<arg value="${value.build.app_bin}"/> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: upgrade_reqs | |
================================= --> | |
<target name="upgrade_reqs" depends="initialize_properties" description="Upgrades the Python libraries per the requirements.txt."> | |
<echo file="${value.build.app_bin}/__init__.py"></echo> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="cmd" /> | |
<arg line="python" /> | |
<arg line="-m" /> | |
<arg line="pip" /> | |
<arg line="install" /> | |
<arg value="-r"/> | |
<arg value="requirements.txt"/> | |
<arg value="-t"/> | |
<arg value="${value.build.app_bin}"/> | |
<arg value="--upgrade"/> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: populate_export_dir | |
================================= --> | |
<target name="populate_export_dir" depends="initialize,get_build_number,install_reqs,compile"> | |
<!-- Make sure that the source directory exists --> | |
<fail message="The directory where the source-code is supposed to be doesn't exist ('${absolute_src_path}')"> | |
<condition> | |
<not> | |
<available file="${absolute_src_path}" type="dir"/> | |
</not> | |
</condition> | |
</fail> | |
<!-- Copy the files over that need substitution. This should only be | |
applied to text files since Ant may corrupt binary files otherwise. --> | |
<copy todir="${export_dir}/${value.build.appname}"> | |
<fileset dir="${value.src.directory}"> | |
<patternset refid="substituted_files" /> | |
</fileset> | |
<!-- Perform the substitution of the build information --> | |
<filterset begintoken="${" endtoken="}"> | |
<filter token="value.build.number" value="${value.build.number}" /> | |
<filter token="value.build.date" value="${value.build.date}" /> | |
<filter token="value.version.number" value="${value.version.number}" /> | |
</filterset> | |
</copy> | |
<!-- Copy the binary files over (excluding the javascript files which are to be minified) --> | |
<copy todir="${export_dir}/${value.build.appname}"> | |
<fileset dir="${value.src.directory}"> | |
<patternset refid="exclude_substituted_files" /> | |
<patternset refid="exclude_minified_files" /> | |
</fileset> | |
</copy> | |
<!-- Determine if this is Windows --> | |
<condition property="is_windows" else="false"> | |
<os family="windows"/> | |
</condition> | |
<!-- If this is Windows, use yuicompressor 2.4.7 since 2.4.8 doesn't support Windows paths correctly --> | |
<if> | |
<equals arg1="${is_windows}" arg2="false" /> | |
<then> | |
<property name="yuicompressorlib" value="lib/yuicompressor-2.4.8.jar" /> | |
</then> | |
<else> | |
<property name="yuicompressorlib" value="lib/yuicompressor-2.4.7.jar" /> | |
</else> | |
</if> | |
<!-- Deploy the CSS and JS (and optionally minimize it) --> | |
<if> | |
<or> | |
<equals arg1="${minimize}" arg2="true" /> | |
<equals arg1="${minimize}" arg2="1" /> | |
</or> | |
<then> | |
<!-- The mapper to map the original source files to the minified versions with the same name, but different path --> | |
<mapper id="to_export_dir_mapper" type="glob" from="*" to="${export_dir}/${value.build.appname}/*" /> | |
<!-- Minify the Javascript files --> | |
<apply executable="java" parallel="false"> | |
<!-- Source of the files --> | |
<fileset dir="${basedir}/src"> | |
<patternset refid="minified_files" /> | |
</fileset> | |
<arg line="-jar" /> | |
<arg path="${yuicompressorlib}" /> | |
<srcfile /> | |
<arg line="-o"/> | |
<mapper refid="to_export_dir_mapper" /> | |
<targetfile /> | |
</apply> | |
</then> | |
<else> | |
<!-- Copy the unoptimized files over --> | |
<copy todir="${export_dir}/${value.build.appname}"> | |
<fileset dir="${value.src.directory}"> | |
<patternset refid="minified_files" /> | |
</fileset> | |
</copy> | |
</else> | |
</if> | |
</target> | |
<!-- ================================= | |
target: set_minimize_for_package | |
================================= --> | |
<target name="set_minimize_for_package" depends="initialize_properties"> | |
<property name="minimize" value="${value.build.minimize}"/> | |
</target> | |
<!-- ================================= | |
target: compile target for any custom compilation things needed | |
================================= --> | |
<target name="compile" depends="initialize_properties" /> | |
<!-- ================================= | |
target: package | |
================================= --> | |
<target name="package" depends="initialize_properties,setup_tmp_directory_for_export,set_minimize_for_package,populate_export_dir" description="Create the Splunk package of the app"> | |
<!-- Make the directory where we will store the files --> | |
<mkdir dir="${value.build.packageoutput.directory}" /> | |
<!-- Define where the tar file will go --> | |
<property name="value.temp.tar_package.file" value="${value.temp.directory}/${value.build.appname}.tar" /> | |
<!-- Tar the files --> | |
<tar destfile="${value.temp.tar_package.file}"> | |
<tarfileset dir="${export_dir}" filemode="755"> | |
<include name="**/*.sh" /> | |
</tarfileset> | |
<tarfileset dir="${export_dir}"> | |
<exclude name="**/*.sh" /> | |
<exclude name="**/*.pyc" /> | |
<exclude name="**/*.tmp" /> | |
</tarfileset> | |
</tar> | |
<!-- Gzip the files --> | |
<gzip src="${value.temp.tar_package.file}" destfile="${value.build.package.file}"/> | |
<!-- Delete the temporary location so that old files do not get streamed in --> | |
<delete dir="${value.temp.directory}" /> | |
<echo>App ${value.build.appname} build ${value.build.number} created: ${value.build.package.file}</echo> | |
</target> | |
<!-- ================================= | |
target: setup_tmp_directory_for_deployment | |
================================= --> | |
<target name="setup_tmp_directory_for_deployment" depends="initialize_properties"> | |
<!-- Create a reference to the directory to send the files to --> | |
<property name="export_dir" value="${value.deploy.splunk_home}/etc/apps" /> | |
<!-- Make the app directory if it does not yet exist --> | |
<mkdir dir="${export_dir}" /> | |
</target> | |
<!-- ================================= | |
target: skip_bump | |
================================= --> | |
<target name="skip_bump"> | |
<property name="skip_bump">1</property> | |
</target> | |
<!-- ================================= | |
target: set_minimize_for_deploy | |
================================= --> | |
<target name="set_minimize_for_deploy" depends="initialize_properties"> | |
<property name="minimize" value="${value.deploy.minimize}"/> | |
</target> | |
<!-- ================================= | |
target: verify_splunk_home | |
================================= --> | |
<target name="verify_splunk_home" depends="initialize_properties"> | |
<fail unless="value.deploy.splunk_home"> | |
"value.deploy.splunk_home" has not been defined | |
Declare it in the a local.properties file in the following path: | |
${absolute_src_path}/local.properties | |
Below is an example of the entry in the file: | |
value.deploy.splunk_home=/Applications/Splunk | |
</fail> | |
</target> | |
<!-- ================================= | |
target: clear_app_dir | |
================================= --> | |
<target name="clear_app_dir" depends="initialize_properties,verify_splunk_home,setup_tmp_directory_for_deployment"> | |
<delete failonerror="false" quiet="false" includeemptydirs="true"> | |
<fileset dir="${export_dir}/${value.build.appname}"> | |
<include name="**/*"/> | |
<exclude name="local/**"/> | |
<exclude name="metadata/local.meta"/> | |
</fileset> | |
</delete> | |
</target> | |
<!-- ================================= | |
target: deploy | |
================================= --> | |
<target name="deploy" depends="initialize_properties,verify_splunk_home,splunk.bump_if_necessary,setup_tmp_directory_for_deployment,clear_app_dir,set_minimize_for_deploy,populate_export_dir" description="Deploys the app to an instance of Splunk" > | |
<!-- Set the permissions for *nix hosts --> | |
<chmod perm="755"> | |
<fileset dir="${export_dir}/${value.build.appname}"> | |
<include name="**/*.sh"/> | |
</fileset> | |
</chmod> | |
<echo>App ${value.build.appname} build ${value.build.number} deployed to ${export_dir}</echo> | |
</target> | |
<!-- ================================= | |
target: splunk.stop | |
================================= --> | |
<target name="splunk.stop" description="Stop Splunk" depends="initialize_properties,verify_splunk_home"> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="stop" /> | |
<arg line="--accept-license" /> | |
</exec> | |
</target> | |
<!-- =================================================================== | |
target: splunk.web_conf | |
=================================================================== --> | |
<target name="splunk.web_conf" description="Configure SplunkWeb for easier web development" depends="initialize_properties,verify_splunk_home"> | |
<mkdir dir="${value.deploy.splunk_home}/etc/system/local/"/> | |
<echo file="${value.deploy.splunk_home}/etc/system/local/web.conf">[settings] | |
minify_js = False | |
minify_css = False | |
js_no_cache = True | |
cacheEntriesLimit = 0 | |
cacheBytesLimit = 0 | |
enableWebDebug = True | |
</echo> | |
</target> | |
<!-- =================================================================== | |
target: splunk.enable_fips | |
=================================================================== --> | |
<target name="splunk.enable_fips" description="Configure SplunkWeb for easier web development" depends="initialize_properties,verify_splunk_home"> | |
<echo file="${value.deploy.splunk_home}/etc/splunk-launch.conf">SPLUNK_FIPS=1</echo> | |
</target> | |
<!-- =================================================================== | |
target: splunk.enable_custom_root_endpoint | |
=================================================================== --> | |
<target name="splunk.enable_custom_root_endpoint" description="Configure SplunkWeb for easier web development" depends="initialize_properties,verify_splunk_home"> | |
<mkdir dir="${value.deploy.splunk_home}/etc/system/local/"/> | |
<echo file="${value.deploy.splunk_home}/etc/system/local/web.conf">[settings] | |
root_endpoint=/custom_endpoint | |
</echo> | |
</target> | |
<!-- ================================= | |
target: does_appserver_exist | |
================================= --> | |
<target name="does_appserver_exist" depends="initialize_properties,verify_splunk_home"> | |
<condition property="appserver_dir_exists"> | |
<available file="${basedir}/${value.src.directory}/appserver/" type="dir"/> | |
</condition> | |
</target> | |
<!-- ================================= | |
target: is_appserver_up_to_date | |
================================= --> | |
<target name="is_appserver_up_to_date" description="Determine if the code in the appserver directory of the Splunk install is outdated" depends="initialize_properties,does_appserver_exist" if="appserver_dir_exists"> | |
<uptodate property="appserver_up_to_date"> | |
<!-- target should point to the source files --> | |
<mapper type="glob" from="*" to="${value.deploy.splunk_home}/etc/apps/${value.build.appname}/appserver/*" /> | |
<!-- srcfiles should point to the deployed files --> | |
<srcfiles dir="${basedir}/${value.src.directory}/appserver/" includes="**/*" /> | |
</uptodate> | |
</target> | |
<!-- ================================= | |
target: splunk.bump_if_necessary | |
================================= --> | |
<target name="splunk.bump_if_necessary" unless="appserver_up_to_date" if="appserver_dir_exists" depends="initialize,does_appserver_exist,is_appserver_up_to_date"> | |
<if> | |
<bool> | |
<not> | |
<isset property="skip_bump" /> | |
</not> | |
</bool> | |
<then> | |
<antcall target="splunk.bump" /> | |
</then> | |
</if> | |
</target> | |
<!-- ================================= | |
target: splunk.bump | |
================================= --> | |
<target name="splunk.bump" depends="initialize_libraries,verify_splunkweb_url" description="Bump Splunk"> | |
<splunkwebbump url="${value.deploy.splunkweb_url}" username="${value.deploy.splunk_username}" password="${value.deploy.splunk_password}"/> | |
</target> | |
<!-- ================================= | |
target: splunk.start | |
================================= --> | |
<target name="splunk.start" description="Start Splunk" depends="initialize_properties,verify_splunk_home"> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="start" /> | |
<arg line="--accept-license" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: verify_splunkd_url | |
================================= --> | |
<target name="verify_splunkd_url" depends="initialize_properties"> | |
<fail unless="value.deploy.splunkd_url"> | |
"splunkd_url" has not been defined | |
Declare it in the a local.properties file in the following path: | |
${absolute_src_path}/local.properties | |
Below is an example of the entry in the file: | |
value.deploy.splunkd_url=http://splunk.example.com:8000 | |
</fail> | |
</target> | |
<!-- ================================= | |
target: verify_splunkweb_url | |
================================= --> | |
<target name="verify_splunkweb_url" depends="initialize_properties"> | |
<fail unless="value.deploy.splunkweb_url"> | |
"splunkweb_url" has not been defined | |
Declare it in the a local.properties file in the following path: | |
${absolute_src_path}/local.properties | |
Below is an example of the entry in the file: | |
value.deploy.splunkweb_url=https://splunk.example.com:8089 | |
</fail> | |
</target> | |
<!-- ================================= | |
target: splunk.restart | |
================================= --> | |
<target name="splunk.restart" description="Restart Splunk" depends="initialize"> | |
<if> | |
<not> | |
<isset property="value.deploy.splunk_home"/> | |
</not> | |
<then> | |
<splunkrestart url="${value.deploy.splunkd_url}" username="${value.deploy.splunk_username}" password="${value.deploy.splunk_password}"/> | |
</then> | |
<else> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="restart" /> | |
<arg line="--accept-license" /> | |
</exec> | |
</else> | |
</if> | |
</target> | |
<!-- ================================= | |
target: splunk.restart_api | |
================================= --> | |
<target name="splunk.restart_api" description="Restart Splunk using a Splunkd API call" depends="verify_splunkd_url,initialize_libraries"> | |
<splunkrestart url="${value.deploy.splunkd_url}" username="${value.deploy.splunk_username}" password="${value.deploy.splunk_password}"/> | |
</target> | |
<!-- ================================= | |
target: splunk.restart_cli | |
================================= --> | |
<target name="splunk.restart_cli" description="Restart Splunk using a CLI call" depends="initialize_properties,verify_splunk_home"> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="restart" /> | |
<arg line="--accept-license" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: splunk.restart_web | |
================================= --> | |
<target name="splunk.restart_web" description="Restart Splunk" depends="initialize_properties,verify_splunk_home"> | |
<exec executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="restart" /> | |
<arg line="splunkweb" /> | |
<arg line="--accept-license" /> | |
<arg line="-auth" /> | |
<arg line="${value.deploy.splunk_username}:${value.deploy.splunk_password}" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: splunk.deploy_and_refresh | |
================================= --> | |
<target name="splunk.deploy_and_refresh" description="Deploys the application and forces Splunk to refresh" depends="deploy,splunk.refresh" /> | |
<!-- ================================= | |
target: splunk.deploy_and_restart | |
================================= --> | |
<target name="splunk.deploy_and_restart" description="Deploys the application and restarts Splunk" depends="skip_bump,deploy,splunk.restart" /> | |
<!-- ================================= | |
target: splunk.package_and_install | |
================================= --> | |
<target name="splunk.package_and_install" description="Builds the package and installs the package into Splunk" depends="package,splunk.install" /> | |
<!-- ================================= | |
target: splunk.install | |
================================= --> | |
<target name="splunk.install" description="Installs the package into Splunk" depends="initialize"> | |
<if> | |
<not> | |
<isset property="value.deploy.splunk_home"/> | |
</not> | |
<then> | |
<antcall target="splunk.install_api" /> | |
</then> | |
<else> | |
<antcall target="splunk.install_cli" /> | |
</else> | |
</if> | |
</target> | |
<!-- ================================= | |
target: splunk.install_cli | |
================================= --> | |
<target name="splunk.install_cli" description="Installs the package into Splunk" depends="initialize_properties,verify_splunk_home,resolve_package_file"> | |
<exec failonerror="true" executable="${value.deploy.splunk_home}/bin/splunk" dir="${basedir}"> | |
<arg line="install" /> | |
<arg line="app" /> | |
<arg line="${absolute_package_file}" /> | |
<arg line="-update" /> | |
<arg line="1" /> | |
<arg line="-auth" /> | |
<arg line="${value.deploy.splunk_username}:${value.deploy.splunk_password}" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: resolve_package_file | |
================================= --> | |
<target name="resolve_package_file" description="Resolve the package file name; downloads the package file necessary" depends="initialize"> | |
<!-- See if the package is a URL and download the package if it is --> | |
<if> | |
<matches pattern="^http(s?):\/\/.*$" string="${value.build.package.file}"/> | |
<then> | |
<!-- Extract the filename from the URL --> | |
<propertyregex property="extracted_filename" | |
input="${value.build.package.file}" | |
regexp=".*\/([^\/]+)\/?" | |
select="\1" | |
casesensitive="false" /> | |
<!-- Resolve the file name to an absolute path --> | |
<property name="absolute_package_file" location="${basedir}/${extracted_filename}"/> | |
<!-- Download the file from the server and use authentication if provided --> | |
<if> | |
<bool> | |
<and> | |
<isset property="value.build.package.username"/> | |
<isset property="value.build.package.password"/> | |
</and> | |
</bool> | |
<then> | |
<!-- Download the file using the provided username and password --> | |
<get src="${value.build.package.file}" | |
dest="${absolute_package_file}" | |
verbose="true" | |
username="${value.build.package.username}" | |
password="${value.build.package.password}" | |
skipexisting="false" /> | |
</then> | |
<else> | |
<!-- Download the file --> | |
<get src="${value.build.package.file}" | |
dest="${absolute_package_file}" | |
verbose="true" | |
skipexisting="false" /> | |
</else> | |
</if> | |
</then> | |
<else> | |
<!-- Resolve the absolute filename --> | |
<property name="absolute_package_file" location="${value.build.package.file}"/> | |
</else> | |
</if> | |
<!-- Verify that the package exists --> | |
<if> | |
<available file="${absolute_package_file}" /> | |
<then> | |
<!-- Package exists, we are good --> | |
</then> | |
<else> | |
<fail message="Package file does not exist; expected it to be at ${absolute_package_file}" /> | |
</else> | |
</if> | |
</target> | |
<!-- ================================= | |
target: splunk.install_api | |
================================= --> | |
<target name="splunk.install_api" description="Installs the package into Splunk using the REST API" depends="initialize_libraries,verify_splunkd_url,resolve_package_file"> | |
<splunkappinstall name="${absolute_package_file}" url="${value.deploy.splunkd_url}" username="${value.deploy.splunk_username}" password="${value.deploy.splunk_password}"/> | |
</target> | |
<!-- ================================= | |
target: splunk.install_and_restart | |
================================= --> | |
<target name="splunk.install_and_restart" description="Builds the package, installs it, and restarts Splunk" depends="initialize_properties,splunk.install,splunk.restart"/> | |
<!-- ================================= | |
target: define_reload_conf_macro | |
================================= --> | |
<target name="define_reload_conf_macro" depends="initialize_properties"> | |
<!-- Define a macro that can be used for refreshing Splunk endpoints --> | |
<macrodef name="reload_conf"> | |
<attribute name="endpoint"/> | |
<sequential> | |
<exec failonerror="true" executable="${value.deploy.splunk_home}/bin/splunk"> <!-- Fail on error is set to true --> | |
<arg value="_internal"/> | |
<arg value="call"/> | |
<arg value="/admin/@{endpoint}/_reload"/> | |
<arg value="-auth"/> | |
<arg value="${value.deploy.splunk_username}:${value.deploy.splunk_password}"/> | |
<arg value="--accept-license"/> | |
</exec> | |
</sequential> | |
</macrodef> | |
</target> | |
<!-- ================================= | |
target: splunk.refresh | |
================================= --> | |
<target name="splunk.refresh" description="Refresh Splunk" depends="define_reload_conf_macro,verify_splunk_home"> | |
<reload_conf endpoint="savedsearch" /> | |
<reload_conf endpoint="nav" /> | |
<reload_conf endpoint="views" /> | |
</target> | |
<!-- ================================= | |
target: test.deploy_and_run | |
================================= --> | |
<target name="test.deploy_and_run" description="Deploys the application and runs tests" depends="verify_splunk_home,skip_bump,deploy,test.run" /> | |
<!-- ================================= | |
target: test.run | |
================================= --> | |
<target name="test.run" description="Run tests" depends="initialize_properties,verify_splunk_home"> | |
<exec failonerror="true" executable="${value.deploy.splunk_home}/bin/splunk"> | |
<arg line="cmd" /> | |
<arg line="python" /> | |
<arg line="-m" /> | |
<arg line="unittest" /> | |
<arg line="discover" /> | |
<arg line="${value.build.test.directory}" /> | |
<arg line="-p" /> | |
<arg line="*.py" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: test.deploy_and_run_unit | |
================================= --> | |
<target name="test.deploy_and_run_unit" description="Deploys the application and runs the unit tests" depends="skip_bump,deploy,test.setup,test.run_unit,test.tear_down" /> | |
<!-- ================================= | |
target: test.deploy_and_test | |
================================= --> | |
<target name="test.deploy_and_test" description="Deploys the application and runs the entire test suite" depends="skip_bump,deploy,test" /> | |
<!-- ================================= | |
target: test.setup | |
================================= --> | |
<target name="test.setup" depends="initialize_properties" /> | |
<!-- ================================= | |
target: test.tear_down | |
================================= --> | |
<target name="test.tear_down" /> | |
<!-- ================================= | |
target: test.run_unit | |
================================= --> | |
<target name="test.run_unit" depends="test.setup"> | |
<!-- Define a default value for the tests to run. Otherwise, arguments passed from the CLI will be used (e.g. ant test.run_unit -Dtest=TestPingParser) --> | |
<property name="test" value="" /> | |
<exec failonerror="true" executable="${value.deploy.splunk_home}/bin/splunk" dir="${value.build.test.directory}"> | |
<arg line="cmd" /> | |
<arg line="python" /> | |
<arg line="unit.py" /> | |
<arg line="${test}" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: test | |
================================= --> | |
<target name="test" description="Run the entire test suite" depends="test.setup,test.run_unit,btool,test.tear_down"> | |
</target> | |
<!-- ================================= | |
target: btool | |
================================= --> | |
<target name="btool" description="Check the app configuration with btool" depends="initialize_properties"> | |
<exec failonerror="true" executable="${value.deploy.splunk_home}/bin/splunk" dir="${value.build.test.directory}"> | |
<arg line="cmd" /> | |
<arg line="btool" /> | |
<arg line="check" /> | |
<arg line="--app=${value.build.appname}" /> | |
</exec> | |
</target> | |
<!-- ================================= | |
target: appinspect | |
================================= --> | |
<target name="appinspect" description="Inspect the app appinspect" depends="package"> | |
<if> | |
<not> | |
<isset property="value.test.appinspect_path"/> | |
</not> | |
<then> | |
<property name="value.test.appinspect_path" value="splunk-appinspect"/> | |
</then> | |
</if> | |
<!-- Check to see if it appinspect is defined in the appinspect_path parameter --> | |
<available file="${value.test.appinspect_path}" | |
filepath="${value.test.appinspect_path}" | |
property="appinspect.present" /> | |
<!-- Check to see if appinspect is on the path --> | |
<available file="splunk-appinspect" | |
filepath="${env.PATH}" | |
property="appinspect.present" /> | |
<!-- Change to an absolute path since app inspect requires this --> | |
<property name="value.build.package.absolute_file" location="${value.build.package.file}"/> | |
<if> | |
<isset property="appinspect.present"/> | |
<!-- Run appinspect on the package --> | |
<then> | |
<exec failonerror="true" executable="${value.test.appinspect_path}" dir="${value.build.packageoutput.directory}"> | |
<arg line="inspect" /> | |
<arg line="${value.build.package.absolute_file}" /> | |
</exec> | |
</then> | |
<!-- Tell the user that they need to install appinspect --> | |
<else> | |
<echo>appinspect was not found. | |
Install appinspect from http://dev.splunk.com/view/appinspect/SP-CAAAFAK if you haven't already. | |
You can declare the "value.test.appinspect_path" parameter with the path where appinspect is installed if isn't on your system path. | |
Declare it in a local.properties file in the following path: | |
${absolute_src_path}/local.properties | |
</echo> | |
</else> | |
</if> | |
</target> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment