getGPUSField() {
    const { data, errors, path, service } = this.props;
    if (service instanceof PodSpec) {
      return null;
    }

    const gpusPath = this.getFieldPath(path, "gpus");
    const gpusErrors = findNestedPropertyInObject(errors, gpusPath);
    const gpusDisabled = this.isGpusDisabled();

    let inputNode = (
      <FieldInput
        disabled={gpusDisabled}
        min="0"
        name={gpusPath}
        step="any"
        type="number"
        value={findNestedPropertyInObject(data, gpusPath)}
      />
    );

    if (gpusDisabled) {
      inputNode = (
        <Tooltip
          content={
            <Trans render="span">
              Docker Engine does not support GPU resources, please select
              Universal Container Runtime (UCR) if you want to use GPU
              resources.
            </Trans>
          }
          interactive={true}
          maxWidth={300}
          wrapText={true}
          wrapperClassName="tooltip-wrapper tooltip-block-wrapper"
        >
          {inputNode}
        </Tooltip>
      );
    }

    return (
      <FormGroup
        className="column-4"
        showError={Boolean(!gpusDisabled && gpusErrors)}
      >
        <FieldLabel className="text-no-transform">
          <FormGroupHeadingContent primary={true}>
            <Trans render="span">GPUs</Trans>
          </FormGroupHeadingContent>
        </FieldLabel>
        {inputNode}
        <FieldError>{gpusErrors}</FieldError>
      </FormGroup>
    );
  }
    return containers.map((item, index) => {
      const artifactsPath = `containers.${index}.artifacts`;
      const artifacts = findNestedPropertyInObject(data, artifactsPath) || [];
      const artifactErrors =
        findNestedPropertyInObject(errors, artifactsPath) || [];

      return (
        <TabView key={index} id={`container${index}`}>
          <ErrorsAlert
            errors={this.getErrors()}
            pathMapping={ServiceErrorPathMapping}
            hideTopLevelErrors={!showAllErrors}
          />
          <Trans render="h1" className="flush-top short-bottom">
            Container
          </Trans>
          <Trans render="p">
            Configure your container below. Enter a container image or command
            you want to run.
          </Trans>
          <ContainerServiceFormSection
            data={data}
            errors={errors}
            onAddItem={this.handleAddItem}
            onRemoveItem={this.handleRemoveItem}
            path={`containers.${index}`}
            service={service}
          />

          <AdvancedSection>
            <AdvancedSectionLabel>
              <Trans render="span">More Settings</Trans>
            </AdvancedSectionLabel>
            <AdvancedSectionContent>
              <MultiContainerFormAdvancedSection
                data={data}
                path={`containers.${index}`}
              />
              <ArtifactsSection
                data={artifacts}
                path={artifactsPath}
                errors={artifactErrors}
                onRemoveItem={this.handleRemoveItem}
                onAddItem={this.handleAddItem}
              />
            </AdvancedSectionContent>
          </AdvancedSection>
        </TabView>
      );
    });
  shouldShowAdvancedOptions() {
    const {
      data,
      data: { container }
    } = this.props;
    const { docker } = container || {};

    return (
      !isEmpty(data.disk) ||
      !isEmpty(data.gpus) ||
      !isEmpty(data.constraints) ||
      !isEmpty(findNestedPropertyInObject(docker, "forcePullImage")) ||
      !isEmpty(findNestedPropertyInObject(docker, "image")) ||
      !isEmpty(findNestedPropertyInObject(docker, "privileged"))
    );
  }
Exemple #4
0
  render() {
    if (this.state.isLoading) {
      return <Loader />;
    }

    const { directory, params, routes, selectedLogFile, task } = this.props;
    const config = ConfigStore.get("config");
    const loggingStrategy = findNestedPropertyInObject(
      config,
      "uiConfiguration.plugins.mesos.logging-strategy"
    );

    if (loggingStrategy === SYSTEM_LOGS) {
      return <TaskSystemLogsContainer task={task} />;
    }

    return (
      <TaskFileViewer
        directory={directory}
        limitLogFiles={["stdout", "stderr"]}
        params={params}
        routes={routes}
        selectedLogFile={selectedLogFile}
        task={task}
      />
    );
  }
  /**
   * @override
   */
  shouldExcludeItem() {
    const { appConfig } = this.props;

    return !Util.findNestedPropertyInObject(
      appConfig,
      "container.volumes.length"
    );
  }
  render() {
    const { data, errors, path } = this.props;
    const artifactsPath = this.getFieldPath(path, "artifacts");
    const artifacts = findNestedPropertyInObject(data, artifactsPath) || [];
    const artifactErrors =
      findNestedPropertyInObject(errors, artifactsPath) || [];
    const diskPath = this.getFieldPath(path, "disk");
    const diskErrors = findNestedPropertyInObject(errors, diskPath);

    return (
      <div>
        <Trans render="h2" className="short-bottom">
          Advanced Settings
        </Trans>
        <Trans render="p">
          Advanced settings related to the runtime you have selected above.
        </Trans>
        {this.getContainerSettings()}
        <FormRow>
          {this.getGPUSField()}
          <FormGroup className="column-4" showError={Boolean(diskErrors)}>
            <FieldLabel className="text-no-transform">
              <FormGroupHeadingContent primary={true}>
                <Trans render="span">Disk (MiB)</Trans>
              </FormGroupHeadingContent>
            </FieldLabel>
            <FieldInput
              min="0"
              name={diskPath}
              step="any"
              type="number"
              value={findNestedPropertyInObject(data, diskPath)}
            />
            <FieldError>{diskErrors}</FieldError>
          </FormGroup>
        </FormRow>
        <ArtifactsSection
          data={artifacts}
          path={artifactsPath}
          errors={artifactErrors}
          onRemoveItem={this.props.onRemoveItem}
          onAddItem={this.props.onAddItem}
        />
      </div>
    );
  }
Exemple #7
0
    return TableUtil.getSortFunction(tieBreakerProp, function(item, prop) {
      const hasGetter = typeof item.get === "function";

      if (prop === "updated") {
        return getUpdatedTimestamp(item) || 0;
      }

      if (prop === "zone") {
        return TaskUtil.getZoneName(item);
      }

      if (prop === "host") {
        return TaskUtil.getHostName(item);
      }

      if (prop === "region") {
        return TaskUtil.getRegionName(item);
      }

      if (prop === "status" && !hasGetter) {
        return TaskStatusSortingOrder[item.state];
      }

      if (
        prop === "cpus" ||
        prop === "gpus" ||
        prop === "mem" ||
        prop === "disk"
      ) {
        // This is necessary for tasks, since they are not structs
        let value = item[prop];

        if (!value && hasGetter) {
          value = item.get(prop);
        }

        if (item.getUsageStats) {
          value = item.getUsageStats(prop).value;
        }

        if (Util.findNestedPropertyInObject(item, `resources.${prop}`)) {
          value = item.resources[prop];
        }

        if (Array.isArray(value)) {
          return Util.last(value).value;
        }

        return value;
      }

      // This is necessary for tasks, since they are not structs
      if (!hasGetter) {
        return item[prop];
      }

      return item.get(prop);
    });
Exemple #8
0
    function(state) {
      let value = findNestedPropertyInObject(state, "container.type");

      if (value == null) {
        value = MESOS;
      }

      return new Transaction(["container", "type"], value);
    },
Exemple #9
0
  instances.forEach(function({
    agentId: host,
    id: taskID,
    localVolumes,
    status: statusCode
  }) {
    let status = VolumeStatus.DETACHED;
    if (statusCode === "STABLE") {
      status = VolumeStatus.ATTACHED;
    }

    if (!Array.isArray(localVolumes)) {
      return;
    }

    const containers = findNestedPropertyInObject(pod, "spec.containers");

    const mounts = containers
      .filter(({ volumeMounts = [] }) => volumeMounts.length > 0)
      .reduce(function(memo, { name: containerName, volumeMounts = [] }) {
        volumeMounts.forEach(function({ name, mountPath }) {
          if (memo[name] == null) {
            memo[name] = [];
          }

          memo[name] = [
            ...memo[name],
            {
              containerName,
              mountPath
            }
          ];
        });

        return memo;
      }, {});

    volumeData.push(
      ...localVolumes.map(function({ containerPath, persistenceId: id }) {
        const volumeDefinition = volumeDefinitionMap.get(containerPath);

        return Object.assign({}, volumeDefinition, {
          status,
          host,
          containerPath,
          id,
          mounts: mounts[containerPath],
          taskID
        });
      })
    );
  });
      (settingName, index) => {
        const {
          runtimes,
          helpText,
          label,
          unavailableText
        } = containerSettings[settingName];
        const settingsPath = this.getFieldPath(path, settingName);
        const checked = findNestedPropertyInObject(data, settingsPath);
        const isDisabled = !runtimes.includes(containerType);
        const labelNodeClasses = classNames({
          "disabled muted": isDisabled,
          "flush-bottom": index === sectionCount - 1
        });

        let labelNode = (
          <FieldLabel key={`label.${index}`} className={labelNodeClasses}>
            <FieldInput
              checked={!isDisabled && Boolean(checked)}
              name={settingsPath}
              type="checkbox"
              disabled={isDisabled}
              value={settingName}
            />
            <Trans render="span" id={label} />
            <FieldHelp>
              <Trans render="span" id={helpText} />
            </FieldHelp>
          </FieldLabel>
        );

        if (isDisabled) {
          labelNode = (
            <Tooltip
              content={<Trans render="span" id={unavailableText} />}
              elementTag="label"
              key={`tooltip.${index}`}
              position="top"
              width={300}
              wrapperClassName="tooltip-wrapper tooltip-block-wrapper"
              wrapText={true}
            >
              {labelNode}
            </Tooltip>
          );
        }

        return labelNode;
      }
  getRuntimeSection() {
    const { errors, data } = this.props;

    const typeErrors = findNestedPropertyInObject(errors, "container.type");
    const runtimeTooltipContent = (
      <Trans render="span">
        You can run Docker containers with both container runtimes. The{" "}
        Universal Container Runtime (UCR) is better supported in DC/OS.{" "}
        <a
          href={MetadataStore.buildDocsURI(
            "/deploying-services/containerizers/"
          )}
          target="_blank"
        >
          More information
        </a>.
      </Trans>
    );

    return (
      <div>
        <h2 className="short-bottom">
          <FormGroupHeading>
            <FormGroupHeadingContent primary={true}>
              <Trans render="span">Container Runtime</Trans>
            </FormGroupHeadingContent>
            <FormGroupHeadingContent>
              <Tooltip
                content={runtimeTooltipContent}
                interactive={true}
                maxWidth={300}
                wrapText={true}
              >
                <InfoTooltipIcon />
              </Tooltip>
            </FormGroupHeadingContent>
          </FormGroupHeading>
        </h2>
        <Trans render="p">
          The container runtime is responsible for running your service. We
          support the Docker Engine and Universal Container Runtime (UCR).
        </Trans>
        <FormGroup showError={Boolean(typeErrors)}>
          {this.getRuntimeSelections(data)}
          <FieldError>{typeErrors}</FieldError>
        </FormGroup>
      </div>
    );
  }
  /**
   * @override
   */
  getDefinition() {
    const { onEditClick } = this.props;

    return {
      tabViewID: "services",
      values: [
        {
          heading: "General",
          headingLevel: 1
        },
        {
          key: "id",
          label: "Service ID"
        },
        {
          key: "instances",
          label: "Instances"
        },
        {
          key: "container.type",
          label: "Container Runtime",
          transformValue(runtime) {
            return labelMap[runtime] || labelMap[MESOS];
          }
        },
        {
          key: "cpus",
          label: "CPU"
        },
        {
          key: "mem",
          label: "Memory",
          transformValue(value) {
            if (value == null) {
              return value;
            }

            return formatResource("mem", value);
          }
        },
        {
          key: "disk",
          label: "Disk",
          transformValue(value) {
            if (value == null) {
              return value;
            }

            return formatResource("disk", value);
          }
        },
        {
          key: "gpus",
          label: "GPU"
        },
        {
          key: "backoffSeconds",
          label: "Backoff Seconds"
        },
        {
          key: "backoffFactor",
          label: "Backoff Factor"
        },
        {
          key: "maxLaunchDelaySeconds",
          label: "Backoff Max Launch Delay"
        },
        {
          key: "minHealthOpacity",
          label: "Upgrade Min Health Capacity"
        },
        {
          key: "maxOverCapacity",
          label: "Upgrade Max Overcapacity"
        },
        {
          key: "container.docker.image",
          label: "Container Image",
          transformValue(value, appConfig) {
            const runtime = findNestedPropertyInObject(
              appConfig,
              "container.type"
            );

            // Disabled for MESOS
            return getDisplayValue(value, runtime == null || runtime === MESOS);
          }
        },
        {
          key: "container.docker.privileged",
          label: "Extended Runtime Priv.",
          transformValue(value, appConfig) {
            const runtime = findNestedPropertyInObject(
              appConfig,
              "container.type"
            );
            // Disabled for DOCKER
            if (runtime !== DOCKER && value == null) {
              return getDisplayValue(null, true);
            }

            // Cast boolean as a string.
            return String(Boolean(value));
          }
        },
        {
          key: "container.docker.forcePullImage",
          label: "Force Pull on Launch",
          transformValue(value, appConfig) {
            const runtime = findNestedPropertyInObject(
              appConfig,
              "container.type"
            );
            // Disabled for DOCKER
            if (runtime !== DOCKER && value == null) {
              return getDisplayValue(null, true);
            }

            // Cast boolean as a string.
            return String(Boolean(value));
          }
        },
        {
          key: "cmd",
          label: "Command",
          type: "pre"
        },
        {
          key: "acceptedResourceRoles",
          label: "Resource Roles",
          transformValue(value = []) {
            return value.join(", ");
          }
        },
        {
          key: "dependencies",
          label: "Dependencies",
          transformValue(value = []) {
            return value.join(", ");
          }
        },
        {
          key: "executor",
          label: "Executor"
        },
        {
          key: "user",
          label: "User"
        },
        {
          key: "args",
          label: "Args",
          transformValue(value = []) {
            if (!value.length) {
              return getDisplayValue(null);
            }

            const args = value.map((arg, index) => (
              <pre key={index} className="flush transparent wrap">{arg}</pre>
            ));

            return <div>{args}</div>;
          }
        },
        {
          key: "version",
          label: "Version"
        },
        {
          key: "fetch",
          heading: "Container Artifacts",
          headingLevel: 3
        },
        {
          key: "fetch",
          render(data) {
            const columns = [
              {
                heading: getColumnHeadingFn("Artifact Uri"),
                prop: "uri",
                render: (prop, row) => {
                  const value = row[prop];

                  return getDisplayValue(value);
                },
                className: getColumnClassNameFn(
                  "configuration-map-table-label"
                ),
                sortable: true
              }
            ];

            if (onEditClick) {
              columns.push({
                heading() {
                  return null;
                },
                className: "configuration-map-action",
                prop: "edit",
                render() {
                  return (
                    <ConfigurationMapEditAction
                      onEditClick={onEditClick}
                      tabViewID="services"
                    />
                  );
                }
              });
            }

            return (
              <Table
                key="artifacts-table"
                className="table table-simple table-align-top table-break-word table-fixed-layout flush-bottom"
                columns={columns}
                data={data}
              />
            );
          }
        }
      ]
    };
  }
  /**
   * @override
   */
  shouldExcludeItem(row) {
    const { appConfig } = this.props;

    switch (row.key) {
      case "fetch":
        return !findNestedPropertyInObject(appConfig, "fetch.length");
      case "gpus":
        return !findNestedPropertyInObject(appConfig, "gpus");
      case "backoffSeconds":
        return !findNestedPropertyInObject(appConfig, "backoffSeconds");
      case "backoffFactor":
        return !findNestedPropertyInObject(appConfig, "backoffFactor");
      case "maxLaunchDelaySeconds":
        return !findNestedPropertyInObject(appConfig, "maxLaunchDelaySeconds");
      case "minHealthOpacity":
        return !findNestedPropertyInObject(appConfig, "minHealthOpacity");
      case "maxOverCapacity":
        return !findNestedPropertyInObject(appConfig, "maxOverCapacity");
      case "acceptedResourceRoles":
        return !findNestedPropertyInObject(
          appConfig,
          "acceptedResourceRoles.length"
        );
      case "dependencies":
        return !findNestedPropertyInObject(appConfig, "dependencies.length");
      case "executor":
        return !findNestedPropertyInObject(appConfig, "executor");
      case "user":
        return !findNestedPropertyInObject(appConfig, "user");
      case "args":
        return !findNestedPropertyInObject(appConfig, "args.length");
      case "version":
        return !findNestedPropertyInObject(appConfig, "version");
      default:
        return false;
    }
  }
  getFormNavigationItems(appConfig, data) {
    // L10NTODO: Pluralize
    const serviceLabel =
      (findNestedPropertyInObject(appConfig, "containers.length") || 1) === 1
        ? "Service"
        : "Services";

    let tabList = [
      {
        id: "services",
        label: serviceLabel,
        children: this.getContainerList(data)
      }
    ];

    if (this.state.isPod) {
      tabList.push(
        { id: "placement", key: "placement", label: i18nMark("Placement") },
        {
          id: "networking",
          key: "multinetworking",
          label: i18nMark("Networking")
        },
        { id: "volumes", key: "multivolumes", label: i18nMark("Volumes") },
        {
          id: "healthChecks",
          key: "multihealthChecks",
          label: i18nMark("Health Checks")
        },
        {
          id: "environment",
          key: "multienvironment",
          label: i18nMark("Environment")
        }
      );
      tabList = Hooks.applyFilter(
        "createServiceMultiContainerTabList",
        tabList
      );
    } else {
      tabList.push(
        { id: "placement", key: "placement", label: i18nMark("Placement") },
        { id: "networking", key: "networking", label: i18nMark("Networking") },
        { id: "volumes", key: "volumes", label: i18nMark("Volumes") },
        {
          id: "healthChecks",
          key: "healthChecks",
          label: i18nMark("Health Checks")
        },
        {
          id: "environment",
          key: "environment",
          label: i18nMark("Environment")
        }
      );
      tabList = Hooks.applyFilter(
        "createServiceMultiContainerTabList",
        tabList
      );
    }

    return tabList;
  }
Exemple #15
0
      // Let's not block the application loading in case it takes a really
      // long time to ready-up analytics or the integrations.
      global.setTimeout(resolve, ANALYTICS_LOAD_TIMEOUT);
    });

    promiseArray.push(promise);

    return promiseArray;
  },

  pluginsConfigured() {
    // Ensure analytics is actually ready, because in #pluginsLoadedCheck we
    // may skip the check so that we don't completely block the applicaiton
    const metadata =
      Util.findNestedPropertyInObject(this, "configuration.metadata") || {};

    global.analytics.ready(() => {
      const setContext = () => {
        if (!global.Raven) {
          return;
        }

        global.Raven.setTagsContext({
          ...metadata,
          environment: process.env.NODE_ENV,
          dcosVersion: MetadataStore.version,
          dcosVariant: MetadataStore.variant
        });
      };
Exemple #16
0
        hosts: [hostName]
      };
    }

    return { ports, hosts: this.getIPAddresses(task) };
  },

  /**
   * Returns a list of ports, if ports is available in discovery it will return
   * those, otherwise it will fall back on ports property on the task
   * @param  {object} task to return ports from
   * @return {Array.<number>} an array of port numbers
   */
  getPorts(task = {}) {
    const ports = Util.findNestedPropertyInObject(
      task,
      "discovery.ports.ports"
    );

    // If there are no service ports, use task ports
    if (!ports || !ports.length) {
      return task.ports || [];
    }

    return ports.map(function(port) {
      return port.number;
    });
  },

  getTaskStatusSlug(task) {
    return task.state.substring("TASK_".length).toLowerCase();
  },
Exemple #17
0
import { findNestedPropertyInObject } from "#SRC/js/utils/Util";
import Transaction from "#SRC/js/structs/Transaction";
import Networking from "#SRC/js/constants/Networking";

const { USER } = Networking.type;

module.exports = {
  JSONReducer: null,

  JSONParser(state) {
    const transactions = [];
    let networkType = findNestedPropertyInObject(
      state,
      "container.docker.network"
    );
    const networkName = findNestedPropertyInObject(
      state,
      "ipAddress.networkName"
    );

    if (networkType == null && networkName == null) {
      return transactions;
    }

    if (networkName != null) {
      networkType = USER;
    }

    if (networkName != null && networkType != null) {
      transactions.push(
        new Transaction(
const PodContainerConfigSection = ({
  containerConfig,
  appConfig,
  onEditClick,
  index
}) => {
  const fields = {
    command: getCommand(containerConfig),
    resources: containerConfig.resources || {},
    user: containerConfig.user || appConfig.user
  };

  let tabViewID = "services";
  if (index != null) {
    tabViewID = `container${index}`;
  }

  let action;
  if (onEditClick) {
    action = (
      <a
        className="button button-link flush table-display-on-row-hover"
        onClick={onEditClick.bind(null, { tabViewID })}
      >
        Edit
      </a>
    );
  }

  return (
    <ConfigurationMapSection key="pod-general-section">
      <MountService.Mount
        type="CreateService:ServiceConfigDisplay:Pod:Container:General"
        containerConfig={containerConfig}
        onEditClick={onEditClick}
      >
        {/* Heading with Icon */}
        <ConfigurationMapHeading level={3}>
          {getContainerNameWithIcon(containerConfig)}
        </ConfigurationMapHeading>

        {/* Container image goes to top */}
        <ConfigurationMapRow>
          <Trans render={<ConfigurationMapLabel />}>Container Image</Trans>
          <ConfigurationMapValueWithDefault
            value={findNestedPropertyInObject(containerConfig, "image.id")}
          />
          {action}
        </ConfigurationMapRow>
        <ConfigurationMapRow>
          <Trans render={<ConfigurationMapLabel />}>Force pull on launch</Trans>
          <ConfigurationMapBooleanValue
            value={findNestedPropertyInObject(
              containerConfig,
              "image.forcePull"
            )}
          />
          {action}
        </ConfigurationMapRow>

        {/* Resources */}
        {Boolean(fields.resources.cpus) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>CPUs</Trans>
            <ConfigurationMapValue value={fields.resources.cpus} />
            {action}
          </ConfigurationMapRow>
        )}
        {Boolean(fields.resources.mem) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>Memory</Trans>
            <ConfigurationMapSizeValue value={fields.resources.mem} />
            {action}
          </ConfigurationMapRow>
        )}
        {Boolean(fields.resources.disk) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>Disk</Trans>
            <ConfigurationMapSizeValue value={fields.resources.disk} />
            {action}
          </ConfigurationMapRow>
        )}
        {Boolean(fields.resources.gpus) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>GPUs</Trans>
            <ConfigurationMapValue value={fields.resources.gpus} />
            {action}
          </ConfigurationMapRow>
        )}

        {/* Global Properties */}
        {Boolean(fields.user) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>Run as User</Trans>
            <ConfigurationMapValue value={fields.user} />
            {action}
          </ConfigurationMapRow>
        )}
        {Boolean(fields.command) && (
          <ConfigurationMapRow>
            <Trans render={<ConfigurationMapLabel />}>Command</Trans>
            <ConfigurationMapMultilineValue value={fields.command} />
            {action}
          </ConfigurationMapRow>
        )}

        {/* Container artifacts */}
        <PodContainerArtifactsConfigSection
          artifacts={containerConfig.artifacts}
          onEditClick={onEditClick}
          index={index}
        />
      </MountService.Mount>
    </ConfigurationMapSection>
  );
};
  isGpusDisabled() {
    const { data, path } = this.props;
    const typePath = this.getFieldPath(path, "type");

    return findNestedPropertyInObject(data, typePath) === DOCKER;
  }
   * @param {Object} app - The data to validate
   * @returns {Array} Returns an array with validation errors
   */
  complyWithIpAddressRules(app) {
    // (AppDefinition.scala#L697)
    if (ValidatorUtil.isEmpty(app.ipAddress)) {
      return [];
    }

    // (AppDefinition.scala#L538)
    if (ValidatorUtil.isEmpty(app.discoveryInfo)) {
      return [];
    }

    // (AppDefinition.scala#L539)
    const network = findNestedPropertyInObject(app, "container.docker.network");
    if (ValidatorUtil.isEmpty(network)) {
      return [];
    }

    // (AppDefinition.scala#L539)
    if (/^(BRIDGE|USER)$/.exec(app.container.docker.network)) {
      const message =
        "ipAddress/discovery is not allowed for Docker " +
        "containers using BRIDGE or USER networks";
      const type = PROP_CONFLICT;
      const variables = {
        feature1: "ipAddress or discoveryInfo",
        feature2: "container.docker.network"
      };
  getContainerSettings() {
    const { data, errors, path, service } = this.props;
    if (service instanceof PodSpec) {
      return null;
    }

    const typePath = this.getFieldPath(path, "type");
    const containerType = findNestedPropertyInObject(data, typePath);
    const typeErrors = findNestedPropertyInObject(errors, typePath);
    const sectionCount = Object.keys(containerSettings).length;
    const selections = Object.keys(containerSettings).map(
      (settingName, index) => {
        const {
          runtimes,
          helpText,
          label,
          unavailableText
        } = containerSettings[settingName];
        const settingsPath = this.getFieldPath(path, settingName);
        const checked = findNestedPropertyInObject(data, settingsPath);
        const isDisabled = !runtimes.includes(containerType);
        const labelNodeClasses = classNames({
          "disabled muted": isDisabled,
          "flush-bottom": index === sectionCount - 1
        });

        let labelNode = (
          <FieldLabel key={`label.${index}`} className={labelNodeClasses}>
            <FieldInput
              checked={!isDisabled && Boolean(checked)}
              name={settingsPath}
              type="checkbox"
              disabled={isDisabled}
              value={settingName}
            />
            <Trans render="span" id={label} />
            <FieldHelp>
              <Trans render="span" id={helpText} />
            </FieldHelp>
          </FieldLabel>
        );

        if (isDisabled) {
          labelNode = (
            <Tooltip
              content={<Trans render="span" id={unavailableText} />}
              elementTag="label"
              key={`tooltip.${index}`}
              position="top"
              width={300}
              wrapperClassName="tooltip-wrapper tooltip-block-wrapper"
              wrapText={true}
            >
              {labelNode}
            </Tooltip>
          );
        }

        return labelNode;
      }
    );

    return (
      <FormGroup showError={Boolean(typeErrors)}>
        {selections}
        <FieldError>{typeErrors}</FieldError>
      </FormGroup>
    );
  }
  render() {
    const { data, errors, i18n } = this.props;
    const title = pluralize(
      "Service",
      findNestedPropertyInObject(data, "containers.length") || 1
    );

    const idTooltipContent = (
      <Trans render="span">
        Include the path to your service, if applicable. E.g.{" "}
        /dev/tools/my-service{" "}
        <a
          href={MetadataStore.buildDocsURI(
            "/deploying-services/creating-services/"
          )}
          target="_blank"
        >
          More information
        </a>.
      </Trans>
    );

    const isEditPage = /\/edit\//g.test(global.location.hash);

    return (
      <div>
        <h1 className="flush-top short-bottom">{title}</h1>
        <Trans render="p">
          Configure your service below. Start by giving your service an ID.
        </Trans>

        <FormRow>
          <FormGroup className="column-9" showError={Boolean(errors.id)}>
            <FieldLabel>
              <FormGroupHeading required={true}>
                <FormGroupHeadingContent primary={true}>
                  <Trans render="span">Service ID</Trans>
                </FormGroupHeadingContent>
                <FormGroupHeadingContent>
                  <Tooltip
                    content={idTooltipContent}
                    interactive={true}
                    maxWidth={300}
                    wrapText={true}
                  >
                    <InfoTooltipIcon />
                  </Tooltip>
                </FormGroupHeadingContent>
              </FormGroupHeading>
            </FieldLabel>
            <FieldAutofocus>
              <FieldInput
                name="id"
                type="text"
                value={data.id}
                disabled={isEditPage}
                onFocus={this.moveCaretAtEnd}
              />
            </FieldAutofocus>
            <FieldHelp>
              <Trans render="span">
                Give your service a unique name within the cluster, e.g.{" "}
                my-service.
              </Trans>
            </FieldHelp>
            <FieldError>{errors.id}</FieldError>
          </FormGroup>

          <FormGroup className="column-3" showError={Boolean(errors.instances)}>
            <FieldLabel>
              <FormGroupHeading>
                <FormGroupHeadingContent primary={true}>
                  <Trans render="span">Instances</Trans>
                </FormGroupHeadingContent>
              </FormGroupHeading>
            </FieldLabel>
            <FieldInput
              name="instances"
              min={0}
              type="number"
              value={data.instances}
            />
            <FieldError>{errors.instances}</FieldError>
          </FormGroup>
        </FormRow>

        {this.getContainerSection()}
        {this.getAdvancedSettingsSection()}
        {this.getMultiContainerSection()}
        {this.getConvertToPodAction()}

        <Confirm
          closeByBackdropClick={true}
          header={
            <ModalHeading>
              <Trans render="span">Switching to a pod service</Trans>
            </ModalHeading>
          }
          open={this.state.convertToPodModalOpen}
          onClose={this.handleCloseConvertToPodModal}
          leftButtonText={i18n._(t`Cancel`)}
          leftButtonClassName="button button-primary-link"
          leftButtonCallback={this.handleCloseConvertToPodModal}
          rightButtonText={i18n._(t`Switch to Pod`)}
          rightButtonClassName="button button-primary"
          rightButtonCallback={this.handleConvertToPod}
          showHeader={true}
        >
          <Trans render="p">
            Adding another container will automatically put multiple containers
            into a Pod definition. Your containers will be co-located on the
            same node and scale together.{" "}
            <a
              href={MetadataStore.buildDocsURI("/deploying-services/pods/")}
              target="_blank"
            >
              More information
            </a>.
          </Trans>
          <Trans render="p">
            Are you sure you would like to continue and create a Pod? Any data
            you have already entered will be lost.
          </Trans>
        </Confirm>
      </div>
    );
  }
Exemple #23
0
    return state.portDefinitions.reduce(function(memo, item, index) {
      memo.push(new Transaction(["portDefinitions"], index, ADD_ITEM));

      if (item.name != null) {
        memo.push(
          new Transaction(["portDefinitions", index, "name"], item.name, SET)
        );
      }

      const port = Number(item.port);
      // If port is a number but not zero, we set automaticPort to false
      // so we can set the port
      if (!isNaN(port) && port !== 0) {
        memo.push(
          new Transaction(
            ["portDefinitions", index, "automaticPort"],
            false,
            SET
          )
        );

        memo.push(
          new Transaction(["portDefinitions", index, "hostPort"], port, SET)
        );
      }

      // If port is zero, we set automaticPort to true
      if (!isNaN(port) && port === 0) {
        memo.push(
          new Transaction(
            ["portDefinitions", index, "automaticPort"],
            true,
            SET
          )
        );
      }

      if (item.protocol != null) {
        const protocols = item.protocol.split(",");
        PROTOCOLS.forEach(protocol => {
          memo.push(
            new Transaction(
              ["portDefinitions", index, "protocol", protocol],
              protocols.includes(protocol),
              SET
            )
          );
        });
      }

      const vip = findNestedPropertyInObject(item, `labels.VIP_${index}`);
      if (vip != null) {
        memo.push(
          new Transaction(["portDefinitions", index, "loadBalanced"], true, SET)
        );

        if (!vip.startsWith(`${state.id}:`)) {
          memo.push(
            new Transaction(["portDefinitions", index, "vip"], vip, SET)
          );
        }
      }

      if (item.labels != null) {
        memo.push(
          new Transaction(
            ["portDefinitions", index, "labels"],
            item.labels,
            SET
          )
        );
      }

      return memo;
    }, []);
Exemple #24
0
            path: ["constraints", index, "value"],
            message: NBSP,
            isPermissive: true
          }
        ]
      );
    }
    visitedOperatorFieldPairs.push(key);
  });

  return errors;
}

const PlacementsValidators = {
  mustHaveUniqueOperatorField(app) {
    let constraints = findNestedPropertyInObject(app, "constraints");

    if (ValidatorUtil.isEmpty(constraints)) {
      constraints = findNestedPropertyInObject(
        app,
        "scheduling.placement.constraints"
      );
    }

    return checkDuplicateOperatorField(constraints);
  },
  validateConstraints(constraints) {
    if (constraints != null && !Array.isArray(constraints)) {
      return [
        {
          path: [],