Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion js/app_api-adminSettings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/app_api-adminSettings.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/Command/Daemon/AddRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(

protected function configure(): void {
$this->setName('app_api:daemon:registry:add');
$this->setDescription('Add Deploy daemon Docker registry mapping');
$this->setDescription('Add deploy daemon Docker registry mapping');
$this->addArgument('name', InputArgument::REQUIRED, 'Deploy daemon name');
$this->addOption('registry-from', null, InputOption::VALUE_REQUIRED, 'Deploy daemon registry from URL');
$this->addOption('registry-to', null, InputOption::VALUE_REQUIRED, 'Deploy daemon registry to URL');
Expand Down
2 changes: 1 addition & 1 deletion lib/Command/Daemon/ListRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct(

protected function configure(): void {
$this->setName('app_api:daemon:registry:list');
$this->setDescription('List configured Deploy daemon Docker registry mappings');
$this->setDescription('List the configured deploy daemon Docker registry mappings');
$this->addArgument('name', InputArgument::REQUIRED, 'Deploy daemon name');
}

Expand Down
20 changes: 10 additions & 10 deletions lib/Command/Daemon/RegisterDaemon.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ protected function configure(): void {
$this->addArgument('display-name', InputArgument::REQUIRED);
$this->addArgument('accepts-deploy-id', InputArgument::REQUIRED, 'The deployment method that the daemon accepts. Can be "manual-install" or "docker-install". "docker-install" is for Docker Socket Proxy and HaRP.');
$this->addArgument('protocol', InputArgument::REQUIRED, 'The protocol used to connect to the daemon. Can be "http" or "https".');
$this->addArgument('host', InputArgument::REQUIRED, 'The hostname (and port) or path at which the docker socket proxy or harp or the manual-install app is/would be available. This need not be a public host, just a host accessible by the Nextcloud server. It can also be a path to the docker socket. (e.g. appapi-harp:8780, /var/run/docker.sock)');
$this->addArgument('host', InputArgument::REQUIRED, 'The hostname (and port) or path at which the Docker socket proxy or HaRP or the manual-install app is/would be available. This does not need to be a public host, just a host accessible by the Nextcloud server. It can also be a path to the Docker socket. (e.g. appapi-harp:8780, /var/run/docker.sock)');
$this->addArgument('nextcloud_url', InputArgument::REQUIRED);

// daemon-config settings
$this->addOption('net', null, InputOption::VALUE_REQUIRED, 'The name of the docker network the ex-apps installed by this daemon should use. Default is "host".');
$this->addOption('haproxy_password', null, InputOption::VALUE_REQUIRED, 'AppAPI Docker Socket Proxy password for HAProxy Basic auth. Only for docker socket proxy daemon.');
$this->addOption('compute_device', null, InputOption::VALUE_REQUIRED, 'Compute device for GPU support (cpu|cuda|rocm)');
$this->addOption('net', null, InputOption::VALUE_REQUIRED, 'The name of the Docker network the ex-apps installed by this daemon should use. Default is "host".');
$this->addOption('haproxy_password', null, InputOption::VALUE_REQUIRED, 'AppAPI Docker Socket Proxy password for HAProxy Basic auth. Only for Docker Socket Proxy daemons.');
$this->addOption('compute_device', null, InputOption::VALUE_REQUIRED, 'Computation device for GPU support (cpu|cuda|rocm)');
$this->addOption('set-default', null, InputOption::VALUE_NONE, 'Set DaemonConfig as default');
$this->addOption('harp', null, InputOption::VALUE_NONE, 'Set daemon to use HaRP for all docker and exapp communication');
$this->addOption('harp_frp_address', null, InputOption::VALUE_REQUIRED, '[host]:[port] of the HaRP FRP server, default host is same as HaRP host and port is 8782');
$this->addOption('harp', null, InputOption::VALUE_NONE, 'Set the daemon to use HaRP for all Docker and ExApp communication');
$this->addOption('harp_frp_address', null, InputOption::VALUE_REQUIRED, '[host]:[port] of the HaRP FRP server, the default host is same as the HaRP host, port is 8782');
$this->addOption('harp_shared_key', null, InputOption::VALUE_REQUIRED, 'HaRP shared key for secure communication between HaRP and AppAPI');
$this->addOption('harp_docker_socket_port', null, InputOption::VALUE_REQUIRED, '\'remotePort\' of the FRP client of the remote docker socket proxy. There is one included in the harp container so this can be skipped for default setups.', '24000');
$this->addOption('harp_docker_socket_port', null, InputOption::VALUE_REQUIRED, '\'remotePort\' of the FRP client of the remote Docker socket proxy. There is one included in the harp container so this can be skipped for default setups.', '24000');
$this->addOption('harp_exapp_direct', null, InputOption::VALUE_NONE, 'Flag for the advanced setups only. Disables the FRP tunnel between ExApps and HaRP.');

$this->addUsage('harp_proxy_docker "Harp Proxy (Docker)" "docker-install" "http" "appapi-harp:8780" "http://nextcloud.local" --net nextcloud --harp --harp_frp_address "appapi-harp:8782" --harp_shared_key "some_very_secure_password" --set-default --compute_device=cuda');
Expand Down Expand Up @@ -82,7 +82,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

if ($this->daemonConfigService->getDaemonConfigByName($name) !== null) {
$output->writeln(sprintf('Skip registration, as daemon config `%s` already registered.', $name));
$output->writeln(sprintf('Registration skipped, as the daemon config `%s` already exists.', $name));
return 0;
}

Expand Down Expand Up @@ -115,15 +115,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
]);

if ($daemonConfig === null) {
$output->writeln('Failed to register daemon.');
$output->writeln('Failed to register the daemon config.');
return 1;
}

if ($input->getOption('set-default')) {
$this->config->setAppValue(Application::APP_ID, 'default_daemon_config', $daemonConfig->getName());
}

$output->writeln('Daemon successfully registered.');
$output->writeln('Daemon config successfully registered.');
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Command/Daemon/RemoveRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(

protected function configure(): void {
$this->setName('app_api:daemon:registry:remove');
$this->setDescription('Remove Deploy daemon Docker registry mapping');
$this->setDescription('Remove deploy daemon Docker registry mapping');
$this->addArgument('name', InputArgument::REQUIRED, 'Deploy daemon name');
$this->addOption('registry-from', null, InputOption::VALUE_REQUIRED, 'Deploy daemon registry from URL');
$this->addOption('registry-to', null, InputOption::VALUE_REQUIRED, 'Deploy daemon registry to URL');
Expand Down
2 changes: 1 addition & 1 deletion lib/Service/ExAppsPageService.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function provideAppApiState(IInitialState $initialState): void {
$this->dockerActions->initGuzzleClient($daemonConfig);
$daemonConfigAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
if (!$daemonConfigAccessible) {
$this->logger->warning(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please verify its configuration', $daemonConfig->getName()));
$this->logger->warning(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please check its configuration', $daemonConfig->getName()));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function getForm(): TemplateResponse {
$daemonConfigAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
$adminInitialData['daemon_config_accessible'] = $daemonConfigAccessible;
if (!$daemonConfigAccessible) {
$this->logger->error(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please verify its configuration', $daemonConfig->getName()));
$this->logger->error(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please check its configuration', $daemonConfig->getName()));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/SetupChecks/DaemonCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function run(): SetupResult {
$this->dockerActions->initGuzzleClient($daemonConfig);
$daemonConfigAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
if (!$daemonConfigAccessible) {
$this->logger->error(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please verify its configuration', $daemonConfig->getName()));
$this->logger->error(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please check its configuration', $daemonConfig->getName()));
return SetupResult::error(
$this->l10n->t('AppAPI default deploy daemon "%s" is not accessible. Please check the daemon configuration.', ['daemon' => $daemonConfig->getName()]),
"https://docs.nextcloud.com/server/$serverVer/admin_manual/exapps_management/AppAPIAndExternalApps.html#setup-deploy-daemon",
Expand All @@ -71,7 +71,7 @@ public function run(): SetupResult {

if (!boolval($daemonConfig->getDeployConfig()['harp'] ?? false)) {
return SetupResult::warning(
$this->l10n->t('AppAPI default deploy daemon is not using HaRP. Please consider upgrading to it for better performance.'),
$this->l10n->t('The AppAPI default deploy daemon is not using HaRP. Please consider switching to HaRP for better performance.'),
// todo: update link
"https://github.com/nextcloud/HaRP/",
);
Expand Down
12 changes: 6 additions & 6 deletions src/components/AdminSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<p>{{ t('app_api', 'The AppAPI Project is an exciting initiative that aims to revolutionize the way applications are developed for Nextcloud through the use of docker containers. Allowing for greater programming language choice and allowing computationally expensive tasks to be offloaded to a different server.') }}</p>
</div>
<NcSettingsSection
:name="t('app_api', 'Deploy Daemons')"
:description="t('app_api', 'Deploy Daemon (DaemonConfig) is an ExApps orchestration daemon.')"
:aria-label="t('app_api', 'Deploy Daemons. Deploy Daemon (DaemonConfig) is an ExApps orchestration daemon.')"
:name="t('app_api', 'Deploy daemons')"
:description="t('app_api', 'A deploy daemon (DaemonConfig) is an ExApps orchestration daemon.')"
:aria-label="t('app_api', 'Deploy daemons. A deploy daemon (DaemonConfig) is an ExApps orchestration daemon.')"
doc-url="https://docs.nextcloud.com/server/latest/admin_manual/exapps_management/AppAPIAndExternalApps.html#setup-deploy-daemon">
<NcNoteCard v-if="state.default_daemon_config !== '' && !state?.daemon_config_accessible" type="error">
<p>{{ t('app_api', 'Default Deploy Daemon is not accessible. Please verify its configuration') }}</p>
<p>{{ t('app_api', 'Default deploy daemon is not accessible. Please check its configuration') }}</p>
</NcNoteCard>
<DaemonConfigList :daemons.sync="daemons" :default-daemon.sync="default_daemon_config" :save-options="saveOptions" />
</NcSettingsSection>
Expand All @@ -33,10 +33,10 @@
</NcSettingsSection>
<NcSettingsSection
:name="t('app_api', 'ExApp container restart policy')"
:description="t('app_api', 'Specify container restart policy, e.g. \'always\' to ensure ExApp running after daemon server reboot')"
:description="t('app_api', 'Choose the container restart policy, e.g. \'always\' to ensure ExApps will be running after a daemon server reboot')"
:aria-label="t('app_api', 'ExApp container restart policy')">
<NcNoteCard type="info">
{{ t('app_api', 'This settings changes are reflected only for newly created containers') }}
{{ t('app_api', 'This settings changes are effective only for newly created containers') }}
</NcNoteCard>
<NcSelect
v-model="state.container_restart_policy"
Expand Down
19 changes: 7 additions & 12 deletions src/components/DaemonConfig/ConfirmDaemonDeleteModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,21 @@
-->
<template>
<div class="confirm-daemon-delete">
<NcModal :show="show" @close="closeModal">
<NcModal :show="show"
:name="t('app_api', 'Deploy daemon deletion confirmation')"
@close="closeModal">
<div class="confirm-delete-dialog">
<h2>{{ t('app_api', 'Are you sure you want delete Deploy Daemon') }}</h2>
<h2>{{ t('app_api', 'Are you sure you want delete the "{name}" deploy daemon?', { name: daemon.name }) }}</h2>

<NcCheckboxRadioSwitch
:checked.sync="removeExAppsOnDaemonDelete"
:placeholder="t('app_api', 'All ExApps on this daemon will be removed')"
:aria-label="t('app_api', 'All ExApps on this daemon will be removed')">
:checked.sync="removeExAppsOnDaemonDelete">
<template #default>
{{ t('app_api', 'All ExApps installed on this daemon will be removed') }}
{{ t('app_api', 'Remove all ExApps installed on this daemon') }}
</template>
</NcCheckboxRadioSwitch>

<div class="actions">
<NcButton type="success" @click="closeModal">
<template #icon>
<Cancel :size="20" />
</template>
<NcButton type="tertiary" @click="closeModal">
{{ t('app_api', 'Cancel') }}
</NcButton>
<NcButton type="error"
Expand All @@ -44,15 +41,13 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Delete from 'vue-material-design-icons/TrashCanOutline.vue'

export default {
name: 'ConfirmDaemonDeleteModal',
components: {
NcModal,
NcCheckboxRadioSwitch,
Cancel,
NcLoadingIcon,
Delete,
NcButton,
Expand Down
4 changes: 2 additions & 2 deletions src/components/DaemonConfig/DaemonConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default {
},
setDaemonDefault(daemon) {
if (this.daemon.accepts_deploy_id === 'manual-install') {
showError(t('app_api', '"manual-install" Deploy Daemon cannot be set as default'))
showError(t('app_api', 'A "manual-install" deploy daemon cannot be set as default'))
return
}
this.settingDefault = true
Expand All @@ -177,7 +177,7 @@ export default {
})
.catch(err => {
console.debug(err)
showError(t('app_api', 'Failed to save admin options. Check the logs'))
showError(t('app_api', 'Failed to save admin settings. Check the logs'))
this.settingDefault = false
})
},
Expand Down
32 changes: 17 additions & 15 deletions src/components/DaemonConfig/DaemonConfigDetailsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,30 @@
-->
<template>
<div class="daemon-config-modal">
<NcModal :show="show" @close="closeModal">
<div class="daemon-config-modal-details" :aria-label="t('app_api', 'Deploy daemon config details')">
<h2>{{ t('app_api', 'Deploy Daemon') }} - {{ daemon.display_name }}</h2>
<NcModal :show="show"
:name="t('app_api', 'Deploy daemon configuration') + ' - ' + daemon.display_name"
@close="closeModal">
<div class="daemon-config-modal-details" :aria-label="t('app_api', 'Deploy daemon configuration details')">
<h2>{{ t('app_api', 'Deploy daemon') }} - {{ daemon.display_name }}</h2>

<NcNoteCard v-if="isDefault" type="success">
{{ t('app_api', 'Default daemon. ExApps will be installed on it') }}
</NcNoteCard>

<NcNoteCard v-if="daemon.accepts_deploy_id === 'manual-install'" type="warning">
{{ t('app_api', 'Manual install daemon usually used for development. It cannot be set as default daemon.') }}
{{ t('app_api', 'The "Manual install" daemon is usually used for development. It cannot be set as the default daemon.') }}
</NcNoteCard>

<p><b>{{ t('app_api', 'ExApps installed') }}: </b>{{ daemon.exAppsCount }}</p>
<p><b>{{ t('app_api', 'Name') }}: </b>{{ daemon.name }}</p>
<p><b>{{ t('app_api', 'Protocol') }}: </b>{{ daemon.protocol }}</p>
<p><b>{{ t('app_api', 'Host') }}: </b>{{ daemon.host }}</p>
<p v-if="daemon.deploy_config.harp"><b>{{ t('app_api', 'ExApp direct communication (FRP disabled)') }}: </b>{{ daemon.deploy_config.harp.exapp_direct ?? false }}</p>
<p v-if="daemon.deploy_config.harp">
<b>{{ t('app_api', 'ExApp direct communication (FRP disabled)') }}: </b>
{{ daemon.deploy_config.harp.exapp_direct ?? false }}
</p>

<h3>{{ t('app_api', 'Deploy config') }}</h3>
<h3>{{ t('app_api', 'Deploy options') }}</h3>
<p><b>{{ t('app_api', 'Docker network') }}: </b>{{ daemon.deploy_config.net }}</p>
<p><b>{{ t('app_api', 'Nextcloud URL') }}: </b>{{ daemon.deploy_config.nextcloud_url }}</p>
<p v-if="daemon.deploy_config.haproxy_password" class="external-label">
Expand All @@ -36,10 +41,10 @@
autocomplete="off" />
</p>
<p>
<b>{{ t('app_api', 'GPUs support') }}:</b> {{ daemon.deploy_config.computeDevice && daemon.deploy_config?.computeDevice?.id !== 'cpu' || false }}
<b>{{ t('app_api', 'GPU support') }}:</b> {{ daemon.deploy_config.computeDevice && daemon.deploy_config?.computeDevice?.id !== 'cpu' || false }}
</p>
<p v-if="daemon.deploy_config.computeDevice">
<b>{{ t('app_api', 'Compute device') }}:</b> {{ daemon.deploy_config?.computeDevice?.label }}
<b>{{ t('app_api', 'Computation device') }}:</b> {{ daemon.deploy_config?.computeDevice?.label }}
</p>
<p><b>{{ t('app_api', 'Memory limit') }}:</b> {{ formatMemoryLimit(daemon.deploy_config?.resourceLimits?.memory) }}</p>

Expand All @@ -54,7 +59,7 @@

<div class="actions">
<NcButton v-if="daemon.accepts_deploy_id !== 'manual-install'" @click="verifyConnection">
{{ t('app_api', 'Verify connection') }}
{{ t('app_api', 'Check connection') }}
<template #icon>
<NcLoadingIcon v-if="verifying" :size="20" />
<Connection v-else :size="20" />
Expand Down Expand Up @@ -122,13 +127,13 @@ export default {
if (res.data.success) {
showSuccess(t('app_api', 'Daemon connection successful'))
} else {
showError(t('app_api', 'Failed to connect to Daemon. Check the logs'))
showError(t('app_api', 'Failed to connect to the daemon. Check the logs'))
}
this.verifying = false
})
.catch(err => {
this.verifying = false
showError(t('app_api', 'Failed to check connection to Daemon. Check the logs'))
showError(t('app_api', 'Failed to check connection to the daemon. Check the logs'))
console.debug(err)
})
},
Expand All @@ -148,10 +153,7 @@ export default {
return t('app_api', 'Unlimited')
}
const cpus = nanoCpus / 1000000000
if (cpus === 1) {
return t('app_api', '1 CPU')
}
return t('app_api', '{cpus} CPUs', { cpus: cpus.toFixed(2) })
return n('app_api', '{n} CPU', '{n} CPUs', cpus, { n: cpus.toFixed(2) })
},
},
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/DaemonConfig/DaemonConfigList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
</ul>
<NcEmptyContent
v-else
:name="t('app_api', 'No Deploy daemons configured')"
:description="t('app_api', 'Register a custom one or setup from available templates')">
:name="t('app_api', 'No Deploy daemons is registered')"
:description="t('app_api', 'Register a custom one or configure one from the available templates')">
<template #icon>
<FormatListBullet :size="20" />
</template>
</NcEmptyContent>
</div>
<NcButton type="primary" style="margin: 20px 0;" @click="showRegister">
{{ t('app_api', 'Register Daemon') }}
{{ t('app_api', 'Register daemon') }}
<template #icon>
<Plus v-if="!registering" :size="20" />
<NcLoadingIcon v-else />
Expand Down
Loading