{
  "$id": "https://firefox-ci-tc.services.mozilla.com/schemas/generic-worker/multiuser_windows.json#",
  "$schema": "https://firefox-ci-tc.services.mozilla.com/schemas/common/metaschema.json#",
  "additionalProperties": false,
  "definitions": {
    "content": {
      "oneOf": [
        {
          "additionalProperties": false,
          "description": "Requires scope `queue:get-artifact:<artifact-name>`.\n\nSince: generic-worker 5.4.0",
          "properties": {
            "artifact": {
              "maxLength": 1024,
              "type": "string"
            },
            "sha256": {
              "description": "If provided, the required SHA256 of the content body.\n\nSince: generic-worker 10.8.0",
              "pattern": "^[a-f0-9]{64}$",
              "title": "SHA 256",
              "type": "string"
            },
            "taskId": {
              "pattern": "^[A-Za-z0-9_-]{8}[Q-T][A-Za-z0-9_-][CGKOSWaeimquy26-][A-Za-z0-9_-]{10}[AQgw]$",
              "type": "string"
            }
          },
          "required": [
            "taskId",
            "artifact"
          ],
          "title": "Artifact Content",
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "Content originating from a task artifact that has been indexed by the Taskcluster Index Service.\n\nSince: generic-worker 51.0.0",
          "properties": {
            "artifact": {
              "maxLength": 1024,
              "type": "string"
            },
            "namespace": {
              "maxLength": 255,
              "type": "string"
            }
          },
          "required": [
            "namespace",
            "artifact"
          ],
          "title": "Indexed Content",
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "URL to download content from.\n\nSince: generic-worker 5.4.0",
          "properties": {
            "sha256": {
              "description": "If provided, the required SHA256 of the content body.\n\nSince: generic-worker 10.8.0",
              "pattern": "^[a-f0-9]{64}$",
              "title": "SHA 256",
              "type": "string"
            },
            "url": {
              "description": "URL to download content from.\n\nSince: generic-worker 5.4.0",
              "format": "uri",
              "title": "URL",
              "type": "string"
            }
          },
          "required": [
            "url"
          ],
          "title": "URL Content",
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "Byte-for-byte literal inline content of file/archive, up to 64KB in size.\n\nSince: generic-worker 11.1.0",
          "properties": {
            "raw": {
              "description": "Byte-for-byte literal inline content of file/archive, up to 64KB in size.\n\nSince: generic-worker 11.1.0",
              "maxLength": 65536,
              "title": "Raw",
              "type": "string"
            }
          },
          "required": [
            "raw"
          ],
          "title": "Raw Content",
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "Base64 encoded content of file/archive, up to 64KB (encoded) in size.\n\nSince: generic-worker 11.1.0",
          "properties": {
            "base64": {
              "description": "Base64 encoded content of file/archive, up to 64KB (encoded) in size.\n\nSince: generic-worker 11.1.0",
              "maxLength": 65536,
              "pattern": "^[A-Za-z0-9/+]+[=]{0,2}$",
              "title": "Base64",
              "type": "string"
            }
          },
          "required": [
            "base64"
          ],
          "title": "Base64 Content",
          "type": "object"
        }
      ]
    },
    "fileMount": {
      "additionalProperties": false,
      "properties": {
        "content": {
          "$ref": "#/definitions/content",
          "description": "Content of the file to be mounted.\n\nSince: generic-worker 5.4.0"
        },
        "file": {
          "description": "The filesystem location to mount the file. This can be a\npath relative to the task directory, or an absolute path.\nThe file will be created as the task user, so the target\nlocation must be writable by the task user.\n\nSince: generic-worker 5.4.0",
          "title": "File",
          "type": "string"
        },
        "format": {
          "description": "Compression format of the preloaded content.\n\nSince: generic-worker 55.3.0",
          "enum": [
            "br",
            "bz2",
            "gz",
            "lz",
            "lz4",
            "mz",
            "sz",
            "xz",
            "zst",
            "zz"
          ],
          "title": "Format",
          "type": "string"
        }
      },
      "required": [
        "file",
        "content"
      ],
      "title": "File Mount",
      "type": "object"
    },
    "mount": {
      "oneOf": [
        {
          "$ref": "#/definitions/fileMount"
        },
        {
          "$ref": "#/definitions/writableDirectoryCache"
        },
        {
          "$ref": "#/definitions/readOnlyDirectory"
        }
      ],
      "title": "Mount"
    },
    "readOnlyDirectory": {
      "additionalProperties": false,
      "properties": {
        "content": {
          "$ref": "#/definitions/content",
          "description": "Contents of read only directory.\n\nSince: generic-worker 5.4.0",
          "title": "Content"
        },
        "directory": {
          "description": "The filesystem location to mount the directory volume.\nThis can be a path relative to the task directory, or an\nabsolute path. The directory will be created as the task\nuser, so the target location must be writable by the task\nuser.\n\nSince: generic-worker 5.4.0",
          "title": "Directory",
          "type": "string"
        },
        "format": {
          "description": "Archive format of content for read only directory.\n\nSince: generic-worker 5.4.0",
          "enum": [
            "7z",
            "rar",
            "tar",
            "tar.br",
            "tar.bz2",
            "tar.gz",
            "tar.lz",
            "tar.lz4",
            "tar.mz",
            "tar.sz",
            "tar.xz",
            "tar.zst",
            "tar.zz",
            "zip"
          ],
          "title": "Format",
          "type": "string"
        }
      },
      "required": [
        "directory",
        "content",
        "format"
      ],
      "title": "Read Only Directory",
      "type": "object"
    },
    "writableDirectoryCache": {
      "additionalProperties": false,
      "dependencies": {
        "content": [
          "format"
        ],
        "format": [
          "content"
        ]
      },
      "properties": {
        "cacheName": {
          "description": "Implies a read/write cache directory volume. A unique name for the\ncache volume. Requires scope `generic-worker:cache:<cache-name>`.\nNote if this cache is loaded from an artifact, you will also require\nscope `queue:get-artifact:<artifact-name>` to use this cache.\n\nSince: generic-worker 5.4.0",
          "title": "Cache Name",
          "type": "string"
        },
        "content": {
          "$ref": "#/definitions/content",
          "description": "Optional content to be preloaded when initially creating the cache\n(if set, `format` must also be provided).\n\nSince: generic-worker 5.4.0",
          "title": "Content"
        },
        "directory": {
          "description": "The filesystem location to mount the directory volume.\nThis can be a path relative to the task directory, or an\nabsolute path. The directory will be created as the task\nuser, so the target location must be writable by the task\nuser.\n\nSince: generic-worker 5.4.0",
          "title": "Directory Volume",
          "type": "string"
        },
        "format": {
          "description": "Archive format of the preloaded content (if `content` provided).\n\nSince: generic-worker 5.4.0",
          "enum": [
            "7z",
            "rar",
            "tar",
            "tar.br",
            "tar.bz2",
            "tar.gz",
            "tar.lz",
            "tar.lz4",
            "tar.mz",
            "tar.sz",
            "tar.xz",
            "tar.zst",
            "tar.zz",
            "zip"
          ],
          "title": "Format",
          "type": "string"
        }
      },
      "required": [
        "directory",
        "cacheName"
      ],
      "title": "Writable Directory Cache",
      "type": "object"
    }
  },
  "description": "This schema defines the structure of the `payload` property referred to in a\nTaskcluster Task definition.",
  "properties": {
    "artifacts": {
      "description": "Artifacts to be published.\n\nSince: generic-worker 1.0.0",
      "items": {
        "additionalProperties": false,
        "properties": {
          "contentEncoding": {
            "description": "Content-Encoding for the artifact. If not provided, `gzip` will be used, except for the\nfollowing file extensions, where `identity` will be used, since they are already\ncompressed:\n\n* 7z\n* aab\n* apk\n* bz2\n* deb\n* dmg\n* flv\n* gif\n* gz\n* jar\n* jpeg\n* jpg\n* npz\n* pkg\n* png\n* swf\n* tbz\n* tgz\n* wasm\n* webp\n* whl\n* woff\n* woff2\n* xpi\n* xz\n* zip\n* zst\n\nNote, setting `contentEncoding` on a directory artifact will apply the same content\nencoding to all the files contained in the directory.\n\nSince: generic-worker 16.2.0",
            "enum": [
              "identity",
              "gzip"
            ],
            "title": "Content-Encoding header when serving artifact over HTTP.",
            "type": "string"
          },
          "contentType": {
            "description": "Explicitly set the value of the HTTP `Content-Type` response header when the artifact(s)\nis/are served over HTTP(S). If not provided (this property is optional) the worker will\nguess the content type of artifacts based on the filename extension of the file storing\nthe artifact content. It does this by looking at the system filename-to-mimetype mappings\ndefined in the Windows registry. Note, setting `contentType` on a directory artifact will\napply the same contentType to all files contained in the directory.\n\nSee [mime.TypeByExtension](https://pkg.go.dev/mime#TypeByExtension).\n\nSince: generic-worker 10.4.0",
            "title": "Content-Type header when serving artifact over HTTP",
            "type": "string"
          },
          "expires": {
            "description": "Date when artifact should expire must be in the future, no earlier than task deadline, but\nno later than task expiry. If not set, defaults to task expiry.\n\nSince: generic-worker 1.0.0",
            "format": "date-time",
            "title": "Expiry date and time",
            "type": "string"
          },
          "name": {
            "description": "Name of the artifact, as it will be published. If not set, `path` will be used.\nConventionally (although not enforced) path elements are forward slash separated. Example:\n`public/build/a/house`. Note, no scopes are required to read artifacts beginning `public/`.\nArtifact names not beginning `public/` are scope-protected (caller requires scopes to\ndownload the artifact). See the Queue documentation for more information.\n\nSince: generic-worker 8.1.0",
            "title": "Name of the artifact",
            "type": "string"
          },
          "optional": {
            "default": false,
            "description": "If `true`, the artifact is optional. If the file or directory\ndoesn't exist, the artifact won't be created.\n\nSince: generic-worker 83.1.0",
            "title": "Optional artifact",
            "type": "boolean"
          },
          "path": {
            "description": "Filesystem path of the file/directory relative to the\ntask directory, or an absolute path.\nExample: `dist\\regedit.exe`. It doesn't matter if\nforward slashes or backslashes are used.\n\nSince: generic-worker 1.0.0",
            "title": "Artifact location",
            "type": "string"
          },
          "type": {
            "description": "Artifacts can be either an individual `file` or a `directory` containing\npotentially multiple files with recursively included subdirectories.\n\nSince: generic-worker 1.0.0",
            "enum": [
              "file",
              "directory"
            ],
            "title": "Artifact upload type.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "path"
        ],
        "title": "Artifact",
        "type": "object"
      },
      "title": "Artifacts to be published",
      "type": "array",
      "uniqueItems": true
    },
    "command": {
      "description": "One entry per command (consider each entry to be interpreted as a full line of\na Windows™ .bat file). For example:\n```\n[\n  \"set\",\n  \"echo hello world > hello_world.txt\",\n  \"set GOPATH=C:\\\\Go\"\n]\n```\n\nSince: generic-worker 0.0.1",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "title": "Commands to run",
      "type": "array",
      "uniqueItems": false
    },
    "env": {
      "additionalProperties": {
        "type": "string"
      },
      "description": "Env vars must be string to __string__ mappings (not number or boolean). For example:\n```\n{\n  \"PATH\": \"C:\\\\Windows\\\\system32;C:\\\\Windows\",\n  \"GOOS\": \"windows\",\n  \"FOO_ENABLE\": \"true\",\n  \"BAR_TOTAL\": \"3\"\n}\n```\n\nNote, the following environment variables will automatically be set in the task\ncommands:\n  * `TASK_ID` - the task ID of the currently running task\n  * `RUN_ID` - the run ID of the currently running task\n  * `TASK_WORKDIR` - the working directory of the currently running task\n  * `TASK_GROUP_ID` - the task group ID of the currently running task\n  * `TASKCLUSTER_ROOT_URL` - the root URL of the taskcluster deployment\n  * `TASKCLUSTER_PROXY_URL` (if taskcluster proxy feature enabled) - the\n     taskcluster authentication proxy for making unauthenticated taskcluster\n     API calls\n  * `TASK_USER_CREDENTIALS` (if payload feature `runTaskAsCurrentUser` set to\n    `true` in the task definition - the absolute file location of a\n    json file containing the current task OS user account name and password.\n    This is only useful for the generic-worker multiuser CI tasks, where\n    `runTaskAsCurrentUser` is set to `true`.\n  * `TASKCLUSTER_INSTANCE_TYPE` - the cloud instance type of the worker (optional, not all workers run in a cloud)\n  * `TASKCLUSTER_WORKER_LOCATION`. See\n    [RFC #0148](https://github.com/taskcluster/taskcluster-rfcs/blob/master/rfcs/0148-taskcluster-worker-location.md)\n    for details.\n\nSince: generic-worker 0.0.1",
      "title": "Env vars",
      "type": "object"
    },
    "features": {
      "additionalProperties": false,
      "description": "Feature flags enable additional functionality.\n\nSince: generic-worker 5.3.0",
      "properties": {
        "backingLog": {
          "default": true,
          "description": "The backing log feature publishes a task artifact containing the complete\nstderr and stdout of the task.\n\nSince: generic-worker 48.2.0",
          "title": "Enable backing log",
          "type": "boolean"
        },
        "chainOfTrust": {
          "description": "Artifacts named `public/chain-of-trust.json` and\n`public/chain-of-trust.json.sig` should be generated which will\ninclude information for downstream tasks to build a level of trust\nfor the artifacts produced by the task and the environment it ran in.\n\nSince: generic-worker 5.3.0\n\nTasks may inject additional data into the certificate by writing them\nas json to file chain-of-trust-additional-data.json in the task\ndirectory.\n\nSince: generic-worker 81.0.0",
          "title": "Enable generation of signed Chain of Trust artifacts",
          "type": "boolean"
        },
        "hideCmdWindow": {
          "default": false,
          "description": "If `true`, the command window for each command will be hidden.\nThis is useful for tasks that run GUI applications to prevent\nthe command window from obscuring the application window.\n\nThe process creation flags used when this is set to `true`\nare CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW. If this is\nset to `false`, the flags used are CREATE_NEW_PROCESS_GROUP|CREATE_NEW_CONSOLE.\nMore info about these flags can be found [here](https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags).\n\nIf your task needs to allocate new consoles (with\nAllocConsole(), for example) then you should not use this.\n\nSince: generic-worker 96.1.0",
          "title": "Hide cmd.exe window",
          "type": "boolean"
        },
        "interactive": {
          "description": "This allows you to interactively run commands from within the worker\nas the task user. This may be useful for debugging purposes.\nCan be used for SSH-like access to the running worker.\nNote that this feature works differently from the `interactive` feature\nin docker worker, which `docker exec`s into the running container.\nSince tasks on generic worker are not guaranteed to be running in a\ncontainer, a powershell instance is started on the task user's account.\nA user can then `docker exec` into the a running container, if there\nis one.\n\nSince: generic-worker 83.6.0",
          "title": "Interactive shell",
          "type": "boolean"
        },
        "liveLog": {
          "default": true,
          "description": "The live log feature streams the combined stderr and stdout to a task artifact\nso that the output is available while the task is running.\n\nSince: generic-worker 48.2.0",
          "title": "Enable [livelog](https://github.com/taskcluster/taskcluster/tree/main/tools/livelog)",
          "type": "boolean"
        },
        "resourceMonitor": {
          "default": true,
          "description": "The resource monitor feature reports Peak System Memory Used,\nAverage System Memory Used, Average Available System Memory,\nand Total System Memory in the task log for each task command\nexecuted. It also will abort any task command if the used\nsystem memory exceeds worker config maxMemoryUsagePercent\n_AND_ available system memory drops below worker config\nminAvailableMemoryBytes for longer than worker config\nallowedHighMemoryDuration seconds. When this happens, the\ntask will be resolved as failed.\n\nSince: generic-worker 83.4.0",
          "title": "Resource monitor",
          "type": "boolean"
        },
        "runAsAdministrator": {
          "description": "Runs commands with UAC elevation. Only set to true when UAC is\nenabled on the worker and Administrative privileges are required by\ntask commands. When UAC is disabled on the worker, task commands will\nalready run with full user privileges, and therefore a value of true\nwill result in a malformed-payload task exception.\n\nA value of true does not add the task user to the `Administrators`\ngroup - see the `osGroups` property for that. Typically\n`task.payload.osGroups` should include an Administrative group, such\nas `Administrators`, when setting to true.\n\nFor security, `runAsAdministrator` feature cannot be used in\nconjunction with `chainOfTrust` feature.\n\nRequires scope\n`generic-worker:run-as-administrator:<provisionerId>/<workerType>`.\n\nSince: generic-worker 10.11.0",
          "title": "Run commands with UAC process elevation",
          "type": "boolean"
        },
        "runTaskAsCurrentUser": {
          "description": "If `true`, task commands will be executed as the\nuser currently running Generic Worker (typically\n`root` or `LocalSystem`), rather than as the\ndedicated task user created for the task. The task\nuser account will still be created, and is\navailable for the task to use.\n\nRequires scope `generic-worker:run-task-as-current-user:<provisionerID>/<workerType>`.\nTasks submitted without this scope will be resolved\nas `exception/malformed-payload`.\n\nSince: generic-worker 81.0.0",
          "title": "Run task as current user",
          "type": "boolean"
        },
        "taskclusterProxy": {
          "description": "The taskcluster proxy provides an easy and safe way to make authenticated\ntaskcluster requests within the scope(s) of a particular task. See\n[the github project](https://github.com/taskcluster/taskcluster/tree/main/tools/taskcluster-proxy) for more information.\n\nSince: generic-worker 10.6.0",
          "title": "Run [taskcluster-proxy](https://github.com/taskcluster/taskcluster/tree/main/tools/taskcluster-proxy) to allow tasks to dynamically proxy requests to taskcluster services",
          "type": "boolean"
        }
      },
      "required": [],
      "title": "Feature flags",
      "type": "object"
    },
    "logs": {
      "additionalProperties": false,
      "description": "Configuration for task logs.\n\nSince: generic-worker 48.2.0",
      "properties": {
        "backing": {
          "default": "public/logs/live_backing.log",
          "description": "Specifies a custom name for the backing log artifact.\nThis is only used if `features.backingLog` is `true`.\n\nSince: generic-worker 48.2.0",
          "title": "Backing log artifact name",
          "type": "string"
        },
        "live": {
          "default": "public/logs/live.log",
          "description": "Specifies a custom name for the live log artifact.\nThis is only used if `features.liveLog` is `true`.\n\nSince: generic-worker 48.2.0",
          "title": "Live log artifact name",
          "type": "string"
        }
      },
      "required": [],
      "title": "Logs",
      "type": "object"
    },
    "maxRunTime": {
      "description": "Maximum time the task container can run in seconds.\nThe maximum value for `maxRunTime` is set by a `maxTaskRunTime` config property specific to each worker-pool.\n\nSince: generic-worker 0.0.1",
      "minimum": 1,
      "multipleOf": 1,
      "title": "Maximum run time in seconds",
      "type": "integer"
    },
    "mounts": {
      "description": "Directories and/or files to be mounted.\n\nSince: generic-worker 5.4.0",
      "items": {
        "$ref": "#/definitions/mount",
        "title": "Mount"
      },
      "type": "array",
      "uniqueItems": false
    },
    "onExitStatus": {
      "additionalProperties": false,
      "description": "By default tasks will be resolved with `state/reasonResolved`: `completed/completed`\nif all task commands have a zero exit code, or `failed/failed` if any command has a\nnon-zero exit code. This payload property allows customsation of the task resolution\nbased on exit code of task commands.",
      "properties": {
        "purgeCaches": {
          "description": "If the task exits with a purge caches exit status, all caches\nassociated with the task will be purged.\n\nSince: generic-worker 49.0.0",
          "items": {
            "minimum": 0,
            "title": "Exit statuses",
            "type": "integer"
          },
          "title": "Purge caches exit status",
          "type": "array",
          "uniqueItems": true
        },
        "retry": {
          "description": "Exit codes for any command in the task payload to cause this task to\nbe resolved as `exception/intermittent-task`. Typically the Queue\nwill then schedule a new run of the existing `taskId` (rerun) if not\nall task runs have been exhausted.\n\nSee [itermittent tasks](https://docs.taskcluster.net/docs/reference/platform/taskcluster-queue/docs/worker-interaction#intermittent-tasks) for more detail.\n\nSince: generic-worker 10.10.0",
          "items": {
            "minimum": 1,
            "title": "Exit codes",
            "type": "integer"
          },
          "title": "Intermittent task exit codes",
          "type": "array",
          "uniqueItems": true
        }
      },
      "required": [],
      "title": "Exit code handling",
      "type": "object"
    },
    "osGroups": {
      "description": "A list of OS Groups that the task user should be a member of. Requires scope\n`generic-worker:os-group:<provisionerId>/<workerType>/<os-group>` for each\ngroup listed.\n\nSince: generic-worker 6.0.0",
      "items": {
        "type": "string"
      },
      "title": "OS Groups",
      "type": "array",
      "uniqueItems": true
    },
    "rdpInfo": {
      "description": "Specifies an artifact name for publishing RDP connection information.\n\nSince this is potentially sensitive data, care should be taken to publish\nto a suitably locked down path, such as\n`login-identity/<login-identity>/rdpinfo.json` which is only readable for\nthe given login identity (for example\n`login-identity/mozilla-ldap/pmoore@mozilla.com/rdpinfo.json`). See the\n[artifact namespace guide](https://docs.taskcluster.net/docs/manual/using/namespaces#artifacts) for more information.\n\nUse of this feature requires scope\n`generic-worker:allow-rdp:<provisionerId>/<workerType>` which must be\ndeclared as a task scope.\n\nThe RDP connection data is published during task startup so that a user\nmay interact with the running task.\n\nThe task environment will be retained for 12 hours after the task\ncompletes, to enable an interactive user to perform investigative tasks.\nAfter these 12 hours, the worker will delete the task's Windows user\naccount, and then continue with other tasks.\n\nNo guarantees are given about the resolution status of the interactive\ntask, since the task is inherently non-reproducible and no automation\nshould rely on this value.\n\nSince: generic-worker 10.5.0",
      "title": "RDP Info",
      "type": "string"
    },
    "supersederUrl": {
      "description": "This property is allowed for backward compatibility, but is unused.",
      "title": "unused",
      "type": "string"
    },
    "taskclusterProxyInterface": {
      "default": "localhost",
      "description": "Specifies whether taskcluster-proxy should listen on\nlocalhost interface (default) or search for a docker bridge\ninterface (for tasks that wish to call the taskcluster\nproxy from inside a docker container that does not share\nthe host network).",
      "enum": [
        "localhost",
        "docker-bridge"
      ],
      "title": "Network Interface for Taskcluster Proxy to listen on",
      "type": "string"
    }
  },
  "required": [
    "command",
    "maxRunTime"
  ],
  "title": "Generic worker payload - multiuser, windows",
  "type": "object"
}