<commit_before>import _ from 'intl'
import Component from 'base-component'
import Copiable from 'copiable'
import decorate from 'apply-decorators'
import Icon from 'icon'
import PropTypes from 'prop-types'
import React from 'react'
import SelectFiles from 'select-files'
import StateButton from 'state-button'
import TabButton from 'tab-button'
import Tooltip from 'tooltip'
import Upgrade from 'xoa-upgrade'
import { compareVersions, connectStore, getIscsiPaths } from 'utils'
import { confirm } from 'modal'
import { Container, Row, Col } from 'grid'
import { createGetObjectsOfType, createSelector } from 'selectors'
import { forEach, isEmpty, map, noop } from 'lodash'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { Sr } from 'render-xo-item'
import { Text } from 'editable'
import { Toggle } from 'form'
import {
  detachHost,
  disableHost,
  editHost,
  enableAdvancedLiveTelemetry,
  enableHost,
  forgetHost,
  installSupplementalPack,
  isHyperThreadingEnabledHost,
  isNetDataInstalledOnHost,
  getPlugin,
  restartHost,
  setHostsMultipathing,
  setRemoteSyslogHost,
} from 'xo'

const ALLOW_INSTALL_SUPP_PACK = process.env.XOA_PLAN > 1

const forceReboot = host => restartHost(host, true)

const formatPack = ({ name, author, description, version }, key) => (
  <tr key={key}>
    <th>{_('supplementalPackTitle', { author, name })}</th>
    <td>{description}</td>
    <td>{version}</td>
  </tr>
)

const getPackId = ({ author, name }) => `${author}\0${name}`

const MultipathableSrs = decorate([
  connectStore({
    pbds: createGetObjectsOfType('PBD').filter((_, { hostId }) => pbd =>
      pbd.host === hostId && Boolean(pbd.otherConfig.multipathed)
    ),
  }),
  ({ pbds }) =>
    isEmpty(pbds) ? (
      <div>{_('hostNoIscsiSr')}</div>
    ) : (
      <Container>
        {map(pbds, pbd => {
          const [nActives, nPaths] = getIscsiPaths(pbd)
          const nSessions = pbd.otherConfig.iscsi_sessions
          return (
            <Row key={pbd.id}>
              <Col>
                <Sr id={pbd.SR} link newTab container={false} />{' '}
                {nActives !== undefined &&
                  nPaths !== undefined &&
                  _('hostMultipathingPaths', {
                    nActives,
                    nPaths,
                  })}{' '}
                {nSessions !== undefined && _('iscsiSessions', { nSessions })}
              </Col>
            </Row>
          )
        })}
      </Container>
    ),
])

MultipathableSrs.propTypes = {
  hostId: PropTypes.string.isRequired,
}

@connectStore(() => {
  const getPgpus = createGetObjectsOfType('PGPU')
    .pick((_, { host }) => host.$PGPUs)
    .sort()

  const getPcis = createGetObjectsOfType('PCI').pick(
    createSelector(getPgpus, pgpus => map(pgpus, 'pci'))
  )

  return {
    pcis: getPcis,
    pgpus: getPgpus,
  }
})
export default class extends Component {
  async componentDidMount() {
    const plugin = await getPlugin('netdata')
    const isNetDataPluginCorrectlySet = plugin !== undefined && plugin.loaded
    this.setState({ isNetDataPluginCorrectlySet })
    if (isNetDataPluginCorrectlySet) {
      this.setState({
        isNetDataPluginInstalledOnHost: await isNetDataInstalledOnHost(
          this.props.host
        ),
      })
    }

    this.setState({
      isHtEnabled: await isHyperThreadingEnabledHost(this.props.host),
    })
  }

  _getPacks = createSelector(
    () => this.props.host.supplementalPacks,
    packs => {
      const uniqPacks = {}
      let packId, previousPack
      forEach(packs, pack => {
        packId = getPackId(pack)
        if (
          (previousPack = uniqPacks[packId]) === undefined ||
          compareVersions(pack.version, previousPack.version) > 0
        ) {
          uniqPacks[packId] = pack
        }
      })
      return uniqPacks
    }
  )

  _setHostIscsiIqn = iscsiIqn =>
    confirm({
      icon: 'alarm',
      title: _('editHostIscsiIqnTitle'),
      body: (
        <div>
          <p>{_('editHostIscsiIqnMessage')}</p>
          <p className='text-muted'>
            <Icon icon='info' /> {_('uniqueHostIscsiIqnInfo')}
          </p>
        </div>
      ),
    }).then(() => editHost(this.props.host, { iscsiIqn }), noop)

  _setRemoteSyslogHost = value => setRemoteSyslogHost(this.props.host, value)

  _accessAdvancedLiveTelemetry = () =>
    window.open(`/netdata/host/${this.props.host.hostname}`)

  _enableAdvancedLiveTelemetry = async host => {
    await enableAdvancedLiveTelemetry(host)
    this.setState({
      isNetDataPluginInstalledOnHost: await isNetDataInstalledOnHost(host),
    })
  }

  render() {
    const { host, pcis, pgpus } = this.props
    const {
      isHtEnabled,
      isNetDataPluginInstalledOnHost,
      isNetDataPluginCorrectlySet,
    } = this.state

    const _isXcpNgHost = host.productBrand === 'XCP-ng'

    const telemetryButton = isNetDataPluginInstalledOnHost ? (
      <TabButton
        btnStyle='success'
        handler={this._accessAdvancedLiveTelemetry}
        handlerParam={host}
        icon='telemetry'
        labelId='advancedLiveTelemetry'
      />
    ) : (
      <TabButton
        btnStyle='success'
        disabled={!_isXcpNgHost || !isNetDataPluginCorrectlySet}
        handler={this._enableAdvancedLiveTelemetry}<commit_msg>fix(xo-web/host/advanced): add trailing slash to telemetry URL<commit_after>import _ from 'intl'
import Component from 'base-component'
import Copiable from 'copiable'
import decorate from 'apply-decorators'
import Icon from 'icon'
import PropTypes from 'prop-types'
import React from 'react'
import SelectFiles from 'select-files'
import StateButton from 'state-button'
import TabButton from 'tab-button'
import Tooltip from 'tooltip'
import Upgrade from 'xoa-upgrade'
import { compareVersions, connectStore, getIscsiPaths } from 'utils'
import { confirm } from 'modal'
import { Container, Row, Col } from 'grid'
import { createGetObjectsOfType, createSelector } from 'selectors'
import { forEach, isEmpty, map, noop } from 'lodash'
import { FormattedRelative, FormattedTime } from 'react-intl'
import { Sr } from 'render-xo-item'
import { Text } from 'editable'
import { Toggle } from 'form'
import {
  detachHost,
  disableHost,
  editHost,
  enableAdvancedLiveTelemetry,
  enableHost,
  forgetHost,
  installSupplementalPack,
  isHyperThreadingEnabledHost,
  isNetDataInstalledOnHost,
  getPlugin,
  restartHost,
  setHostsMultipathing,
  setRemoteSyslogHost,
} from 'xo'

const ALLOW_INSTALL_SUPP_PACK = process.env.XOA_PLAN > 1

const forceReboot = host => restartHost(host, true)

const formatPack = ({ name, author, description, version }, key) => (
  <tr key={key}>
    <th>{_('supplementalPackTitle', { author, name })}</th>
    <td>{description}</td>
    <td>{version}</td>
  </tr>
)

const getPackId = ({ author, name }) => `${author}\0${name}`

const MultipathableSrs = decorate([
  connectStore({
    pbds: createGetObjectsOfType('PBD').filter((_, { hostId }) => pbd =>
      pbd.host === hostId && Boolean(pbd.otherConfig.multipathed)
    ),
  }),
  ({ pbds }) =>
    isEmpty(pbds) ? (
      <div>{_('hostNoIscsiSr')}</div>
    ) : (
      <Container>
        {map(pbds, pbd => {
          const [nActives, nPaths] = getIscsiPaths(pbd)
          const nSessions = pbd.otherConfig.iscsi_sessions
          return (
            <Row key={pbd.id}>
              <Col>
                <Sr id={pbd.SR} link newTab container={false} />{' '}
                {nActives !== undefined &&
                  nPaths !== undefined &&
                  _('hostMultipathingPaths', {
                    nActives,
                    nPaths,
                  })}{' '}
                {nSessions !== undefined && _('iscsiSessions', { nSessions })}
              </Col>
            </Row>
          )
        })}
      </Container>
    ),
])

MultipathableSrs.propTypes = {
  hostId: PropTypes.string.isRequired,
}

@connectStore(() => {
  const getPgpus = createGetObjectsOfType('PGPU')
    .pick((_, { host }) => host.$PGPUs)
    .sort()

  const getPcis = createGetObjectsOfType('PCI').pick(
    createSelector(getPgpus, pgpus => map(pgpus, 'pci'))
  )

  return {
    pcis: getPcis,
    pgpus: getPgpus,
  }
})
export default class extends Component {
  async componentDidMount() {
    const plugin = await getPlugin('netdata')
    const isNetDataPluginCorrectlySet = plugin !== undefined && plugin.loaded
    this.setState({ isNetDataPluginCorrectlySet })
    if (isNetDataPluginCorrectlySet) {
      this.setState({
        isNetDataPluginInstalledOnHost: await isNetDataInstalledOnHost(
          this.props.host
        ),
      })
    }

    this.setState({
      isHtEnabled: await isHyperThreadingEnabledHost(this.props.host),
    })
  }

  _getPacks = createSelector(
    () => this.props.host.supplementalPacks,
    packs => {
      const uniqPacks = {}
      let packId, previousPack
      forEach(packs, pack => {
        packId = getPackId(pack)
        if (
          (previousPack = uniqPacks[packId]) === undefined ||
          compareVersions(pack.version, previousPack.version) > 0
        ) {
          uniqPacks[packId] = pack
        }
      })
      return uniqPacks
    }
  )

  _setHostIscsiIqn = iscsiIqn =>
    confirm({
      icon: 'alarm',
      title: _('editHostIscsiIqnTitle'),
      body: (
        <div>
          <p>{_('editHostIscsiIqnMessage')}</p>
          <p className='text-muted'>
            <Icon icon='info' /> {_('uniqueHostIscsiIqnInfo')}
          </p>
        </div>
      ),
    }).then(() => editHost(this.props.host, { iscsiIqn }), noop)

  _setRemoteSyslogHost = value => setRemoteSyslogHost(this.props.host, value)

  _accessAdvancedLiveTelemetry = () =>
    window.open(`/netdata/host/${this.props.host.hostname}/`)

  _enableAdvancedLiveTelemetry = async host => {
    await enableAdvancedLiveTelemetry(host)
    this.setState({
      isNetDataPluginInstalledOnHost: await isNetDataInstalledOnHost(host),
    })
  }

  render() {
    const { host, pcis, pgpus } = this.props
    const {
      isHtEnabled,
      isNetDataPluginInstalledOnHost,
      isNetDataPluginCorrectlySet,
    } = this.state

    const _isXcpNgHost = host.productBrand === 'XCP-ng'

    const telemetryButton = isNetDataPluginInstalledOnHost ? (
      <TabButton
        btnStyle='success'
        handler={this._accessAdvancedLiveTelemetry}
        handlerParam={host}
        icon='telemetry'
        labelId='advancedLiveTelemetry'
      />
    ) : (
      <TabButton
        btnStyle='success'
        disabled={!_isXcpNgHost || !isNetDataPluginCorrectlySet}
        handler={this._enableAdvancedLiveTelemetry}
{'fraction_non_alphanumeric': 0.12723340229452698, 'fraction_numerical': 0.0005642279480910288, 'mean_word_length': 2.826916156890968, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5555744', 'n_tokens_mistral': 3474, 'n_tokens_neox': 3386, 'n_words': 657}