Skip to content

Environment Configuration

manne ohrstrom edited this page Apr 1, 2013 · 48 revisions

This document contains specifications for the various file formats that Tank uses for its configuration and settings.

Tank Environments

Three major components exists in Tank:

  • An engine provides a translation layer or an adapter between a host application (such as Maya or Nuke) and Tank Apps. Tank Apps typically use python and PySide, and it is the responsibility of the engine to present the host application in a standardized fashion and for example add pyside on top of the host application if this doesn't exist already.

  • An app provides a piece of business logic, it is essentially a tool that does something. Apps can be hand crafted to work in a specific host application, or they can be designed to run in more than one host application.

  • A framework is a library which can be used by engines, apps or other frameworks. A framework makes it possible to more easily manage code or behaviour which is shared between multiple apps.

A tank environment file contains the configuration settings for a collection of engines, apps and frameworks. Such a collection is called an Environment. Tank launches different environments for different files or different people. You can for example have an environment for Shot production and environment for Rigging. Each environment is a single yaml file.

The yaml file has the following basic format:

engines:
    tk-maya:
        location
        engine settings

        apps:
            tk-maya-publish:
                location
                app settings

            tk-maya-revolver:
                location
                app settings

    tk-nuke:
        location
        engine settings

        apps:
            tk-nuke-setframerange:
                location
                app settings

            tk-nuke-nukepub:
                location
                app settings
                
frameworks:
    tk-framework-tools:
        location
        framework settings

Each app and engine defined a bunch of settings. These settings need to correspond with the list of settings that the app expects. This list is defined in a manifest file called info.yml.

In addition to the various specific settings that needs to be defined for each item, each app, engine and framework also needs to define where its code is located. This is done using a special location parameter.

Code Locations

Tank currently supports app installation and management using the following sources:

![configuration](images/folder_location.png) ![configuration](images/git_location.png) ![configuration](images/github_location.png) ![configuration](images/app_store_location.png)

Each of the above has a slightly different Location definition in the environment file.

Apps in the local file system

Pointing tank to an app that resides in the local file system is typically something you do when you do development. Use the following syntax:

location: {"type": "dev", "path": "/path/to/app"}

The above syntax means that tank will look for the app in the location specified by path. This normally works fine, however, if you need to do development on multiple platforms at the same time, you need to specify the path in a platform specific fashion. In that case, use the following syntax:

location: {"type": "dev", 
           "windows_path": "c:\\path\\to\\app", 
           "linux_path": "/path/to/app", 
           "mac_path": "/path/to/app"}

You can also include environment variables in the syntax -- this is handy if you want to set up a generic dev area for a small team. Typically, it would look something like this:

location: {"type": "dev", "path": "${HOME}/dev/tank/tk-nuke-myapp"}

Since Tank does not know what version of the app is being run, it will return Undefined for an app referenced using the dev type. Sometimes, especially when doing framework development, it can be useful to be able to specify a version number. In that case, you can specify a specific version number and Tank will associate this version number with the app:

location: {"type": "dev", "path": "/path/to/app", "version": "v0.2.1"}

For production configurations, we recommend one of the other location specifiers.

Apps in git (and github)

If you manage your apps in a local git repository, this location syntax will let you work with multiple versions of an app in Tank easily! Use the following syntax in the environment file:

location: {"type": "git", "path": "/path/to/repo.git", "version": "v0.2.1"}
location: {"type": "git", "path": "user@remotehost:/path_to/repo.git", "version": "v0.1.0"}
location: {"type": "git", "path": "git://github.com/manneohrstrom/tk-hiero-publish.git", "version": "v0.1.0"}
location: {"type": "git", "path": "https://github.com/manneohrstrom/tk-hiero-publish.git", "version": "v0.1.0"}

As shown in the examples above, the git descriptor handles both local and remote repositories. It also handles private repositories in github, assuming that you have set up your ssh authentication correctly. On Windows, recommend that you use forward slashes.

Note! When you are using the git location, you need to have the git executable in the PATH in order for Tank to be able to do an app update check or app download. (the git exeuctable is, however, not needed during daily app execution, only when you are doing upgrades and installs).

When you install and app with this location, tank will look for a repository in the path specified and download the tag version specified into its local app storage. Note that you only need access to the git repository when you perform app maintenance such as updates and installation. During normal tank operation, tank will load the app from a local app storage. When looking for updates, tank will retrieve all tags from the repository and run a version comparison, trying to determine the highest number.

Apps in the Tank Store

We also provide a special app store for Tank Apps and Engines. If you want to use an app from the app store, use the following syntax:

location: {"type": "app_store", "name": "tk-nukepublish", "version": "v0.5.0"}

Similar to the git location, tank will locate the repository, download the specified tag into a local app storage and execute the code from there.

Manual management of Apps and Engines

We also provide a manual mode to make it easy to manage production installations of apps and engines without any automation. This is similar to the Tank Store approach described above, except it contains no automation whatsoever; it is up to you to install the code in the right place and no automated update checks can take place. The manual mode uses the following syntax:

location: {"type": "manual", "name": "tk-nuke-publish", "version": "v0.5.0"}

It will look for the code in a manual folder, so with the example above, Tank will look for the code in the install/apps/manual/tk-nuke-publish/v0.5.0 folder.

Disabling Tank Apps and Engines

Sometimes it can be useful to temporarily disable an app or an engine. The recommended way of doing this is to to add a disabled: true parameter to the location dictionary that specifies where the app or engine should be loaded from. This syntax is supported by all the different location types. It may look like this for example:

location: {"type": "app_store", "name": "tk-nukepublish", "version": "v0.5.0", "disabled": true}

Alternatively, if you want an app to only run on certain platforms, you can specify this using the special deny_platforms setting:

location: {"type": "app_store", "name": "tk-nukepublish", "version": "v0.5.0", "deny_platforms": [windows, linux]}

Possible values for the deny_platforms parameter are windows, linux, and mac.

For App Developers: Manifest file

Apps, engines and frameworks each have a metadata file. It always resides in the root of the app or engine and is always named info.yml. This metadata file contains important information about the item:

  • All the settings that the app or engine expects to have been specified in any environment where the item is loaded.
  • All custom Shotgun fields that are required by the app or engine code.
  • An optional field defining a display name for the app.
  • An optional field to specify which engines this app works with.
  • An optional set of frameworks that are required in order for this app to run.

Below is an example of what such a file may look like:

configuration:
    # Configuration settings definitions

requires_shotgun_fields:
    # Shotgun fields that this app expects

# List of engines with which this app works (optional)
supported_engines: ["tk-nuke", "tk-maya"]

# List of frameworks which are needed to run the app (optional)
frameworks:
    - {"name": "tk-framework-widget", "version": "v0.1.2"}
    - {"name": "tk-framework-tools", "version": "v0.1.5"}

# More verbose description of this item 
display_name: "Nicely formatted name"
description: "One line description of what the app does."

# optional url links to documentation and support
documentation_url: "http://intranet/path/to/tank_app_docs.html"
support_url: "http://intranet/pipeline_team/support.html"

# Required minimum versions for this item to run
requires_shotgun_version: "v4.2"
requires_engine_version: "v0.2.21"
requires_core_verson: "v0.12.4"
 
# what operating systems are supported?
# leaving this out, or blank means that all operating systems
# are supported. Valid choices are windows, linux and mac
supported_platforms: ["windows", "linux"]

# what parts of the context are required for this app?
# possible choices are project, entity, step, task, user
required_context: ["project", "entity", "user"]

Shotgun fields

Shotgun fields that are required for any app are defined in the following way:

entity_type:
    - { "system_name": "sg_xxx", "type": "sg_type" }
    - { "system_name": "sg_yyy", "type": "sg_type" }
    - { "system_name": "sg_zzz", "type": "sg_type" }

Tank's deploy system will ensure that these fields all exist once the app or engine has been installed. A real example could look like this:

requires_shotgun_fields:
    # Shotgun fields that this app expects
    Version:
        - { "system_name": "sg_movie_type", "type": "text" }

Supported Engines

Normally, for apps that are designed to run in a single engine, this parameter can be omitted. However, if your app supports multiple engines, you can specify them as a list and Tank will validate that the engine which is loading the app is supported.

Frameworks

If a framework is being used by the app, declare it in the info.yml and tank will keep track and make sure that it is installed and available. Once inside the app, use the call module_name = tank.platform.import_framework("tk-framework-name", "module_name") instead of a local import (e.g. from . import module_name).

Display name and Description

The optional display_name field defines the name that the user will see for the app. The optional description field is a brief one line description of what the app does.

Version constraints

If your app or engine requires specific versions of shotgun, the core or other things, you can specify this using the three parameters requires_shotgun_version, requires_core_verson and (for apps only) requires_engine_version.

Documentation

If you are developing an app for the tank app store, no need to fill this in - the Tank Store manages documentation separately! But if you are building an in-house app for your studio, it can be useful to link it up to a wiki page or similar, so that it is easy for users to jump straight from the app to the documentation. In this case, just add a documentation_url setting to your app's info.yml manifest file:

documentation_url: "http://intranet/path/to/tank_app_docs.html"

This will be picked up and displayed in various locations in the Tank UIs.

Support

Similar to the documentation url above, it can be useful to connect an app to a url which lets users know how to get help when they have questions. If you have a separate system in your studio, (like an Request Tracker setup), and you want to make it easy for users to reach out from the app to this system, just define a support_url url:

support_url: "http://intranet/pipeline_team/support.html"

This setting is optional, and if left blank, the support url will automatically be the standard Tank support location.

Supported Operating Systems

If your app or engine only supports a particular operating system, you can define this using a supported_platforms parameter. Valid values are linux, windows and mac. This is an optional setting - omitting it or leaving it blank means that the app or engine will work on all platforms.

Required Context Fields

Tank has a Context which it uses to determine what the current Shot, Project or Asset is. Apps may require a particular feature to be present in the context - for example, a Loader App may require an entity to be present in order to show a list of items for the current Asset or Shot. The required_context settings help defining what fields are needed. Possible values are project, entity, step, task and user.

The Configuration Section

If an app requires a setting in its code, it should be defined in the info.yml. The Tank Platform will keep tabs on all requested settings and make sure that they have all been defined and are valid before apps are launched. It will also use this metadata when performing upgrades and installations.

A configuration entry typically looks like this:

setting_name:
    type: some_type
    description: "description of the setting"
    default_value: some_value
    option: option_value
    option: option_value

Data types typically have specific optional settings. All data types and their options are outlines in the following sections.

A note about default values

In the configuration you can define default value for the various app parameters that you define. Please note that these default values are not being read at run-time, but only used to populate the environment configuration when an app is being installed or upgraded. Tank's configuration files are non-sparse, meaning that all parameters need to be populated in the configuration. A default value effectively means a value which will be set at install or upgrade time in case no other value is provided.

Values that are procedurally populated by hooks

For advanced use cases, it is possible to specify a configuration value as a special hook evaluator rather than as a template setting. This means that when you configure your tank environment, rahter than specifying an actual value for a setting to use with your app, you can specify a piece of code that returns the value to use. This makes it possible to create very complex settings logic. For more information, see the example_template_hook.py located in the core hooks area.

Simple Data Types

A number of simple data types are supported. These do not have any special options.

  • str - a string value
  • int - an integer
  • float - a floating point value
  • bool - a boolean, expecting values true or false

An example declaration for a simple data type may look like this:

debug_logging: 
    type: bool
    default_value: false
    description: Controls whether debug messages should be emitted to the logger 

config_path

Use this when your app requires an external file that is part of the tank configuration. Typically, this settings type is used when you want to allow for a user to associate files with a tank configuration. These files can be icons or other resource files that should be part of the configuration. These paths should always be defined without an initial slash and using slashes as its path separator. Tank will translate it into a valid windows path.

output_icon:
    type: config_path
    description: A config centric path that points to a square icon png file. 

tank_type

Use this when you want a setting which expects a Tank Type - these are typically used when publishing data to Shotgun. Value is a string matching TankType.code.

published_script_tank_type:
    type: tank_type
    description: The string value of the TankType used for published Nuke scripts.

shotgun_entity_type

Value is a string that represents a Shotgun entity type like Task, Sequence, Shot.

entity_type:
    type: shotgun_entity_type
    default_value: Shot
    description: "The entity type to attach to" 

shotgun_permission_group

Value is a string that represents the display name of a Shotgun permission group like Admin, Artist.

permissions_group:
    type: shotgun_permission_group
    default_value: Artist
    description: "Permissions group to use when performing the operation" 

shotgun_filter

Value is a filter that will be passed to the shotgun api when performing a query (e.g. ["sg_status_list", "is", "cmpt"]). As shotgun filters can take multiple forms, no additional validation will be done on values of this type.

publish_filters:
    type: list
    values:
        type: shotgun_filter

template

Value is a string matching an entry in templates.yml. Using the fields option you can tell Tank to check that the template that is being used in a configuration has the fields that the code expects. Using the allows_empty option (False by default) you can allow empty template values.

output_render:
    description: Render output location
    type: template
    fields: "context, name, channel, version, [width], [height], [eye]"
    allows_empty: True

When you specify the fields your app requires, it needs to be strict. Tank will make sure that the template that the user has chosen to configure the app with exactly matches the values specified in the fields string. Typically, the app will also pull in fields via the context object - you can specify this by using the special context parameter. Optional parameters are represented with [brackets] and the special token * indicates that this parameter accepts an arbitrary number of fields. For example:

  • fields: name - only templates containing a single field name will be valid
  • fields: context, name - templates containing exactly the number of fields that the context is able to resolve, and name, will be valid.
  • fields: context, name, [width], [height] - same as previous but the two fields width and height can be present in the template at the user's discression.
  • fields: name, * - name is required, the rest of the fields can be arbitrary.

A typical example illustrating the use of * is when you need to look for things in the scene which do not belong to the current context - for example if you are working on a shot and wants to scan for assets that have been imported into the scene. In this case, you cannot use the context since this is pointing at the current Shot.

input_templates_to_look_for:
    type: list
    description: List of templates to look for when scanning the scene for inputs. 
                A template listed here only needs to have a field called version. This field
                will be used in the comparison to determine what is out of date.
    allows_empty: True
    values:
        type: template
        fields: "version, *"

hook

Value is a string. Tank will automatically append the py extension to it and then look for the file in the hooks directory. Hook settings need to specify a list of parameters that need to be defined by the hook which is being specified in the configuration.

hook_publish_file:
    type: hook
    default: publish_file
    description: Called when a file is published, e.g. copied from a work area to a publish area.
    parameters: [source_path, target_path]

If you specify a default value for your hook setting, Tank's app installer will set the value in your environment configuration to default when the app is installed. Later on, whenever, the hooks needs to be loaded, tank will load the default hook implementation that comes bundled with the app.

If you for eaxmple have the following app configuration in your environment, tank notice the value being set to default, go to the app install location, look in the info.yml manifest for a default value (in this case it would fine publish_file) and then look for that python file in the application's hooks folder (APP_LOCATION/hooks/publish_file.py):

my-publish-app:
   location: {...}
   publish_template: ...
   work_template: ...
   publish_hook: default

When you configure an app, if you don't want to use the default hook but a hook that you have written yourself, just change the value from default to whatever you want to name your hook. If you for example have a hook named my_publish_hook.py located in the hooks folder in your tank project configuration and want this to be used instead, just set the the app config like this:

my-publish-app:
   location: {...}
   publish_template: ...
   work_template: ...
   publish_hook: my_publish_hook

Some hooks are complex and cover multiple applications. In order to reduce complexity and to make the default hooks more valuable as sample code, it is possible to create default hooks per engine. For example, if you have an app that runs in both maya and nuke and you want to implement a hook for both engines, you could create two hooks:

  • APP_LOCATION/hooks/publish_file_tk-maya.py
  • APP_LOCATION/hooks/publish_file_tk-nuke.py

Then in your app manifest, just specify the default hook value like this:

hook_publish_file:
    type: hook
    default: "publish_file_{engine_name}"
    description: Called when a file is published, e.g. copied from a work area to a publish area.
    parameters: [source_path, target_path]

list

Value is a list, all values in the list must be of the same data type. You must supply values dict that describes the data type of the list items.

entity_types:
    type: list
    values: {type: shotgun_entity_type}
    default_value: [Sequence,Shot,Asset,Task]
    description: "List of Shotgun entity types where this 
                 tank action should be visible on the Actions menu." 

Optionally you can also specify an allows_empty option if an empty list is a valid value:

tank_types:
    type: list
    allows_empty: True
    values: {type: tank_type}

You would then be able to specify an empty list in your environment configuration:

apps:
    tk-multi-loader:
        tank_types: []

dict

Value is a dictionary, keys are always strings, values can be of mixed types.

In info.yml, optionally provide an items dict. Used to mark what keys must be in the config, default values, and type info for the values which will be used for validation.

write_nodes:
    type: list
    description: "A list of dictionaries in which you define the Tank write nodes that 
                 are supported in this configuration. Each dictionary entry needs to have
                 the following keys: name - a descriptive name for this node. file_type -
                 the file type to use for the renders (exr, cin, dpx etc). This will be 
                 passed to the Nuke write node when rendering. settings - configuration
                 settings for the given file type, as a dictionary. This too will be 
                 passed to the write node when rendering. Lastly, you need two entries 
                 named render_template and publish_template 
                 - these control the locations where data is written to at various stages 
                 of the workflow. These templates need to include the fields 
                 name, channel and version, and can optionally include the fields width and
                 height which reflect the image resolution of the render. If you are doing
                 stereo rendering and want to use Nuke's %V flag, include an eye field. 
                 This will be replaced by %V in the paths when the tank write node 
                 computes them."
    allows_empty: True
    values:
        type: dict
        items:
            name: { type: str }
            file_type: { type: str }
            settings: { type: dict }
            tank_type: { type: tank_type }
            render_template:
                type: template
                required_fields: [name,channel,version,SEQ]
                optional_fields: [width,height,eye]
            publish_template:
                type: template
                required_fields: [name,channel,version,SEQ]
                optional_fields: [width,height,eye]

Complex Examples

A list of dictionaries, each with keyes type, tank_type, template

movies:
    type: list
    description: list of dictionaries. This list should contain one entry for every type
                 of movies that needs to be rendered at publish time. Each list item
                 should be a dictionary with the keys type and template, defining the name
                 of the movies to make and the template to base its path on. This template
                 should have a subset of the fields available to the render template.
    allows_empty: True
    values:
        type: dict
        items:
            type: { type: str }
            tank_type: { type: tank_type }
            template:
                type: template
                required_fields: [name,channel,version]
                optional_fields: [width,height,eye]

A valid setting could look like this:

movies:
- {tank_type: Quicktime, template: shot_quicktime_full_res, type: standard}
- {tank_type: Quicktime, template: shot_quicktime_half_res, type: half_res}
Clone this wiki locally