Skip to content

Commit

Permalink
feat: add new options to windows install script and installer
Browse files Browse the repository at this point in the history
* remotely managed
* ephemeral
* api
  • Loading branch information
fguimond committed Feb 2, 2024
1 parent febcbf1 commit 8fecb64
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 8 deletions.
4 changes: 4 additions & 0 deletions packaging/msi/SumoLogic.wixext/SumoLogic.wixext/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public class Config
{
public string InstallationToken { get; set; }
public Dictionary<string, string> CollectorFields { get; set; }
public bool RemotelyManaged { get; set; }
public bool Ephemeral { get; set; }
public string OpAmpFolder { get; set; }
public string Api { get; set; }

public Config() {
this.CollectorFields = new Dictionary<string, string>();
Expand Down
58 changes: 58 additions & 0 deletions packaging/msi/SumoLogic.wixext/SumoLogic.wixext/ConfigUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,47 @@ public void Update(Config config)
collectorFields.Children[field.Key] = field.Value;
}
}

if (config.RemotelyManaged)
{
EnsureMapKey(extensions, "opamp");
YamlMappingNode opamp = (YamlMappingNode)extensions.Children["opamp"];
EnsureScalarKey(opamp, "remote_configuration_directory");
opamp.Children["remote_configuration_directory"] = config.OpAmpFolder;

// Add OpAmp extension to service section
EnsureMapKey(root, "service");
YamlMappingNode service = (YamlMappingNode)root.Children["service"];
EnsureSequenceKey(service, "extensions");
YamlSequenceNode serviceExtensions = (YamlSequenceNode)service.Children["extensions"];
if (!serviceExtensions.Children.Contains("opamp"))
{
serviceExtensions.Children.Add("opamp");
}
}

if (config.Ephemeral)
{
EnsureScalarKey(sumologic, "ephemeral");
sumologic.Children["ephemeral"] = "true";
}

if (!string.IsNullOrEmpty(config.Api))
{
EnsureScalarKey(sumologic, "api_base_url");
sumologic.Children["api_base_url"] = config.Api;
}

// Make sure the sumologic processor node is a map node, otherwise an empty string
// is generated as the value instead of an empty node.
if (root.Children.ContainsKey("processors"))
{
YamlMappingNode processors = (YamlMappingNode)root.Children["processors"];
if (processors.Children.ContainsKey("sumologic"))
{
EnsureMapKey(processors, "sumologic");
}
}
}

public void Save(StreamWriter streamWriter)
Expand Down Expand Up @@ -100,5 +141,22 @@ private void EnsureScalarKey(YamlMappingNode node, string key)
// Add empty YamlScalarNode to key
node.Children.Add(key, new YamlScalarNode());
}

private void EnsureSequenceKey(YamlMappingNode node, string key)
{
if (node.Children.ContainsKey(key))
{
if (node.Children[key].NodeType == YamlNodeType.Sequence)
{
return;
}

// TODO: is this how we want to handle incorrect node types?
// YamlNode is wrong type, remove it
node.Children.Remove(key);
}
// Add empty YamlScalarNode to key
node.Children.Add(key, new YamlSequenceNode());
}
}
}
62 changes: 58 additions & 4 deletions packaging/msi/SumoLogic.wixext/SumoLogic.wixext/CustomAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using WixToolset.Dtf.WindowsInstaller;

namespace SumoLogic.wixext
Expand All @@ -13,9 +14,21 @@ public class CustomActions

// WiX property names
private const string pCommonConfigPath = "CommonConfigPath";
private const string pSumoLogicConfigPath = "SumoLogicConfigPath";
private const string pInstallationToken = "InstallationToken";
private const string pInstallToken = "InstallToken";
private const string pTags = "Tags";
private const string pApi = "Api";
private const string pRemotelyManaged = "RemotelyManaged";
private const string pEphemeral = "Ephemeral";
private const string pConfigFolder = "ConfigFolder";
private const string pOpAmpFolder = "OpAmpFolder";
private const string pConfigFragmentsFolder = "ConfigFragmentsFolder";
private const string pServiceArgumentsProperty = "ServiceArgumentsProperty";

// WiX features
private const string fEphemeral = "EPHEMERALD";
private const string fRemotelyManaged = "REMOTELYMANAGED";

[CustomAction]
public static ActionResult UpdateConfig(Session session)
Expand All @@ -41,25 +54,39 @@ public static ActionResult UpdateConfig(Session session)
}

var commonConfigPath = session.CustomActionData[pCommonConfigPath];
var sumoLogicConfigPath = session.CustomActionData[pSumoLogicConfigPath];
var tags = session.CustomActionData[pTags];

var installationToken = "";
if (session.CustomActionData.ContainsKey(pInstallationToken) && session.CustomActionData[pInstallationToken] != "") {
if (session.CustomActionData.ContainsKey(pInstallationToken) && session.CustomActionData[pInstallationToken] != "")
{
installationToken = session.CustomActionData[pInstallationToken];
} else if (session.CustomActionData.ContainsKey(pInstallToken)){
}
else if (session.CustomActionData.ContainsKey(pInstallToken))
{
installationToken = session.CustomActionData[pInstallToken];
}

var remotelyManaged = (session.CustomActionData.ContainsKey(pRemotelyManaged) && session.CustomActionData[pRemotelyManaged] == "true");
var ephemeral = (session.CustomActionData.ContainsKey(pEphemeral) && session.CustomActionData[pEphemeral] == "true");
var opAmpFolder = session.CustomActionData[pOpAmpFolder];
var api = session.CustomActionData[pApi];

// Load config from disk and replace values
Config config = new Config();
config.InstallationToken = installationToken;
config.SetCollectorFieldsFromTags(tags);
config.RemotelyManaged = remotelyManaged;
config.Ephemeral = ephemeral;
config.OpAmpFolder = opAmpFolder;
config.Api = api;

var configFile = remotelyManaged ? sumoLogicConfigPath : commonConfigPath;
try
{
ConfigUpdater configUpdater = new ConfigUpdater(new StreamReader(commonConfigPath));
ConfigUpdater configUpdater = new ConfigUpdater(new StreamReader(configFile));
configUpdater.Update(config);
configUpdater.Save(new StreamWriter(commonConfigPath));
configUpdater.Save(new StreamWriter(configFile));
}
catch (Exception e)
{
Expand All @@ -72,6 +99,33 @@ public static ActionResult UpdateConfig(Session session)
return ActionResult.Success;
}

[CustomAction]
public static ActionResult PopulateServiceArguments(Session session)
{
try
{
var configFolder = session.GetTargetPath(pConfigFolder);
var configFragmentsFolder = session.GetTargetPath(pConfigFragmentsFolder);
var remotelyManaged = session.Features.Contains(fRemotelyManaged) && session.Features[fRemotelyManaged].RequestState == InstallState.Local;

if (remotelyManaged)
{
session["SERVICEARGUMENTS"] = " --remote-config \"opamp:" + configFolder + "sumologic.yaml\"";
}
else
{
session["SERVICEARGUMENTS"] = " --config \"" + configFolder + "sumologic.yaml\" --config \"glob:" + configFragmentsFolder + "*.yaml\"";
}
}
catch (Exception e)
{
showErrorMessage(session, ecConfigError, e.Message + e.StackTrace);
return ActionResult.Failure;
}

return ActionResult.Success;
}

private static void showErrorMessage(Session session, short errCode, string key)
{
Record record = new Record(3);
Expand Down
9 changes: 8 additions & 1 deletion packaging/msi/wix/components.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
<RemoveFolder On="uninstall" />
</Component>

<Component Id="cOpAmpFolder" Directory="OpAmpFolder" KeyPath="yes" Guid="DB8F7CF1-B793-4C37-8B96-03E1A2FF7F92">
<CreateFolder />
<RemoveFolder On="uninstall" />
</Component>

<Component Id="cFileStorageFolder" Directory="FileStorageFolder" KeyPath="yes" Guid="0A7EFA54-26F3-46A9-BA12-9D12CDAEF1CD">
<CreateFolder />
<RemoveFolder On="uninstall" />
Expand All @@ -84,7 +89,9 @@
<Environment Id="PATH" Name="PATH" Value="[INSTALLDIR]\bin" Permanent="yes" Part="last" Action="set" System="yes" />

<!-- Add service for OTC -->
<ServiceInstall Id="Sevice" Name="!(loc.ServiceName)" DisplayName="!(loc.ServiceDisplayName)" Description="!(loc.ServiceDescription)" Type="ownProcess" Vital="yes" Start="auto" Account="LocalSystem" ErrorControl="normal" Arguments=" --config &quot;[ConfigFolder]sumologic.yaml&quot; --config &quot;glob:[ConfigFragmentsFolder]*.yaml&quot;" Interactive="no" />
<ServiceInstall Id="Service" Name="!(loc.ServiceName)" DisplayName="!(loc.ServiceDisplayName)"
Description="!(loc.ServiceDescription)" Type="ownProcess" Vital="yes" Start="auto" Account="LocalSystem"
ErrorControl="normal" Arguments="[SERVICEARGUMENTS]" Interactive="no" />

<!-- Start/Stop/Remove OTC service -->
<ServiceControl Id="StartServiceControl" Name="!(loc.ServiceName)" Start="install" Stop="both" Remove="uninstall" Wait="no" />
Expand Down
1 change: 1 addition & 0 deletions packaging/msi/wix/folders.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<Directory Id="APPDATAFOLDER" Name="!(bind.Property.ProductName)">
<Directory Id="ConfigFolder" Name="config">
<Directory Id="ConfigFragmentsFolder" Name="conf.d" />
<Directory Id="OpAmpFolder" Name="opamp.d" />
</Directory>
<Directory Id="DataFolder" Name="data">
<Directory Id="FileStorageFolder" Name="file_storage" />
Expand Down
39 changes: 37 additions & 2 deletions packaging/msi/wix/package.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,51 @@
<!-- <RegistrySearch Id="DetermineTags" Type="raw" Root="HKLM" Key="$(RegKeyPath)" Name="Tags" /> -->
<!-- </Property> -->

<!-- Whether or not the remotely managed and ephemeral features are selected -->
<Property Id="REMOTELYMANAGEDSELECTED" Value="false" Hidden="yes" />
<Property Id="EPHEMERALSELECTED" Value="false" Hidden="yes" />

<!-- The API base URL if overriden -->
<Property Id="API" Hidden="yes" />

<!-- UI Properties -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />

<!-- The service arguments, to be updated in teh UpdateConfigAction if necessary -->
<Property Id="SERVICEARGUMENTS" Value="empty" Hidden="yes"/>

<!-- Custom Actions -->
<CustomAction Id="SetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLFOLDER]" />

<Binary Id="SumoLogicDll" SourceFile="$(SumoLogic.TargetDir)\SumoLogic.wixext.CA.dll" />
<CustomAction Id="UpdateConfigAction" BinaryRef="SumoLogicDll" DllEntry="UpdateConfig" Execute="deferred" Return="check" Impersonate="no" />
<CustomAction Id="UpdateConfigActionData" Property="UpdateConfigAction" Value="CommonConfigPath=[ConfigFragmentsFolder]common.yaml;InstallToken=[INSTALLTOKEN];InstallationToken=[INSTALLATIONTOKEN];Tags=[TAGS]" />
<CustomAction Id="PopulateServiceArgumentsAction" BinaryRef="SumoLogicDll" DllEntry="PopulateServiceArguments"
Return="check" Impersonate="no" />
<CustomAction Id="UpdateConfigAction" BinaryRef="SumoLogicDll" DllEntry="UpdateConfig" Execute="deferred"
Return="check" Impersonate="no" />
<!-- Split the properties into multiple sections and merge them to avoid size limit -->
<CustomAction Id="UpdateConfigActionData1" Property="UpdateConfigAction1"
Value="CommonConfigPath=[ConfigFragmentsFolder]common.yaml;SumoLogicConfigPath=[ConfigFolder]sumologic.yaml;InstallToken=[INSTALLTOKEN];InstallationToken=[INSTALLATIONTOKEN]" />
<CustomAction Id="UpdateConfigActionData2" Property="UpdateConfigAction2"
Value="Tags=[TAGS];OpAmpFolder=[OpAmpFolder];Ephemeral=[EPHEMERALSELECTED];RemotelyManaged=[REMOTELYMANAGEDSELECTED];Api=[API]" />
<CustomAction Id="UpdateConfigActionData" Property="UpdateConfigAction" Value="[UpdateConfigAction1];[UpdateConfigAction2]" />

<!-- Before updating the config files set the properties indicating whether or not the remotely managed and ephemeral features are selected -->
<SetProperty Id="REMOTELYMANAGEDSELECTED" Value="true" Sequence="execute" Before="UpdateConfigActionData" Condition="&amp;REMOTELYMANAGED=3" />
<SetProperty Id="EPHEMERALSELECTED" Value="true" Sequence="execute" Before="UpdateConfigActionData" Condition="&amp;EPHEMERAL=3" />

<!-- Execute Sequence -->
<InstallExecuteSequence>
<!-- Determine the install location after the install path has been validated -->
<Custom Action="SetARPINSTALLLOCATION" After="InstallValidate" />

<!-- Update service arguments before the service is installed -->
<Custom Action="PopulateServiceArgumentsAction" Before="InstallServices" Condition="NOT REMOVE" />

<!-- Run config updating before the service is installed -->
<Custom Action="UpdateConfigAction" Before="InstallServices" Condition="NOT REMOVE" />
<Custom Action="UpdateConfigActionData" Before="UpdateConfigAction" Condition="NOT REMOVE" />
<Custom Action="UpdateConfigActionData1" Before="UpdateConfigActionData" Condition="NOT REMOVE" />
<Custom Action="UpdateConfigActionData2" Before="UpdateConfigActionData" Condition="NOT REMOVE" />
</InstallExecuteSequence>

<!-- Features -->
Expand All @@ -102,6 +129,14 @@
<Feature Id="HOSTMETRICS" Title="Collect Host Metrics" Level="2" AllowAbsent="yes" AllowAdvertise="yes" TypicalDefault="advertise">
<ComponentGroupRef Id="HostMetricsComponents" />
</Feature>

<Feature Id="REMOTELYMANAGED" Title="Remotely Managed" Level="2" AllowAbsent="yes" AllowAdvertise="no" TypicalDefault="install" >
<Component Id="RemotelyManagedComponent" Location="local" Directory="INSTALLFOLDER" Guid="5169967a-f9e9-43f7-abb4-6b69273932a3" />
</Feature>

<Feature Id="EPHEMERAL" Title="Ephemeral" Level="2" AllowAbsent="yes" AllowAdvertise="no" TypicalDefault="install" >
<Component Id="EphemeralComponent" Location="local" Directory="INSTALLFOLDER" Guid="4095b4ee-d011-49c3-b7a7-755aa36fcc5e" />
</Feature>
</Feature>

<!-- UI -->
Expand Down
20 changes: 19 additions & 1 deletion scripts/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ param (
[bool] $InstallHostMetrics,

# Fips is used to download a fips binary installer.
[bool] $Fips
[bool] $Fips,

# Specifies wether or not remote management is enabled
[bool] $RemotelyManaged,

# Ephemeral option enabled
[bool] $Ephemeral,

# The API URL used to communicate with the SumoLogic backend
[string] $Api
)

$PackageGithubOrg = "SumoLogic"
Expand Down Expand Up @@ -488,9 +497,18 @@ try {
$tagsProperty = $tagStrs -Join ","
$msiProperties += "TAGS=`"${tagsProperty}`""
}
if ($Api.Length -gt 0) {
$msiProperties += "API=`"${Api}`""
}
if ($InstallHostMetrics -eq $true) {
$msiAddLocal += "HOSTMETRICS"
}
if ($RemotelyManaged -eq $true) {
$msiAddLocal += "REMOTELYMANAGED"
}
if ($Ephemeral -eq $true) {
$msiAddLocal += "EPHEMERAL"
}
if ($msiAddLocal.Count -gt 0) {
$addLocalStr = $msiAddLocal -Join ","
$msiProperties += "ADDLOCAL=${addLocalStr}"
Expand Down

0 comments on commit 8fecb64

Please sign in to comment.