Skip to content

Commit 5266854

Browse files
committed
feat: add pre-flight check for HaRP K8s support
Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>
1 parent 01b2c25 commit 5266854

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

lib/DeployActions/KubernetesActions.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ public function deployExApp(ExApp $exApp, DaemonConfig $daemonConfig, array $par
7777
$harpUrl = $this->buildHarpK8sUrl($daemonConfig);
7878
$this->initGuzzleClient($daemonConfig);
7979

80+
$pingError = $this->ping($daemonConfig);
81+
if ($pingError !== '') {
82+
return $pingError;
83+
}
84+
8085
$roles = $params['k8s_service_roles'] ?? [];
8186

8287
if (empty($roles)) {
@@ -703,6 +708,42 @@ public function resolveExAppUrl(
703708
return sprintf('%s/exapps/%s', $url, $appId);
704709
}
705710

711+
/**
712+
* Pre-flight check: verify HaRP has a working Kubernetes backend.
713+
*
714+
* Calls GET /info and inspects the kubernetes status fields.
715+
* Returns empty string on success, actionable error message on failure.
716+
*/
717+
public function ping(DaemonConfig $daemonConfig): string {
718+
$url = rtrim($daemonConfig->getProtocol() . '://' . $daemonConfig->getHost(), '/')
719+
. '/exapps/app_api/info';
720+
try {
721+
$response = $this->guzzleClient->get($url, ['timeout' => 5]);
722+
$data = json_decode((string)$response->getBody(), true);
723+
724+
$k8s = $data['kubernetes'] ?? null;
725+
if ($k8s === null) {
726+
return 'HaRP version is too old and does not report Kubernetes support. Please update HaRP.';
727+
}
728+
if (!($k8s['enabled'] ?? false)) {
729+
return 'Kubernetes backend is disabled in HaRP. Set HP_K8S_ENABLED=true in HaRP configuration.';
730+
}
731+
if (!($k8s['reachable'] ?? false)) {
732+
return sprintf(
733+
'HaRP cannot reach the Kubernetes API server (%s). Check HP_K8S_API_SERVER, token, and network connectivity.',
734+
$k8s['api_server'] ?? 'unknown'
735+
);
736+
}
737+
return '';
738+
} catch (GuzzleException $e) {
739+
$this->logger->error(sprintf('K8s pre-flight check failed: %s', $e->getMessage()), ['exception' => $e]);
740+
return sprintf('Cannot reach HaRP: %s', $e->getMessage());
741+
} catch (Exception $e) {
742+
$this->logger->error(sprintf('K8s pre-flight check failed: %s', $e->getMessage()), ['exception' => $e]);
743+
return sprintf('K8s pre-flight check failed: %s', $e->getMessage());
744+
}
745+
}
746+
706747
public function buildHarpK8sUrl(DaemonConfig $daemonConfig): string {
707748
$url = $daemonConfig->getProtocol() . '://' . $daemonConfig->getHost();
708749
return rtrim($url, '/') . '/exapps/app_api/k8s';

lib/SetupChecks/DaemonCheck.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use OCA\AppAPI\AppInfo\Application;
1313
use OCA\AppAPI\Db\DaemonConfig;
1414
use OCA\AppAPI\DeployActions\DockerActions;
15+
use OCA\AppAPI\DeployActions\KubernetesActions;
1516
use OCA\AppAPI\Service\DaemonConfigService;
1617
use OCP\IAppConfig;
1718
use OCP\IConfig;
@@ -26,6 +27,7 @@ public function __construct(
2627
private IConfig $config,
2728
private IAppConfig $appConfig,
2829
private DockerActions $dockerActions,
30+
private KubernetesActions $kubernetesActions,
2931
private LoggerInterface $logger,
3032
private DaemonConfigService $daemonConfigService,
3133
) {
@@ -59,13 +61,25 @@ public function run(): SetupResult {
5961
);
6062
}
6163

64+
$docsUrl = "https://docs.nextcloud.com/server/$serverVer/admin_manual/exapps_management/AppAPIAndExternalApps.html#setup-deploy-daemon";
65+
66+
if ($daemonConfig->getAcceptsDeployId() === KubernetesActions::DEPLOY_ID) {
67+
$this->kubernetesActions->initGuzzleClient($daemonConfig);
68+
$pingError = $this->kubernetesActions->ping($daemonConfig);
69+
if ($pingError !== '') {
70+
$this->logger->error(sprintf('K8s deploy daemon "%s" pre-flight check failed: %s', $daemonConfig->getName(), $pingError));
71+
return SetupResult::error($pingError, $docsUrl);
72+
}
73+
return SetupResult::success();
74+
}
75+
6276
$this->dockerActions->initGuzzleClient($daemonConfig);
6377
$daemonConfigAccessible = $this->dockerActions->ping($this->dockerActions->buildDockerUrl($daemonConfig));
6478
if (!$daemonConfigAccessible) {
6579
$this->logger->error(sprintf('Deploy daemon "%s" is not accessible by Nextcloud. Please check its configuration', $daemonConfig->getName()));
6680
return SetupResult::error(
6781
$this->l10n->t('AppAPI default deploy daemon "%s" is not accessible. Please check the daemon configuration.', ['daemon' => $daemonConfig->getName()]),
68-
"https://docs.nextcloud.com/server/$serverVer/admin_manual/exapps_management/AppAPIAndExternalApps.html#setup-deploy-daemon",
82+
$docsUrl,
6983
);
7084
}
7185

0 commit comments

Comments
 (0)