TrueChartsClone/.github/docs/development/questions-yaml.md

9.5 KiB

Questions.yaml

Questions.yaml is the file which get rendered by TrueNAS to create the UI. When not creating new charts, most of what this project does is stitching together questions.yaml files to turn existing Helm Charts into Apps.

Syntax

In this document we give you a short reference guide (ported from IX Official) which lays out the settings available in questions.yaml.

Question Variable Reference

Variable Type Required Description
variable string true define the variable name specified in the values.yamlfile.
label string true define the UI label.
description string false specify the description of the variable.
group string false group questions by input value.
schema dictionary true specify schema details for the variable
schema.type string true specify type of value for variable (current supported types are string, int, boolean, path, hostpath, list, dict, ipaddr, and cron).
schema.required bool false define if the variable is required or not (true \ false), defaults to false
schema.default object false specify the default value.
schema.min_length int false min character length for string type variable.
schema.max_length int false max character length for string type variable.
schema.min int false min integer length.
schema.max int false max integer length.
schema.enum []dictionary false specify the options when the variable type is string, for example,

enum:
- value: "RollingUpdate"
  description: "Create new pods and then kill old ones"
- value: "Recreate"
  description: "Kill existing pods before creating new ones"
schema.valid_chars string false regular expression for input chars validation.
schema.subquestions []subquestion false add an array of subquestions.
schema.show_if string false show current variable if condition specified is true, for example show_if: [["workloadType", "=", "CronJob"]]
schema.show_subquestions_if string false show subquestions if is true or equal to one of the options. for example show_subquestion_if: "static". system will convert this to the filters format specifid for shcema.show_if automatically.
schema.attrs []variables false specified when schema.type is dictionary to declare attributes allowed in the dictionary.
schema.items []variables false specified when schema.type is list to declare attributes allowed in the list.
schema.private bool false specified for declaring information sensitive fields.
schema.null bool false specifies if the value for the variable can be null. defaults to false.
Subquestions

subquestions[] cannot contain subquestions or show_subquestions_if keys, but all other keys in the above table are supported. Also variables having schema.type list do not support subquestions.

Special Questions

There are some novel cases where we would like to provide ability to configure / manage resources for workloads with getting some data from system dynamically. So a chart can specify certain actions to be performed by the system for a variable by defining a reference. An example better illustrates this concept:

- variable: volume
  label: "Volume"
  schema:
    type: dict
    $ref:
      - "normalize/ixVolume"
attrs:
      - variable: mountPath
        label: "Mount Path"
        description: "Path where the volume will be mounted inside the pod"
        schema:
          type: path
          required: true
      - variable: datasetName
label: "Dataset Name"
        schema:
          type: string
          required: true

In the above variable we define a $ref in schema which specifies that the system should take some action for normalising the value specified for the variable. In this specific case, ix_volume is a concept introduced where we recommend using a volume which we are able to rollback automatically on chart release rollback. In essence, it is just a hostPath volume for which the system automatically creates the dataset specified.

We have following types of actions supported in $ref right now:

  1. definitions
  2. normalize

For (1), system will automatically update schema for a particular definition. For example,

- variable: hostInterface
  description: "Please specify host interface"
label: "Host Interface"
  schema:
    type: string
    required: true
    $ref:
      - "definitions/interface"

System will automatically populate available interfaces for the user based on what interfaces are available on the system.

For (2), system will normalize values or perform some actions as discussed above.

Standardised questions.yaml sections

To minimise the maintenance load of our App collection, we always aim to standardise as much as possible. The same goes for questions.yaml. Included here are some code standardised code-snippets that are expected to be included in every App.

Be aware that sometimes specific functions might or might not completely function. Leaving them out would, however, everely increase the maintenance load and often said functionality will be added in the common-chart later on anyway.

General Configuration options

These options are always included because almost every chart (eventually) has a use for them and/or other parts of the common chart depend on them. They are called general options, because they affect the basic functionalities of a chart. For example: Custom User environment variables, permissions and timezones.

  - variable: timezone
    group: "Configuration"
    label: "Timezone"
    schema:
      type: string
      default: "Etc/UTC"
      $ref:
        - "definitions/timezone"

  - variable: PUID
    group: "Configuration"
    label: "PUID"
    description: "The UserID of the user running the application and owning the files"
    schema:
      type: int
      default: 568

  - variable: PGID
    group: "Configuration"
    label: "PGID"
    description: "The groupID of the user/group running the application and owning the files"
    schema:
      type: int
      default: 568

  - variable: UMASK
    group: "Configuration"
    label: "UMASK (advanced)"
    description: "The UMASK used if supported by the application"
    schema:
      type: string
      default: "002"

  # Configure Custom Enviroment Variables
  - variable: environmentVariables
    label: "Image environment"
    group: "Configuration"
    schema:
      type: list
      default: []
      items:
        - variable: environmentVariable
          label: "Environment Variable"
          schema:
            type: dict
            attrs:
              - variable: name
                label: "Name"
                schema:
                  type: string
              - variable: value
                label: "Value"
                schema:
                  type: string
Main Service

Services in Kubernetes (the underlaying framework in TrueNAS SCALE), are (simply put) internal loadbalancers. Besides being load balancers, they are always guaranteed to be reachable by (internal!) DNS name and (in some cases) prevent traffic from reaching your App when the healthcheck isn't finished yet (or is failing).

Every App is required to have a main service, the primary thing that users (or other Apps!) connect with. No mater if it's a webUI, an API, a database connection or something totally else, A service is always required.

Please keep in mind that every App is different, some just have one service (the primary one) and others need more (which get defined in appAdditionalService). Every App also uses different ports, so please alter accordingly.

  - variable: service
    group: "Networking"
    label: "Configure Service"
    schema:
      type: dict
      attrs:
        - variable: type
          label: "Service type"
          schema:
            type: string
            default: "ClusterIP"
            enum:
              - value: "NodePort"
                description: "NodePort"
              - value: "ClusterIP"
                description: "ClusterIP"
            show_subquestions_if: "NodePort"
            subquestions:
              - variable: port
                label: "Port configuration"
                schema:
                  type: dict
                  attrs:
                    - variable: port
                      label: "container port"
                      schema:
                        type: int
                        default: 80
                        editable: false
                    - variable: nodePort
                      label: "Node Port to expose for UI"
                      schema:
                        type: int
                        min: 9000
                        max: 65535
                        default: 36052
                        required: true

_ Note: Our final main service format has not been fully completed as of yet, this might change the above snipped considerably_