Configuration file

Octory mainly uses this plist configuration file to adapt its interface and its behavior. By editing it, you can deeply customize the application, like choosing its components to display, specify which apps should be monitored, and what MDM to use.
The configuration file has several sections. Each one holds a specific configuration part of the application. You can find all the sections on the left.

Finally, you can find a blank configuration file with the minimum required sections on the configurations respository.

All the groups marked as Optional are not required to launch Octory. However, when you use an optional group, the keys marked as Required have to be specified.



Admin (Dictionary) Optional

Key name: Admin

Let you enter the admin mode This allows you to access actions in the Admin menu bar. Here are the features.

Keys

Summary

Name Type Required
IsAdminModeEnabled Boolean Required
IsMenuBarSemiTransient Boolean

Detail

IsAdminModeEnabled Required


IsMenuBarSemiTransient


Example

<key>Admin</dict>
<dict>
	<key>IsAdminModeEnabled</key>
	<true/>
</dict>



Input (Dictionary) Optional

Key name: Input

Lets you configure the properties of the input variables files, where all the values entered by the user will be found. You can read Input components to know how to use components to ask information to the user.

As this group is optional, it can be omitted. In this case, the file path will be /Users/jdoe/Octory/Octory_inputs.json and the file format will be JSON.

Keys

Summary

Name Type Possible values Required
FileFormat String PLIST, JSON Required
FilePath String -

Detail

FileFormat Required


FilePath


Octory will overwrite the file if it exists or create it if not. You need to specify the full path to the file, for example: /tmp/user_input.json or /Users/Shared/enrollment_inputs.plist. The extension of the file has to match the FileFormat key. Note that you may need to give the right to the end-user to write in some directories if necessary, for Octory to be able to save the file in those directories.

Example

Tell Octory to save the user's inputs in the file at /Users/Shared/Octory_inputs.json in a JSON format.

<key>Input</key>
<dict>
	<key>FileFormat</key>
	<string>JSON</string>
	<key>FilePath</key>
	<string>/Users/Shared/Octory_inputs.json</string>
</dict>



Font styles (Dictionary) Optional

Key name: FontStyles

You can define here custom font styles which will be available in any place where you can use font style. To use a font configuration defined here, you just need to add the key Style in the font configuration dictionary, and to give as value the name of the key. A font configuration can have a style and implement other properties, like setting the color. Note that if a font configuration uses a style but also specifies properties which exist in the style, the properties in the style will be overridden.

To use them in a font configuration elsewhere in the plist, simply set the key Style to the name of the style you want to use.

You can define default fonts that will be used in Octory by default if possible when no other font configuration is specified.

Keys

Summary

Name Type Required
DefaultPrimary Font configuration
DefaultSecondary Font configuration

Detail

DefaultPrimary


DefaultSecondary


Example

We defined here two font styles: "Title" and "Body", to use them elwhere in the configuration file, like in a TextComponent

<key>FontStyles</key>
<dict>
  <key>Title</key>
  <dict>
    <key>SystemFontWeight</key>
    <string>Bold</string>
    <key>Size</key>
    <integer>30</integer>
  </dict>
    <key>Body</key>
    <dict>
        <key>SystemFontWeight</key>
        <string>Regular</string>
  </dict>
</dict>

You can use a font style to define another font style. Do note that if you specify a style A for a font that is already used as a style B in the style A, Octory will ignore one of the style to avoid infinite loops.
Here the style "Title2" uses the style "Title" but changes its color attribute.

<key>FontStyles</key>
<dict>
  <key>Title</key>
  <dict>
      <key>SystemFontWeight</key>
      <string>Bold</string>
      <key>Size</key>
      <integer>30</integer>
  </dict>
  <key>Title2</key>
  <dict>
      <key>Style</key>
      <string>Title</string>
      <key>Color</key>
      <dict>
          <key>Style</key>
          <string>Main</string>
  </dict>
</dict>



Color styles (Dictionary) Optional

Key name: ColorStyles

You can define here custom colors which will be available in any place where you can use colors. To use a font configuration defined here, you just need to add the key Style in the font configuration dictionary, and to give as value the name of the key. A color can have a style and implement other properties, like setting the alpha. Note that if a color uses a style but also specify properties which exist in the style, the properties in the style will be overridden.

To use styles in a colors elsewhere in the plist, simply set the key Style to the name of the style you want to use.

You can define default colors that will be used in Octory by default if possible when no other color is specified.

Keys

Summary

Name Type Required
DefaultBorder Color

Detail

DefaultBorder


Example

We defined here two colors: "Main" and "Secondary".

<key>ColorStyles</key>
<dict>
    <key>Main</key>
    <dict>
        <key>DarkMode</key>
        <string>#819ABE</string>
        <key>LightMode</key>
        <string>#ED682580</string>
    </dict>
    <key>Secondary</key>
    <dict>
        <key>DarkMode</key>
        <string>#000000</string>
        <key>LightMode</key>
        <string>#50607F</string>
    </dict>
</dict>

You can use a color style to define another color style. Do note that if you specify a style A for a font that is already used as a style B in the style A, Octory will ignore one of the style to avoid infinite loops. Here we define a "Main" color a "LighterMain" color which uses "Main" but changes its alpha to 0.7

<key>ColorStyles</key>
<dict>
    <key>Main</key>
    <dict>
        <key>DarkMode</key>
        <string>#819ABE</string>
        <key>LightMode</key>
        <string>#ED682580</string>
    </dict>
    <key>LighterMain</key>
    <dict>
        <key>Style</key>
        <string>Main</string>
        <key>Alpha</key>
        <Real>0.7</real>
    </dict>
</dict>



Key name: Navigation

Lets you customize some properties relative to the navigation view. This view is at the bottom of the window and displays the navigation buttons. The last slide will display a Quit button instead of the Next button, whose text will differ. This Quit button will make the app to terminate. It will quit the app only if all the application monitors specified in the monitors are installed and if the current slide is valid.

Summary

Name Type Required
IsHidden Boolean
PreviousButtonText String
NextButtonText String
PreviousButtonTextColor String
NextButtonTextColor String
QuitButtonText String
InstallationIncompleteQuitText String
UserCanQuitIfInstallationIsIncomplete Boolean

Detail

IsHidden


PreviousButtonText


NextButtonText


PreviousButtonTextColor


NextButtonTextColor


QuitButtonText


InstallationIncompleteQuitText


UserCanQuitIfInstallationIsIncomplete


Example

The following hide the navigation view while enabling user to quit even if not all mandatory monitors are installed

<key>Navigation</key>
<dict>
	<key>IsHidden</key>
	<true/>
	<key>UserCanQuitIfInstallationIsIncomplete</key>
	<true/>
</dict>



App Termination (Dictionary) Optional

Key name: AppTermination

Holds the keys to customize the app termination behavior.
This group is optional. It can be omitted. In this case, the classic shortcut to quit the app will be enabled, and no script will be executed when the app terminates.

Keys

Summary

Name Type Required
QuitShortcutIsEnabled Boolean
ForceQuitShortcutIsEnabled Boolean
ForceQuitShortcutKey Boolean
IncompleteInstallationScriptPath String Required
CompleteInstallationScriptPath String Required
ExecuteAsRoot Bool

Detail

QuitShortcutIsEnabled


ForceQuitShortcutIsEnabled


ForceQuitShortcutKey


Make sure to avoid conflicts with already existing shortcuts.

CompleteInstallationScriptPath Required


IncompleteInstallationScriptPath Required


ExecuteAsRoot



The following commands in a script allow you to restart and shutdown the computer, while not requiring the root rights:
- restart: osascript -e 'tell app "System Events" to restart'
- shutdown: osascript -e 'tell application "Finder" to shut down'

For Octory 2.0.2, you can simply write reboot as the application will use the Helper with root privileges to execute the termination script.

Thus, you can use these commands at the end of the scripts to be executed when the application terminates. This solution - rather than doing it in Octory internally - ensures that your scripts will be executed to the end, before the computer restart or shutdown. Simple scripts to restart and shutdown are included in the Octory download file.

Example

The following configuration for the app termination disables the classic quit shortcut ⌘Q. Also, it will execute a script when the app terminates depending on the installation states of the monitors. Note the usage of the placeholder OCTORY_DIRECTORY which is the directory where the app is located.

<key>AppTermination</key>
<dict>
	<key>QuitShortcutIsEnabled</key>
	<false/>
	<key>IncompleteInstallationScriptPath</key>
	<string>${OCTORY_DIRECTORY}/Scripts/incompleteFinish.sh</string>
	<key>CompleteInstallationScriptPath</key>
	<string>${OCTORY_DIRECTORY}/Scripts/completeFinish.sh</string>
</dict>



General (Dictionary) Optional

Key name: General

All the variables that can be used to populate strings. See the Variables section to know more about how to use them.

Keys

Summary

Name Type Required
Variables Dictionary

Detail

Variables


Remarks

You can use other variables when defining one variable as long you respect those rules :
- You can use the available placeholders exposed in the Variables section.
- Do no use variables that are not defined in the General configuration
- Do not define a variable A to be used in variable B and the variable B to be used in variable A. If you do so, none of the implied variables will be available in Octory.

Examples

Here we define two variables to be reused elsewhere in the configuration file: "ResourcesPath" and "ApplicationIconsPath". Note that we use the USER_NAME placeholder.
<key>General</key>
<dict>
    <key>Variables</key>
    <dict>
        <key>ResourcesPath</key>
        <string>Users/${USER_NAME}/Desktop/Octory</string>
        <key>ApplicationIconsPath</key>
        <string>${ResourcesPath}/ApplicationIcons</string>
    </dict>
</dict>



Window (Dictionary) Required

Key name: Window

Groups all the keys associated to the window configuration.

Keys

Summary

Name Type Possible values Required
Title String -
IsTitleBarHidden Boolean -
MinimumSize Size -
MaximumSize Size -
MenuBarSize Size -
IsClosable Boolean -
IsMovable Boolean -
IsResizable Boolean -
ScreenIndex Int -
Position Window position -
OnScreen String Simple, BlurredBackground,
FullScreen, MenuBar
Required
MenuBarIconPath PRO String

Detail

Title


IsTitleBarHidden


MinimumSize


MaximumSize


MenuBarSize


IsClosable


IsMovable


IsResizable


ScreenIndex


Position


OnScreen Required


MenuBarIconPath PRO


Window position (Dictionary)

Let you specify a window position on the screen

Key Type Possible keys Explanation Is Required
Horizontal String Left, Center, Right Horizontal position Required
Vertical String Top, Center, Bottom Vertical position Required
Padding Number - Add padding to the side of the window. Default is 20.

Command line

You can override the value for the OnScreen key in the plist by launching the app with an argument: -w or --window and the name of the OnScreen value you want. For example:

/path/to/Octory.app/Contents/MacOS/Octory -w MenuBar

or

/path/to/Octory.app/Contents/MacOS/Octory --window BlurredBackground

will set the app window as MenuBar no matter what is in the plist.




Slides (Array) Required

Key name: Slides

Contains all the slides that will be displayed to the user. See the Slides section to learn how to use slides.

Example

Display a single slide with one container and one component in the container. The component is a TextComponent to display text.
<key>Slides</key>
<array>
	<dict>
		<key>Containers</key>
		<array>
			<dict>
				<key>Components</key>
				<array>
					<dict>
						<key>Type</key>
						<string>Text</string>
						<key>Text</key>
						<string>I love the smell of napalm in the morning</string>
					</dict>
				</array>
			</dict>
		</array>
	</dict>
</array>



Key name: MenuBarSlide

Specify here the slide you want to use when displaying the application with the "MenuBar" value for the OnScreen key.




Monitoring (Dictionary) Optional

Key name: Monitoring

You choose in this section how to monitor applications and packages installation, or file presence. The supported installer currently are Jamf, AirWatch (Wokspace ONE) and Munki, and applications installed with VPP (or from the App Store more generally).

To use Munki monitoring, set the Monitor Installer key as AirWatch and specify the paths to the corresponding Munki log files in the keys AirWatchInstallLogPath and AirWatchManagedSoftwareUpdateLogPath.

Keys

Summary

Name Type Required
JamfLogPath String
AirWatchInstallLogPath String
AirWatchManagedSoftwareUpdateLogPath String
InstallationCompleteSoundNameOrFilePath String
Monitors Array(Monitors) Required

Detail

JamfLogPath


AirWatchInstallLogPath


AirWatchManagedSoftwareUpdateLogPath


InstallationCompleteSoundNameOrFilePath


Monitors Required


Examples

Ask Octory to monitor the installation of the application "Drinky", installed from the App Store, and the application "Sushis" installed with Jamf. Note the usage of variable Monitors where could be stored the path to the monitors icons folder.

<dict>
	<key>Monitors</key>
	<array>
		<dict>
			<key>Type</key>
			<string>Application</string>
			<key>Installer</key>
			<string>System</string>
			<key>Name</key>
			<string>Drinky</string>
			<key>IconURL</key>
			<string>${Monitors}/drinky.png</string>
		</dict>
		<dict>
			<key>Type</key>
			<string>Application</string>
			<key>Installer</key>
			<string>Jamf</string>
			<key>Name</key>
			<string>Sushis</string>
		</dict>
	</array>
</dict>



Conditions (Dictionary) Optional PRO

Key name: Conditions

Write here the conditions you want to reuse in other conditions in the plist. You can use user inputs variables or dynamic placeholders to specify those conditions.

Examples

With UserRole as an input variable asked to the user, and the DEVICE_NAME dynamic placeholder. The ~= operand tests if the right operand is a prefix of the left operand.

<key>Conditions</key>
<dict>
	<key>UserIsConsultant</key>
	<string>UserRole == "Consultant"</string>
	<key>ComputerIsLaptop</key>
	<string>DEVICE_NAME ~= "LMAC"</string>
	<key>ComputerIsDesktop</key>
	<string>DEVICE_NAME ~= "DMAC"</string>
</dict>

You can then use the conditions defined here in a TextComponent for example, without writing again all the condition:

<dict>
    <key>Type</key>
    <string>Text</string>
    <key>Condition</key>
    <string>UserIsConsultant</string>
    <key>Text</key>
    <string>You are a consultant!</string>
</dict>

The component will only appear when the condition is evaluated as true.




API Requests (Dictionary) Optional PRO

Key name: APIRequests

You can define here all the api requests you want Octory to make with a SendRequest action

You can also define some useful keys that will be used by the requests.

Keys

Summary

Name Type Possible values Required
JamfBaseURL String -
JamfProBaseURL String -
AirwatchBaseURL String -
DefaultMDMApi String Jamf, JamfPro, AirWatch
Models Array(ApiRequest) - Required

Detail

JamfBaseURL


JamfProBaseURL


DefaultMDMApi


Models Required


Examples

<key>APIRequests</key>
<dict>
	<key>JamfBaseURL</key>
	<string>https://mycompany.jamfcloud.com/JSSResource/</string>
	<key>DefaultMDMApi</key>
	<string>Jamf</string>
	<key>Models</key>
	<dict>
		<key>ComputerName</key>
		<dict>
			<key>Endpoint</key>
			<string>computers/id/20</string>
			<key>VariableReadingPaths</key>
			<dict>
				<key>ComputerName</key>
				<string>computer->general->name</string>
			</dict>
		</dict>
		<key>UserName</key>
		<dict>
			<key>Endpoint</key>
			<string>accounts</string>
			<key>VariableReadingPaths</key>
			<dict>
				<key>UserName</key>
				<string>accounts->users->[0]->name</string>
			</dict>
		</dict>
		<key>TerminationSuccess</key>
		<dict>
			<key>Endpoint</key>
			<string>computers/id/20</string>
			<key>Method</key>
			<string>PUT</string>
			<key>Body</key>
			<dict>
				<key>computer</key>
				<dict>
					<key>extension_attributes</key>
					<dict>
						<key>extension_attribute</key>
						<dict>
							<key>id</key>
							<string>7</string>
							<key>value</key>
							<string>${INSTALLATION_COMPLETE}</string>
						</dict>
					</dict>
				</dict>
			</dict>
		</dict>
	</dict>
</dict>



Action Sets (Array) Optional PRO

Key name: ActionSets

Specify here the action sets you want Octory to trigger.

Examples

<array>
	<dict>
		<key>Type</key>
		<string>Chained</string>
		<key>Triggers</key>
		<array>
			<string>Launch</string>
		</array>
		<key>Actions</key>
		<array>
			<dict>
				<key>Type</key>
				<string>SendRequest</string>
				<key>Request</key>
        <string>ComputerName</string>
			</dict>
			<dict>
				<key>Type</key>
				<string>SendRequest</string>
				<key>Request</key>
        <string>UserName</string>
			</dict>
		</array>
	</dict>
	<dict>
		<key>Type</key>
		<string>Parallel</string>
		<key>Triggers</key>
		<array>
			<string>Termination</string>
		</array>
		<key>Actions</key>
		<array>
			<dict>
				<key>Type</key>
				<string>SendRequest</string>
				<key>Request</key>
        <string>TerminationSuccess</string>
			</dict>
		</array>
	</dict>
	<dict>
		<key>Type</key>
		<string>Chained</string>
		<key>Triggers</key>
		<array>
			<string>Update(ComputerName)</string>
		</array>
    <key>Condition</key>
    <string>ComputerName != ""</string>
		<key>Actions</key>
		<array>
			<dict>
				<key>Type</key>
				<string>ExecuteScript</string>
        <key>Script</key>
        <string>WriteComputerName</string>
			</dict>
		</array>
	</dict>
</array>