fix7: закрыть P0/P1 блокеры runtime/install и перевести hysteria UI в read-only
This commit is contained in:
+1
@@ -7,6 +7,7 @@ export {}
|
|||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
ElCard: typeof import('element-plus/es')['ElCard']
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
ElCol: typeof import('element-plus/es')['ElCol']
|
ElCol: typeof import('element-plus/es')['ElCol']
|
||||||
|
|||||||
@@ -2,28 +2,6 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<el-form :inline="true">
|
<el-form :inline="true">
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="submitForm" :icon="Select">
|
|
||||||
{{ $t("common.save") }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-upload
|
|
||||||
v-model:file-list="fileList"
|
|
||||||
:http-request="handleImport"
|
|
||||||
:show-file-list="false"
|
|
||||||
accept=".yaml"
|
|
||||||
:limit="1"
|
|
||||||
:before-upload="beforeImport"
|
|
||||||
>
|
|
||||||
<el-button>
|
|
||||||
<template #icon>
|
|
||||||
<i-ep-upload />
|
|
||||||
</template>
|
|
||||||
{{ $t("common.import") }}
|
|
||||||
</el-button>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleExport">
|
<el-button @click="handleExport">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@@ -32,53 +10,18 @@
|
|||||||
{{ $t("common.export") }}
|
{{ $t("common.export") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="handleReset">
|
|
||||||
<template #icon>
|
|
||||||
<i-ep-refresh />
|
|
||||||
</template>
|
|
||||||
{{ $t("common.reset") }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-alert
|
||||||
|
title="Hysteria runtime config is managed by hy2xs-orchestrator reconfigure."
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
style="margin-bottom: 12px"
|
||||||
|
/>
|
||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<el-form ref="enableFormRef" :model="enableForm" inline>
|
<el-form inline>
|
||||||
<el-tooltip :content="$t('hysteria.config.enable')" placement="bottom">
|
|
||||||
<el-form-item prop="enable">
|
|
||||||
<el-switch
|
|
||||||
v-model="enableForm.enable"
|
|
||||||
active-value="1"
|
|
||||||
inactive-value="0"
|
|
||||||
@change="handleChangeEnable"
|
|
||||||
:active-text="$t('hysteria.enable')"
|
|
||||||
:inactive-text="$t('hysteria.disable')"
|
|
||||||
style="height: 32px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-form-item>
|
|
||||||
<el-dropdown @command="handleDropdownClick">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
:icon="CirclePlusFilled"
|
|
||||||
style="height: 32px"
|
|
||||||
>
|
|
||||||
{{ $t("hysteria.addConfigItem") }}
|
|
||||||
</el-button>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item
|
|
||||||
:key="item"
|
|
||||||
v-for="item in tabs"
|
|
||||||
:command="item.name"
|
|
||||||
>{{ item.desc }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-tag style="height: 32px">
|
<el-tag style="height: 32px">
|
||||||
{{ $t("hysteria.hysteria2Version") }}:
|
{{ $t("hysteria.hysteria2Version") }}:
|
||||||
@@ -100,17 +43,16 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-form
|
<el-form
|
||||||
ref="dataFormRef"
|
ref="dataFormRef"
|
||||||
:rules="dataFormRules"
|
:rules="dataFormRules"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
:model="dataForm"
|
:model="dataForm"
|
||||||
|
:disabled="true"
|
||||||
>
|
>
|
||||||
<el-tabs
|
<el-tabs
|
||||||
v-model="activeName"
|
v-model="activeName"
|
||||||
class="tabs"
|
class="tabs"
|
||||||
closable
|
|
||||||
@tab-remove="closeTabPane"
|
|
||||||
>
|
>
|
||||||
<el-tab-pane :label="$t('hysteria.extension')" name="extension">
|
<el-tab-pane :label="$t('hysteria.extension')" name="extension">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
@@ -1057,21 +999,16 @@ import {
|
|||||||
Tab,
|
Tab,
|
||||||
} from "@/api/config/types";
|
} from "@/api/config/types";
|
||||||
import Outbounds from "./components/Outbounds/index.vue";
|
import Outbounds from "./components/Outbounds/index.vue";
|
||||||
import { CirclePlusFilled, Select } from "@element-plus/icons-vue";
|
|
||||||
import {
|
import {
|
||||||
exportHysteria2ConfigApi,
|
exportHysteria2ConfigApi,
|
||||||
getHysteria2ConfigApi,
|
getHysteria2ConfigApi,
|
||||||
importHysteria2ConfigApi,
|
|
||||||
listConfigApi,
|
listConfigApi,
|
||||||
updateConfigsApi,
|
|
||||||
updateHysteria2ConfigApi,
|
|
||||||
uploadCertFileApi,
|
uploadCertFileApi,
|
||||||
} from "@/api/config";
|
} from "@/api/config";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { assignWith, deepCopy } from "@/utils/copy";
|
import { assignWith, deepCopy } from "@/utils/copy";
|
||||||
import {
|
import {
|
||||||
UploadFile,
|
UploadFile,
|
||||||
UploadRawFile,
|
|
||||||
UploadRequestOptions,
|
UploadRequestOptions,
|
||||||
} from "element-plus/lib/components";
|
} from "element-plus/lib/components";
|
||||||
import { monitorHysteria2Api } from "@/api/monitor";
|
import { monitorHysteria2Api } from "@/api/monitor";
|
||||||
@@ -1079,7 +1016,6 @@ import { UploadUserFile } from "element-plus";
|
|||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const hysteria2EnableKey = "HYSTERIA2_ENABLE";
|
|
||||||
const hysteria2Remark = "HYSTERIA2_CONFIG_REMARK";
|
const hysteria2Remark = "HYSTERIA2_CONFIG_REMARK";
|
||||||
const clashExtension = "CLASH_EXTENSION";
|
const clashExtension = "CLASH_EXTENSION";
|
||||||
const dataFormRef = ref(ElForm);
|
const dataFormRef = ref(ElForm);
|
||||||
@@ -1119,9 +1055,6 @@ const resolverTypes = ref<string[]>(["tcp", "udp", "tls", "https"]);
|
|||||||
const masqueradeTypes = ref<string[]>(["file", "proxy", "string"]);
|
const masqueradeTypes = ref<string[]>(["file", "proxy", "string"]);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
enableForm: {
|
|
||||||
enable: "0",
|
|
||||||
},
|
|
||||||
configForm: {
|
configForm: {
|
||||||
remark: "",
|
remark: "",
|
||||||
clashExtension: "",
|
clashExtension: "",
|
||||||
@@ -1140,7 +1073,6 @@ const state = reactive({
|
|||||||
acl: false,
|
acl: false,
|
||||||
outbounds: false,
|
outbounds: false,
|
||||||
masquerade: false,
|
masquerade: false,
|
||||||
fileList: [] as UploadFile[],
|
|
||||||
hysteria2Monitor: {
|
hysteria2Monitor: {
|
||||||
version: "",
|
version: "",
|
||||||
running: false,
|
running: false,
|
||||||
@@ -1150,7 +1082,6 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
enableForm,
|
|
||||||
configForm,
|
configForm,
|
||||||
activeName,
|
activeName,
|
||||||
dataForm,
|
dataForm,
|
||||||
@@ -1166,7 +1097,6 @@ const {
|
|||||||
acl,
|
acl,
|
||||||
outbounds,
|
outbounds,
|
||||||
masquerade,
|
masquerade,
|
||||||
fileList,
|
|
||||||
hysteria2Monitor,
|
hysteria2Monitor,
|
||||||
crtFileList,
|
crtFileList,
|
||||||
keyFileList,
|
keyFileList,
|
||||||
@@ -1237,28 +1167,6 @@ const tabs = computed(() => {
|
|||||||
return tabs;
|
return tabs;
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleImport = (params: UploadRequestOptions) => {
|
|
||||||
if (state.fileList.length > 0) {
|
|
||||||
let formData = new FormData();
|
|
||||||
formData.append("file", params.file);
|
|
||||||
importHysteria2ConfigApi(formData).then(() => {
|
|
||||||
ElMessage.success(t("common.success"));
|
|
||||||
});
|
|
||||||
state.fileList = [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const beforeImport = (file: UploadRawFile) => {
|
|
||||||
if (!file.name.endsWith(".yaml")) {
|
|
||||||
ElMessage.error("file format not supported");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (file.size / 1024 / 1024 > 2) {
|
|
||||||
ElMessage.error("the file is too big, less than 2 MB");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
let response = await exportHysteria2ConfigApi();
|
let response = await exportHysteria2ConfigApi();
|
||||||
try {
|
try {
|
||||||
@@ -1279,199 +1187,13 @@ const handleExport = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
state.configForm = {
|
|
||||||
remark: "",
|
|
||||||
clashExtension: "",
|
|
||||||
};
|
|
||||||
state.dataForm = deepCopy(defaultHysteria2ServerConfig);
|
|
||||||
state.activeName = "extension";
|
|
||||||
state.tlsType = "acme";
|
|
||||||
state.aclType = "inline";
|
|
||||||
state.obfs = false;
|
|
||||||
state.quic = false;
|
|
||||||
state.bandwidth = false;
|
|
||||||
state.speedTest = false;
|
|
||||||
state.udp = false;
|
|
||||||
state.resolver = false;
|
|
||||||
state.sniff = false;
|
|
||||||
state.acl = false;
|
|
||||||
state.outbounds = false;
|
|
||||||
state.masquerade = false;
|
|
||||||
state.fileList = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeEnable = async () => {
|
|
||||||
const enable = state.enableForm.enable === "1" ? "0" : "1";
|
|
||||||
try {
|
|
||||||
await updateConfigsApi({
|
|
||||||
configUpdateDtos: [
|
|
||||||
{ key: hysteria2EnableKey, value: state.enableForm.enable },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
if (state.enableForm.enable === "1") {
|
|
||||||
ElMessage.success(t("common.enableSuccess"));
|
|
||||||
} else {
|
|
||||||
ElMessage.error(t("common.disableSuccess"));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
state.enableForm.enable = enable;
|
|
||||||
}
|
|
||||||
await setHysteria2Monitor();
|
|
||||||
};
|
|
||||||
|
|
||||||
const submitForm = () => {
|
|
||||||
dataFormRef.value.validate((valid: any) => {
|
|
||||||
if (valid) {
|
|
||||||
let configs: ConfigsUpdateDto[] = [
|
|
||||||
{
|
|
||||||
key: hysteria2Remark,
|
|
||||||
value: state.configForm.remark,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: clashExtension,
|
|
||||||
value: state.configForm.clashExtension,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
updateConfigsApi({ configUpdateDtos: configs });
|
|
||||||
|
|
||||||
if (state.tlsType == "tls") {
|
|
||||||
state.dataForm.acme = undefined;
|
|
||||||
} else if (state.tlsType == "acme") {
|
|
||||||
state.dataForm.tls = undefined;
|
|
||||||
if (state.dataForm.acme?.type == "http") {
|
|
||||||
state.dataForm.acme.tls = undefined;
|
|
||||||
state.dataForm.acme.dns = undefined;
|
|
||||||
} else if (state.dataForm.acme?.type == "tls") {
|
|
||||||
state.dataForm.acme.http = undefined;
|
|
||||||
state.dataForm.acme.dns = undefined;
|
|
||||||
} else if (state.dataForm.acme?.type == "dns") {
|
|
||||||
state.dataForm.acme.http = undefined;
|
|
||||||
state.dataForm.acme.tls = undefined;
|
|
||||||
} else if (state.dataForm.acme?.type == "") {
|
|
||||||
state.dataForm.acme.http = undefined;
|
|
||||||
state.dataForm.acme.tls = undefined;
|
|
||||||
state.dataForm.acme.dns = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dataForm.acl) {
|
|
||||||
if (state.aclType == "inline") {
|
|
||||||
state.dataForm.acl.file = undefined;
|
|
||||||
} else if (state.aclType == "file") {
|
|
||||||
state.dataForm.acl.inline = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dataForm.resolver?.type == "tcp") {
|
|
||||||
state.dataForm.resolver.udp = undefined;
|
|
||||||
state.dataForm.resolver.tls = undefined;
|
|
||||||
state.dataForm.resolver.https = undefined;
|
|
||||||
} else if (state.dataForm.resolver?.type == "udp") {
|
|
||||||
state.dataForm.resolver.tcp = undefined;
|
|
||||||
state.dataForm.resolver.tls = undefined;
|
|
||||||
state.dataForm.resolver.https = undefined;
|
|
||||||
} else if (state.dataForm.resolver?.type == "tls") {
|
|
||||||
state.dataForm.resolver.tcp = undefined;
|
|
||||||
state.dataForm.resolver.udp = undefined;
|
|
||||||
state.dataForm.resolver.https = undefined;
|
|
||||||
} else if (state.dataForm.resolver?.type == "https") {
|
|
||||||
state.dataForm.resolver.tcp = undefined;
|
|
||||||
state.dataForm.resolver.udp = undefined;
|
|
||||||
state.dataForm.resolver.tls = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dataForm.masquerade?.type == "file") {
|
|
||||||
state.dataForm.masquerade.proxy = undefined;
|
|
||||||
state.dataForm.masquerade.string = undefined;
|
|
||||||
} else if (state.dataForm.masquerade?.type == "proxy") {
|
|
||||||
state.dataForm.masquerade.file = undefined;
|
|
||||||
state.dataForm.masquerade.string = undefined;
|
|
||||||
} else if (state.dataForm.masquerade?.type == "string") {
|
|
||||||
state.dataForm.masquerade.file = undefined;
|
|
||||||
state.dataForm.masquerade.proxy = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state.obfs) {
|
|
||||||
state.dataForm.obfs = undefined;
|
|
||||||
}
|
|
||||||
if (!state.quic) {
|
|
||||||
state.dataForm.quic = undefined;
|
|
||||||
}
|
|
||||||
if (!state.bandwidth) {
|
|
||||||
state.dataForm.bandwidth = undefined;
|
|
||||||
state.dataForm.ignoreClientBandwidth = undefined;
|
|
||||||
}
|
|
||||||
if (!state.speedTest) {
|
|
||||||
state.dataForm.speedTest = undefined;
|
|
||||||
}
|
|
||||||
if (!state.udp) {
|
|
||||||
state.dataForm.disableUDP = undefined;
|
|
||||||
state.dataForm.udpIdleTimeout = undefined;
|
|
||||||
}
|
|
||||||
if (!state.resolver) {
|
|
||||||
state.dataForm.resolver = undefined;
|
|
||||||
}
|
|
||||||
if (!state.sniff) {
|
|
||||||
state.dataForm.sniff = undefined;
|
|
||||||
}
|
|
||||||
if (!state.acl) {
|
|
||||||
state.dataForm.acl = undefined;
|
|
||||||
}
|
|
||||||
if (!state.outbounds) {
|
|
||||||
state.dataForm.outbounds = undefined;
|
|
||||||
}
|
|
||||||
if (!state.masquerade) {
|
|
||||||
state.dataForm.masquerade = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dataForm?.udpIdleTimeout === "") {
|
|
||||||
state.dataForm!.udpIdleTimeout = "60s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.quic?.maxIdleTimeout === "") {
|
|
||||||
state.dataForm!.quic!.maxIdleTimeout = "30s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.resolver?.tcp?.timeout === "") {
|
|
||||||
state.dataForm!.resolver!.tcp!.timeout = "4s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.resolver?.udp?.timeout === "") {
|
|
||||||
state.dataForm!.resolver!.udp!.timeout = "4s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.resolver?.tls?.timeout === "") {
|
|
||||||
state.dataForm!.resolver!.tls!.timeout = "10s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.resolver?.https?.timeout === "") {
|
|
||||||
state.dataForm!.resolver!.https!.timeout = "10s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.sniff?.timeout === "") {
|
|
||||||
state.dataForm!.sniff!.timeout = "2s";
|
|
||||||
}
|
|
||||||
if (state.dataForm?.acl?.geoUpdateInterval === "") {
|
|
||||||
state.dataForm!.acl!.geoUpdateInterval = "168h";
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = { ...state.dataForm };
|
|
||||||
updateHysteria2ConfigApi(params).then(() => {
|
|
||||||
ElMessage.success(t("common.success"));
|
|
||||||
setConfig();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setConfig = () => {
|
const setConfig = () => {
|
||||||
listConfigApi({
|
listConfigApi({
|
||||||
keys: [
|
keys: [hysteria2Remark, clashExtension],
|
||||||
hysteria2EnableKey,
|
|
||||||
hysteria2Remark,
|
|
||||||
clashExtension,
|
|
||||||
],
|
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
data.forEach((configVo) => {
|
data.forEach((configVo) => {
|
||||||
if (configVo.key === hysteria2EnableKey) {
|
if (configVo.key === hysteria2Remark) {
|
||||||
state.enableForm.enable = configVo.value;
|
|
||||||
} else if (configVo.key === hysteria2Remark) {
|
|
||||||
state.configForm.remark = configVo.value;
|
state.configForm.remark = configVo.value;
|
||||||
} else if (configVo.key === clashExtension) {
|
} else if (configVo.key === clashExtension) {
|
||||||
state.configForm.clashExtension = configVo.value;
|
state.configForm.clashExtension = configVo.value;
|
||||||
@@ -1502,66 +1224,6 @@ const setConfig = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeTabPane = (tabPaneName: string) => {
|
|
||||||
if (
|
|
||||||
tabPaneName === "extension" ||
|
|
||||||
tabPaneName === "listen" ||
|
|
||||||
tabPaneName === "tls" ||
|
|
||||||
tabPaneName === "http"
|
|
||||||
) {
|
|
||||||
ElMessage.error("This tab is required");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tabPaneName === "obfs") {
|
|
||||||
state.obfs = false;
|
|
||||||
} else if (tabPaneName === "quic") {
|
|
||||||
state.quic = false;
|
|
||||||
} else if (tabPaneName === "bandwidth") {
|
|
||||||
state.bandwidth = false;
|
|
||||||
} else if (tabPaneName === "speedTest") {
|
|
||||||
state.speedTest = false;
|
|
||||||
} else if (tabPaneName === "udp") {
|
|
||||||
state.udp = false;
|
|
||||||
} else if (tabPaneName === "resolver") {
|
|
||||||
state.resolver = false;
|
|
||||||
} else if (tabPaneName === "sniff") {
|
|
||||||
state.sniff = false;
|
|
||||||
} else if (tabPaneName === "acl") {
|
|
||||||
state.acl = false;
|
|
||||||
} else if (tabPaneName === "outbounds") {
|
|
||||||
state.outbounds = false;
|
|
||||||
} else if (tabPaneName === "masquerade") {
|
|
||||||
state.masquerade = false;
|
|
||||||
}
|
|
||||||
state.activeName = "listen";
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDropdownClick = (command: string) => {
|
|
||||||
if (command === "obfs") {
|
|
||||||
state.obfs = true;
|
|
||||||
} else if (command === "quic") {
|
|
||||||
state.quic = true;
|
|
||||||
} else if (command === "bandwidth") {
|
|
||||||
state.bandwidth = true;
|
|
||||||
} else if (command === "speedTest") {
|
|
||||||
state.speedTest = true;
|
|
||||||
} else if (command === "udp") {
|
|
||||||
state.udp = true;
|
|
||||||
} else if (command === "resolver") {
|
|
||||||
state.resolver = true;
|
|
||||||
} else if (command === "sniff") {
|
|
||||||
state.sniff = true;
|
|
||||||
} else if (command === "acl") {
|
|
||||||
state.acl = true;
|
|
||||||
} else if (command === "outbounds") {
|
|
||||||
state.outbounds = true;
|
|
||||||
} else if (command === "masquerade") {
|
|
||||||
state.masquerade = true;
|
|
||||||
}
|
|
||||||
state.activeName = command;
|
|
||||||
};
|
|
||||||
|
|
||||||
const setHysteria2Monitor = async () => {
|
const setHysteria2Monitor = async () => {
|
||||||
const { data } = await monitorHysteria2Api();
|
const { data } = await monitorHysteria2Api();
|
||||||
Object.assign(state.hysteria2Monitor, data);
|
Object.assign(state.hysteria2Monitor, data);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@
|
|||||||
## CLI baseline
|
## CLI baseline
|
||||||
|
|
||||||
Команды:
|
Команды:
|
||||||
- `install --package-dir <path> [--config /etc/hy2xs/hy2xs.env]`
|
- `install --package-dir <path> [--config <source-env>]`
|
||||||
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --dry-run`
|
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --dry-run`
|
||||||
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --apply`
|
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --apply`
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ Install-only orchestrator ставит систему на чистый Debian 1
|
|||||||
CLI baseline
|
CLI baseline
|
||||||
Допустимые флаги:
|
Допустимые флаги:
|
||||||
- --non-interactive
|
- --non-interactive
|
||||||
- --domain
|
|
||||||
- --port
|
- --port
|
||||||
- --ssh-port
|
- --ssh-port
|
||||||
- --skip-firewall
|
- --skip-firewall
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ export async function preflight(context: InstallContext): Promise<void> {
|
|||||||
fail("acme mode requires HY2XS_DOMAIN and HY2XS_ACME_EMAIL");
|
fail("acme mode requires HY2XS_DOMAIN and HY2XS_ACME_EMAIL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isReconfigure && context.config.tlsMode === "acme") {
|
||||||
|
const acmeChallengePort = context.config.acmeType === "http" ? 80 : 443;
|
||||||
|
if (await isPortBusy(acmeChallengePort)) {
|
||||||
|
fail(`ACME ${context.config.acmeType}-challenge port is already in use: ${acmeChallengePort}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (context.config.domain) {
|
if (context.config.domain) {
|
||||||
try {
|
try {
|
||||||
const a = await run`getent ahostsv4 ${context.config.domain}`;
|
const a = await run`getent ahostsv4 ${context.config.domain}`;
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ cp -a "$PACKAGE_DIR/docs" "$RUNTIME_PACKAGE_DIR/"
|
|||||||
cp -a "$PACKAGE_DIR/systemd" "$RUNTIME_PACKAGE_DIR/"
|
cp -a "$PACKAGE_DIR/systemd" "$RUNTIME_PACKAGE_DIR/"
|
||||||
cp -a "$PACKAGE_DIR/templates" "$RUNTIME_PACKAGE_DIR/"
|
cp -a "$PACKAGE_DIR/templates" "$RUNTIME_PACKAGE_DIR/"
|
||||||
cp -a "$PACKAGE_DIR/metadata" "$RUNTIME_PACKAGE_DIR/"
|
cp -a "$PACKAGE_DIR/metadata" "$RUNTIME_PACKAGE_DIR/"
|
||||||
|
cp -a "$PACKAGE_DIR/ui" "$RUNTIME_PACKAGE_DIR/"
|
||||||
|
cp -a "$PACKAGE_DIR/install.sh" "$RUNTIME_PACKAGE_DIR/"
|
||||||
|
|
||||||
log "package directory: $PACKAGE_DIR"
|
log "package directory: $PACKAGE_DIR"
|
||||||
log "starting install-only orchestrator"
|
log "starting install-only orchestrator"
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ ensure_node() {
|
|||||||
|
|
||||||
ensure_pnpm() {
|
ensure_pnpm() {
|
||||||
local managed="$TOOLCHAIN_DIR/pnpm/bin/pnpm"
|
local managed="$TOOLCHAIN_DIR/pnpm/bin/pnpm"
|
||||||
|
export PATH="$TOOLCHAIN_DIR/pnpm/bin:$PATH"
|
||||||
if [ -x "$managed" ] && [ "$($managed --version)" = "$PNPM_REQUIRED" ]; then
|
if [ -x "$managed" ] && [ "$($managed --version)" = "$PNPM_REQUIRED" ]; then
|
||||||
PNPM_BIN="$managed"
|
PNPM_BIN="$managed"
|
||||||
else
|
else
|
||||||
@@ -151,11 +152,8 @@ ensure_pnpm() {
|
|||||||
mkdir -p "$TOOLCHAIN_DIR/pnpm/bin"
|
mkdir -p "$TOOLCHAIN_DIR/pnpm/bin"
|
||||||
corepack enable --install-directory "$TOOLCHAIN_DIR/pnpm/bin"
|
corepack enable --install-directory "$TOOLCHAIN_DIR/pnpm/bin"
|
||||||
corepack prepare "pnpm@$PNPM_REQUIRED" --activate
|
corepack prepare "pnpm@$PNPM_REQUIRED" --activate
|
||||||
if command -v pnpm >/dev/null 2>&1; then
|
[ -x "$managed" ] || fail "pnpm binary was not installed into $managed"
|
||||||
cp "$(command -v pnpm)" "$managed"
|
PNPM_BIN="$managed"
|
||||||
chmod 0755 "$managed"
|
|
||||||
fi
|
|
||||||
PNPM_BIN="$(command -v pnpm)"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PNPM_BIN
|
export PNPM_BIN
|
||||||
|
|||||||
Reference in New Issue
Block a user