完成Linux版本发布和下载页面

Signed-off-by: Chenyang Gao <gps949@outlook.com>
This commit is contained in:
Chenyang Gao
2023-05-12 17:46:33 +08:00
parent 5764ba8907
commit ceece9361f
12 changed files with 769 additions and 57 deletions
+233 -4
View File
@@ -38,6 +38,9 @@ const naviAarch64Uploader = ref(null);
const naviProc = ref("");
const naviProcPercent = ref(0);
const wantLinuxRepo = ref("");
const wantLinuxRepoCred = ref("");
const wantWinVersion = ref({});
const winExtURL = ref(false);
const winUploader = ref(null);
@@ -185,15 +188,42 @@ function handleWinError(err) {
toastShow.value = true;
}
onMounted(() => {
var getLinuxBuildStateIntID;
function getLinuxBuildState() {
axios
.get("/cockpit/api/setting/general")
.get("/cockpit/api/publish")
.then(function (response) {
// 处理成功情况
if (response.data["status"] == "success") {
uploadURL.value =
"https://" + response.data["data"]["server_url"] + "/cockpit/api/publish/";
uploadURL.value = response.data["data"]["upload_url"];
ClientVersion.value = response.data["data"]["client_version"];
if (ClientVersion.value["linux"]["buildst"] != "正在进行") {
clearInterval(getLinuxBuildStateIntID);
}
} else {
toastMsg.value = response.data["status"].substring(6);
toastShow.value = true;
}
})
.catch(function (error) {
// 处理错误情况
toastMsg.value = error;
toastShow.value = true;
});
}
onMounted(() => {
axios
.get("/cockpit/api/publish")
.then(function (response) {
// 处理成功情况
if (response.data["status"] == "success") {
uploadURL.value = response.data["data"]["upload_url"];
ClientVersion.value = response.data["data"]["client_version"];
wantLinuxRepo.value = response.data["data"]["client_version"]["linux"]["url"];
wantWinVersion.value = {};
wantWinVersion.value["version"] =
response.data["data"]["client_version"]["win"]["version"];
@@ -221,6 +251,33 @@ onMounted(() => {
});
});
function publishLinux() {
axios
.post("/cockpit/api/publish/linux", {
version: wantLinuxRepoCred.value,
url: wantLinuxRepo.value,
})
.then(function (response) {
// 处理成功情况
if (response.data["status"] == "success") {
toastMsg.value = "Linux已提交构建";
toastShow.value = true;
getLinuxBuildStateIntID = setInterval(() => {
getLinuxBuildState();
}, 3000);
} else {
toastMsg.value = response.data["status"].substring(6);
toastShow.value = true;
}
})
.catch(function (error) {
// 处理错误情况
toastMsg.value = error;
toastShow.value = true;
});
return;
}
function publishWin() {
if (winExtURL.value) {
axios
@@ -501,6 +558,178 @@ function publishIOSToTestflight() {
</div>
</div>
<!---->
<div>
<header class="max-w-sm flex mt-4">
<svg
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="28"
height="28"
>
<path
d="M525.2 198.3c-8.6 5.6-15.2 13.8-18.9 23.4-3.8 12.4-3.2 25.6 1.5 37.7 3.9 12.7 11.7 23.8 22.2 31.8 5.4 3.8 11.6 6.2 18.2 7 6.6 0.8 13.2-0.3 19.1-3.3 7-3.9 12.6-10 15.9-17.3 3.2-7.4 5-15.3 5.2-23.3 0.7-10.2-0.6-20.4-3.8-30.1-3.5-10.6-10.3-19.7-19.5-25.9-4.7-3-9.9-5-15.4-5.8-5.5-0.8-11.1-0.2-16.3 1.8-2.9 1.2-5.7 2.7-8.3 4.5"
fill="#FFFFFF"
></path>
<path
d="M810.2 606.5c-5.1-28.3-13.1-56-23.8-82.6-7.3-19.8-17.2-38.6-29.5-55.8-12.4-16.5-28.1-30.4-40.2-47.1-6.4-8.7-11.8-18.4-18.5-26.9-2.7-5.6-5.3-11.2-7.9-16.8-8-17.5-15.3-35.4-24.8-52-1.5-2.6-3.1-5.2-4.6-7.7-1.2-16-2.9-32-3.8-48 0.7-32.1-2-64.3-8.1-95.9-4.2-15.1-10.6-29.6-19-42.8-9.8-15.6-22.4-29.2-37.2-40.1-24.1-17.1-52.9-26.3-82.4-26.4-21.7-0.5-43.2 4.4-62.5 14.4-20.3 11.1-36.7 28.2-47 48.9-9.6 20.9-14.7 43.5-15 66.5-0.8 22.6 1.3 45 2.2 67.6 0.9 23.4 0.4 46.9 2.3 70.3 0.6 7.5 1.5 15 1.5 22.6 0 3.8-0.2 7.6-0.3 11.3l-0.3 0.8c-10.2 17.3-21.5 34-33.8 49.9-8.6 10.9-17.2 21.7-25.9 32.4-11.3 12.7-20.9 26.8-28.5 42-5.1 13.2-9.2 26.8-12.4 40.6l-0.3 1.1c-4.8 15.9-10.8 31.3-18 46.2-0.7 1.4-1.4 2.9-2 4.2-4.3 8.9-8.8 17.8-13.5 26.5l-5.4 10.1c-3.4 6.1-6.4 12.4-9 18.8-1.5 3.9-2.7 7.9-3.4 12-1.3 8.7-0.7 17.5 1.6 25.9 0.5 2.1 1.2 4.2 1.9 6.3 2.2 6.2 4.8 12.3 7.9 18.1 1.4 2.7 2.9 5.3 4.3 8l1.3 1.9c1.4 2.5 2.9 5 4.4 7.4l0.2 0.3c1.7 2.8 3.6 5.5 5.4 8.2l0.3 0.4c1.9 2.6 3.8 5.3 5.8 7.9 7.4 28.9 21 55.8 39.7 79-2.9 5.1-5.5 10.1-8.4 15.1-10.2 14.8-18.6 30.7-25.1 47.4-2.7 8.6-3.4 17.7-1.9 26.6 1.4 9 6 17.1 13 23 4.7 3.6 10.1 6.1 15.8 7.3 5.7 1.2 11.6 1.8 17.5 1.5 22.2-1.7 44.2-6.1 65.4-12.9 12.8-3.4 25.6-6.4 38.6-9 13.5-3.1 27.2-5 41-5.6 3.4 0.1 6.8-0.1 10.1-0.3 9.4 1 18.8 1.4 28.3 1l3.5-0.2c2.4 0.3 4.9 0.4 7.4 0.6 16.6 0.9 33.1 2.6 49.5 5.1 14.4 2.2 28.8 5 43 8.5 21.9 6.6 44.4 11 67.3 12.9 6 0.3 12-0.2 18-1.4 5.9-1.2 11.5-3.8 16.3-7.4 7-5.8 11.6-13.9 13.1-22.9 1.5-8.9 0.8-18-1.9-26.6-6.6-16.7-15.1-32.6-25.5-47.3-3.6-6.1-7-12.4-10.6-18.5 15.5-17.3 29.2-36.3 40.7-56.5 7 0.4 13.9-0.4 20.6-2.6 17.5-5.9 32.7-17.3 43.3-32.5 3.2-4.5 5.7-9.5 7.2-14.8 6.9-10.7 11.6-22.7 13.8-35.3 3.2-20.8 2.7-42.1-1.5-62.7h-0.2z m0 0"
fill="#020204"
></path>
<path
d="M425.6 323.2c-3.1 4-5.3 8.7-6.4 13.6-1.1 4.9-1.8 10-1.9 15 0.3 10.1-0.5 20.2-2.5 30.1-3.5 10.3-8.8 19.8-15.6 28.3-11.7 14.7-20.9 31.2-27.2 48.8-3.2 10.9-4.3 22.3-3.1 33.7-12.1 17.9-22.6 36.9-31.3 56.7-13.4 29.9-22 61.8-25.5 94.4-4.3 40.1 1.6 80.6 17 117.8 11.3 26.8 28.5 50.8 50.3 70.1 11.2 9.7 23.5 17.9 36.7 24.4 46.7 22.8 101.4 22.3 147.6-1.4 23.1-13.5 44.2-30.2 62.6-49.5 11.9-10.8 22.5-22.9 31.8-36.1 15.5-26.9 24.6-57.1 26.5-88.1 9.6-53.6 3.7-108.8-16.9-159.2-8.1-16.8-18.8-32.2-31.8-45.6a252.5 252.5 0 0 0-20.2-68c-7.2-15.5-15.9-30.3-22.6-46.2-2.7-6.5-5.1-13.1-8.1-19.4-2.9-6.4-6.9-12.3-11.8-17.3-5.3-4.9-11.6-8.6-18.5-10.7-6.9-2.2-14-3.4-21.2-3.6-14.4-0.7-28.9 1.1-43.1 0.6-11.5-0.5-22.8-2.5-34.3-1.8-5.7 0.3-11.4 1.4-16.7 3.5-5.4 2.1-10.1 5.5-13.8 10m4.6-125.1c-5.4 0.4-10.5 2.7-14.4 6.4-3.9 3.7-6.8 8.4-8.4 13.5-2.7 10.4-3.4 21.3-1.9 32 0.2 9.7 1.9 19.4 5.1 28.6 1.8 4.5 4.4 8.7 7.8 12.2 3.4 3.5 7.7 6.1 12.4 7.3 4.5 1.1 9.2 0.9 13.5-0.5 4.3-1.4 8.3-3.8 11.5-7 4.7-4.8 8.1-10.7 9.8-17.1 1.7-6.4 2.5-13.1 2.3-19.8 0-8.3-1.3-16.6-3.8-24.6s-6.8-15.3-12.6-21.4c-2.8-2.9-6-5.4-9.6-7.2-3.7-1.7-7.7-2.6-11.7-2.4m95 0c-8.6 5.6-15.2 13.8-18.9 23.4-3.8 12.4-3.2 25.6 1.5 37.7 3.9 12.7 11.7 23.8 22.2 31.8 5.4 3.8 11.6 6.2 18.2 7 6.6 0.8 13.2-0.3 19.1-3.3 7-3.9 12.6-10 15.9-17.3 3.2-7.4 5-15.3 5.2-23.3 0.7-10.2-0.6-20.4-3.8-30.1-3.5-10.6-10.3-19.7-19.5-25.9-4.7-3-9.9-5-15.4-5.8-5.5-0.8-11.1-0.2-16.3 1.8-2.9 1.2-5.7 2.7-8.3 4.5"
fill="#FFFFFF"
></path>
<path
d="M544.5 223.6c-3.2 0.2-6.2 1.2-8.9 2.9s-5 4-6.8 6.6c-3.4 5.3-5.3 11.5-5.4 17.9-0.3 4.7 0.4 9.5 1.9 14s4.3 8.5 7.9 11.5c3.8 3.1 8.4 4.9 13.3 5.2 4.9 0.2 9.7-1.1 13.7-3.9 3.2-2.3 5.8-5.2 7.6-8.7 1.8-3.4 2.9-7.2 3.4-11 1-6.8-0.2-13.8-3.2-19.9-3.1-6.2-8.4-10.9-14.8-13.4-2.8-1.1-5.7-1.5-8.7-1.4"
fill="#020204"
></path>
<path
d="M430.2 198.3c-5.4 0.4-10.5 2.7-14.4 6.4-3.9 3.7-6.8 8.4-8.4 13.5-2.7 10.4-3.4 21.3-1.9 32 0.2 9.7 1.9 19.4 5.1 28.6 1.8 4.6 4.4 8.7 7.8 12.2 3.4 3.5 7.7 6.1 12.4 7.3 4.5 1.1 9.2 0.9 13.5-0.5 4.3-1.4 8.3-3.8 11.5-7 4.7-4.8 8.1-10.7 9.8-17.1 1.7-6.4 2.5-13.1 2.3-19.8 0-8.3-1.3-16.6-3.8-24.6s-6.8-15.3-12.6-21.4c-2.8-2.9-6-5.4-9.6-7.2-3.7-1.7-7.7-2.6-11.7-2.4"
fill="#FFFFFF"
></path>
<path
d="M417.3 242.8c-1.3 6.7-1 13.7 1.1 20.2 1.6 4.3 4 8.2 7.2 11.5 2 2.2 4.3 4.1 7 5.4 2.7 1.4 5.7 1.8 8.7 1.1 2.7-0.7 5-2.3 6.7-4.5 1.7-2.2 2.9-4.7 3.7-7.3 2.3-7.8 2.1-16.1-0.4-23.9-1.6-5.7-4.7-10.9-9.1-14.8-2.1-1.8-4.7-3.2-7.4-3.9-2.8-0.7-5.7-0.5-8.4 0.7-2.8 1.4-5.1 3.7-6.5 6.5-1.4 2.8-2.3 5.8-2.7 8.9"
fill="#020204"
></path>
<path
d="M404.6 326.9c0.2 0.9 0.5 1.8 1 2.5 0.9 1.4 2 2.5 3.4 3.4 1.3 0.9 2.6 1.7 3.9 2.5 6.9 4.7 13 10.5 17.9 17.3 6 9.4 13.5 17.8 22 25 6.5 4.5 14.1 7.2 22 7.9 9.2 0.7 18.5-0.4 27.4-3.2 8.2-2.4 16.1-5.8 23.5-10.3 12.7-10.2 26.3-19.2 40.7-26.7 3.4-1.2 6.8-2.1 10-3.6 3.3-1.4 6.1-3.8 7.8-7 1.1-3.2 1.8-6.6 1.9-10 0.5-3.6 1.7-7.1 2.3-10.7 0.8-3.6 0.5-7.3-0.8-10.8-1.4-2.7-3.6-4.9-6.3-6.3-2.7-1.3-5.7-2.1-8.7-2.2-6.1 0.2-12.1 0.8-18 1.8-8 0.7-16-0.3-24 0-9.9 0.3-19.8 2.5-29.8 2.9-11.4 0.6-22.7-1.2-34.1-1.7-4.9-0.3-9.9-0.1-14.8 0.7-4.9 0.7-9.6 2.5-13.7 5.3-3.8 3-7.3 6.2-10.7 9.6-1.8 1.6-3.8 3-5.9 4.1-2.2 1.1-4.5 1.7-7 1.6-1.2-0.2-2.5-0.2-3.7 0-0.7 0.3-1.4 0.7-1.9 1.2l-1.5 1.8c-1 1.5-1.9 3.1-2.6 4.7"
fill="#D99A03"
></path>
<path
d="M429.7 301.7c-4 2.4-7.9 5-11.8 7.7-2.1 1.3-3.8 3-5.1 5.1-0.7 1.6-1 3.3-0.9 5 0.1 1.7 0.1 3.4 0 5.1-0.1 1.1-0.5 2.3-0.5 3.5 0 0.6 0 1.2 0.2 1.7 0.2 0.6 0.4 1.1 0.8 1.5 0.5 0.5 1.2 0.9 2 1.1 0.7 0.2 1.5 0.3 2.3 0.5 3.5 1 6.7 2.9 9.3 5.4 2.7 2.4 5.1 5.2 8 7.5 8 6 17.7 9.1 27.6 9 9.9-0.2 19.7-1.6 29.2-4.1 7.5-1.6 14.9-3.6 22.1-6.1 11.2-4.2 21.5-10.3 30.4-18.2 3.9-3.8 8-7.2 12.4-10.3 4-2.5 8.7-4.2 12.7-6.6 0.4-0.2 0.7-0.5 1.1-0.7 0.3-0.3 0.6-0.6 0.8-1 0.3-0.7 0.3-1.5 0-2.2-0.2-0.7-0.5-1.3-0.9-1.8-0.5-0.6-1.1-1.2-1.7-1.7-4.6-3.4-10.1-5.3-15.8-5.5-5.8-0.4-11.3 0-16.9-1.1-5.2-1.1-10.3-2.6-15.3-4.4-5.3-1.7-10.7-3-16.3-3.9-13-2.1-26.2-1.8-39.1 1-12.1 2.7-23.8 7.3-34.6 13.5"
fill="#604405"
></path>
<path
d="M428.4 288.1c-5.8 3.9-11 8.7-15.5 14.1-2.6 3-4.7 6.5-6.1 10.3-0.9 3-1.5 6.1-2 9.2-0.3 1.1-0.5 2.3-0.5 3.5 0 0.6 0.1 1.2 0.3 1.7 0.2 0.6 0.5 1.1 0.9 1.5 0.7 0.7 1.6 1.1 2.6 1.3 0.9 0.2 1.9 0.2 2.9 0.3 4.4 0.7 8.5 2.5 12.1 5.1 3.6 2.5 7 5.4 10.7 7.8 8.4 5 18 7.7 27.8 7.9 9.8 0.2 19.5-0.8 29-2.9 7.6-1.4 15.1-3.5 22.4-6.3 10.9-4.7 21.1-10.8 30.4-18.2 4.3-3.2 8.5-6.6 12.4-10.3 1.3-1.3 2.6-2.6 4-3.8 1.4-1.2 3-2.1 4.7-2.7 2.7-0.7 5.5-0.8 8.3-0.1 2 0.5 4.1 0.7 6.2 0.7 1.1 0 2.1-0.2 3.1-0.5 1-0.4 1.9-1 2.5-1.8 0.9-1.1 1.3-2.4 1.3-3.8s-0.4-2.7-1.1-3.9c-1.5-2.3-3.8-4.1-6.3-5.1-3.5-1.4-7.1-2.5-10.8-3.2-11.3-2.7-22.3-6.7-32.7-11.9-5.2-2.6-10.1-5.4-15.3-8.1-5.2-2.9-10.6-5.4-16.2-7.2-12.9-3.5-26.6-2.9-39.1 1.8-14 4.9-26.5 13.4-36.1 24.7"
fill="#F5BD0C"
></path>
<path
d="M493.5 272.2c0.7 2.3 4.3 1.9 6.4 2.9 2.1 1 3.3 2.9 5.3 3.1 2.1 0.2 5-0.7 5.3-2.6 0.4-2.6-3.4-4.2-5.8-5.1-3.2-1.5-6.8-1.6-10-0.2-0.7 0.3-1.4 1.2-1.2 1.9z m-34.4-1.2c-2.7-0.9-7.1 3.8-5.8 6.3 0.4 0.7 1.6 1.5 2.4 1.1 0.8-0.4 2.3-3.1 3.6-4 1-0.8 0.8-3.1-0.2-3.4z m0 0"
fill="#CD8907"
></path>
<path
d="M887.7 829.8c-2 5.2-4.9 10-8.5 14.3-8.4 9-18.6 16.2-29.8 21.2-19 8.8-37.5 18.6-55.5 29.3-11.7 7.8-22.6 16.6-32.7 26.4-8.3 8.7-17.2 16.7-26.6 24.2-9.8 7.2-21.1 12.1-33.1 14-14.7 1.9-29.6-0.4-43.1-6.5-9.7-3.7-18.1-10.2-24-18.8-5-9.2-7.3-19.5-6.8-29.9 0.6-18.3 2.8-36.5 6.6-54.5 2.6-15 5.2-30 6.8-45.1 2.8-27.6 3.1-55.3 1-82.9-0.5-4.6-0.5-9.3 0-13.9 0.6-9.4 8.5-16.6 18-16.5 4.3-0.1 8.6 0.3 12.8 1.1 10 1.2 20 2.9 29.8 5.2 6.1 1.6 12.2 3.8 18.3 5.5 10.2 3 21 3.9 31.6 2.9 11.1-2.6 22.4-4.3 33.8-5.3 4.7 0.2 9.4 1 13.8 2.4 4.6 1.3 8.9 3.6 12.4 6.9 2.5 2.7 4.5 5.8 5.8 9.2 1.9 5.1 3.1 10.4 3.5 15.8 0.2 4.8 0.6 9.6 1.2 14.4 1.7 7.7 5.4 14.9 10.6 20.9 5.3 5.8 11 11.2 17.2 16 5.9 5.2 12.1 10 18.6 14.4 3.1 2.1 6.2 4 9.1 6.3 3 2.2 5.5 5 7.4 8.2 2.4 4.4 3.2 9.5 2 14.4"
fill="#F5BD0C"
></path>
<path
d="M887.7 829.8c-2 5.2-4.9 10-8.5 14.3-8.4 9-18.6 16.2-29.8 21.2-19 8.8-37.5 18.6-55.5 29.3-11.7 7.8-22.6 16.6-32.7 26.4-8.3 8.7-17.2 16.7-26.6 24.2-9.8 7.2-21.1 12.1-33.1 14-14.7 1.9-29.6-0.4-43.1-6.5-9.7-3.7-18.1-10.2-24-18.8-5-9.2-7.3-19.5-6.8-29.9 0.6-18.3 2.8-36.5 6.6-54.5 2.6-15 5.2-30 6.8-45.1 2.8-27.6 3.1-55.3 1-82.9-0.5-4.6-0.5-9.3 0-13.9 0.6-9.4 8.5-16.6 18-16.5 4.3-0.1 8.6 0.3 12.8 1.1 10 1.2 20 2.9 29.8 5.2 6.1 1.6 12.2 3.8 18.3 5.5 10.2 3 21 3.9 31.6 2.9 11.1-2.6 22.4-4.3 33.8-5.3 4.7 0.2 9.4 1 13.8 2.4 4.6 1.3 8.9 3.6 12.4 6.9 2.5 2.7 4.5 5.8 5.8 9.2 1.9 5.1 3.1 10.4 3.5 15.8 0.2 4.8 0.6 9.6 1.2 14.4 1.7 7.7 5.4 14.9 10.6 20.9 5.3 5.8 11 11.2 17.2 16 5.9 5.2 12.1 10 18.6 14.4 3.1 2.1 6.2 4 9.1 6.3 3 2.2 5.5 5 7.4 8.2 2.4 4.4 3.2 9.5 2 14.4M259.4 676.3c4.9-1.9 10.2-2.4 15.4-1.4 5.2 1 10.1 3.1 14.4 6.1 8.3 6.3 15.5 14.1 21.2 22.8 14.1 19.4 27.6 39.2 39.9 59.8 10 16.7 19.1 33.9 30.6 49.6 7.5 10.2 16 19.7 23.6 29.9 7.9 10 13.9 21.4 17.6 33.5 4.4 16.1 2.6 33.2-4.9 48.1-5.4 10.4-13.5 19.1-23.4 25.1-10 6-21.5 9-33.2 8.7-18.4-2.5-36.2-8.1-52.6-16.6-34.9-13.9-72.8-18.3-108.8-29.1-11.1-3.3-21.9-7.3-33.1-10.3-5-1.2-9.9-2.7-14.7-4.7-4.7-2-8.8-5.4-11.5-9.7-2-3.5-3-7.5-2.9-11.5 0.1-4 0.9-7.9 2.3-11.5 2.7-7.5 7.1-14.2 10-21.6 4.4-12.2 6.1-25.3 5-38.2-0.6-12.9-2.9-25.8-3.6-38.7-0.6-5.8-0.4-11.6 0.6-17.3 1.5-11.4 10.4-20.5 21.9-22.2 5.3-0.9 10.6-1.3 15.9-1 5.3 0.3 10.7 0.3 16 0 5.3-0.3 10.6-1.8 15.3-4.3 4.3-2.6 8.1-6.2 11-10.4 2.9-4.2 5.5-8.5 7.9-13 2.4-4.5 5.1-8.7 8.3-12.7 3-4.1 7.1-7.2 11.8-9.4"
fill="#F5BD0C"
></path>
<path
d="M259.4 676.4c4.9-1.9 10.2-2.4 15.4-1.4 5.2 1 10.1 3.1 14.4 6.1 8.3 6.3 15.5 14.1 21.2 22.8 14.1 19.4 27.6 39.2 39.9 59.8 10 16.7 19.1 33.9 30.6 49.6 7.5 10.2 16 19.7 23.6 29.9 7.9 10 13.9 21.4 17.6 33.5 4.4 16.1 2.6 33.2-4.9 48.1-5.4 10.4-13.5 19.1-23.4 25.1-10 6-21.5 9-33.2 8.7-18.4-2.5-36.2-8.1-52.6-16.6-34.9-13.9-72.8-18.3-108.8-29.1-11.1-3.3-21.9-7.3-33.1-10.3-5-1.2-9.9-2.7-14.7-4.7-4.7-2-8.8-5.4-11.5-9.7-2-3.5-3-7.5-2.9-11.5 0.1-4 0.9-7.9 2.3-11.5 2.7-7.5 7.1-14.2 10-21.6 4.4-12.2 6.1-25.3 5-38.2-0.6-12.9-2.9-25.7-3.6-38.7-0.6-5.8-0.4-11.6 0.6-17.3 1.5-11.4 10.4-20.5 21.9-22.2 5.3-0.9 10.6-1.3 15.9-1 5.3 0.3 10.7 0.3 16 0 5.3-0.3 10.6-1.8 15.3-4.3 4.3-2.6 8.1-6.2 11-10.4 2.9-4.2 5.5-8.5 7.9-13 2.4-4.5 5.1-8.7 8.3-12.7 3-4.1 7.1-7.3 11.8-9.4"
fill="#F5BD0C"
></path>
<path
d="M267.1 684.8c4.4-1.7 9.3-2 13.9-0.9s8.9 3.2 12.6 6.2c7.1 6.2 13.1 13.6 17.6 21.9 12 19.4 23.7 39 34.6 59 7.9 15.3 16.8 30.1 26.6 44.2 6.8 9.2 14.6 17.6 21.6 26.6 7.3 8.9 12.8 19 16.2 29.9 4 14.3 2.3 29.6-4.5 42.9-5 9.4-12.5 17.3-21.7 22.6-9.2 5.4-19.8 8-30.4 7.5-16.7-2.6-32.9-7.6-48.2-14.9-30.4-11.1-63.5-12.5-94.7-21.2-11.2-3-22.1-7.1-33.4-9.9-5-1.1-10-2.5-14.8-4.3-4.8-1.8-9-5.2-11.8-9.5-1.8-3.4-2.7-7.2-2.5-11 0.2-3.8 1-7.6 2.4-11.2 2.7-7.1 7-13.6 9.7-20.7 3.8-11 5.1-22.6 3.9-34.2-0.8-11.5-2.9-22.9-3.5-34.5-0.4-5.1-0.2-10.3 0.7-15.4 0.9-5.1 3.3-9.8 6.9-13.6 4.2-3.8 9.4-6.3 15-7 5.6-0.7 11.2-0.7 16.7 0 5.6 0.7 11.2 0.9 16.8 0.8 11 0 21-6.4 25.7-16.4 2.3-4.5 4.3-9.2 5.9-13.9 1.7-4.8 4-9.3 6.7-13.6 2.8-4.3 6.8-7.7 11.5-9.7"
fill="#F5BD0C"
></path>
</svg>
<h3 class="text-xl font-semibold tracking-tight ml-4 min-w-fit">
Linux 客户端发布
</h3>
<div
class="tooltip flex items-center text-stone-300"
data-tip="需服务器安装有gitgogzipdpkg-devcreaterepo/createrepo-c"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.35"
stroke-linecap="round"
stroke-linejoin="round"
class="ml-1"
>
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
</header>
<div
class="rounded-md border border-stone-200 mt-4 mb-3 gap-2 max-w-sm bg-stone-50 p-2"
>
<div class="flex flex-col justify-start">
<div class="w-full text-left font-bold max-w-xl text-gray-500">
当前源码仓库
</div>
<div class="w-full text-left max-w-xl break-all text-gray-500">
{{
ClientVersion.linux.url && ClientVersion.linux.url != ""
? ClientVersion.linux.url
: "未设置"
}}
</div>
<div class="w-full text-left font-bold max-w-xl text-gray-500">当前版本</div>
<div class="w-full text-left max-w-xl text-gray-500">
{{
ClientVersion.linux.version && ClientVersion.linux.version != ""
? ClientVersion.linux.version
: "尚未构建本"
}}
</div>
<div class="w-full text-left font-bold max-w-xl text-gray-500">
最近一次构建情况
</div>
<div class="w-full text-left max-w-xl break-all text-gray-500">
{{
ClientVersion.linux.buildst && ClientVersion.linux.buildst != ""
? ClientVersion.linux.buildst
: "尚未进行"
}}
</div>
</div>
</div>
<div class="flex w-full max-w-sm">
<p class="text-gray-600 max-w-sm min-w-fit">仓库地址</p>
<div class="w-full flex justify-end">
<button
:disabled="
/*
(ClientVersion.linux.buildst &&
ClientVersion.linux.buildst == '正在进行') ||
*/
!isValidURL(wantLinuxRepo)
"
@click="publishLinux"
class="btn border-0 bg-blue-500 hover:bg-blue-900 disabled:bg-blue-500/60 text-white disabled:text-white/60 h-7 min-h-fit"
>
构建
</button>
</div>
</div>
<div
:class="{
'border-red-500 hover:border-red-700':
wantLinuxRepo == '' || !isValidURL(wantLinuxRepo),
'border-stone-200 hover:border-stone-400':
wantLinuxRepo != '' && isValidURL(wantLinuxRepo),
}"
class="mt-1 max-w-sm flex border rounded-md relative overflow-hidden min-w-0"
>
<input
class="outline-none py-2 px-3 w-full h-full font-mono text-sm text-ellipsis"
v-model="wantLinuxRepo"
/>
</div>
<div class="flex w-full max-w-sm">
<p class="text-gray-600 max-w-sm min-w-fit">
用户名:口令 (选填, <strong>clear</strong> 清除)
</p>
</div>
<div
class="mt-1 max-w-sm flex border border-stone-200 hover:border-stone-400 rounded-md relative overflow-hidden min-w-0"
>
<input
class="outline-none py-2 px-3 w-full h-full font-mono text-sm text-ellipsis"
v-model="wantLinuxRepoCred"
/>
</div>
</div>
<!---->
<div>
<header class="max-w-sm flex mt-4">
<svg
+6
View File
@@ -32,6 +32,12 @@ export default defineConfig({
main: resolve(__dirname, 'index.html'),
},
output:{
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
},
// https://github.com/rollup/rollup/blob/master/src/utils/sanitizeFileName.ts
sanitizeFileName(fileName) {
const match = DRIVE_LETTER_REGEX.exec(fileName);
+1 -27
View File
@@ -9,7 +9,7 @@
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="shortcut icon" href="/img/favicon.ico" type="img/x-icon">
<link rel="apple-touch-icon" href="/img/mlogo.png">
<title>蜃境 - 控制台</title>
<title>蜃境 - 客户端下载</title>
</head>
<body>
@@ -17,32 +17,6 @@
<script type="module" src="/src/downloads.js"></script>
<script type="application/json" id="download-details">
{{.DownloadDetails}}
/*
{
"macos": {
"supportedVersions": "Requires macOS High Sierra 10.13 or later.",
"downloadLink": "https://apps.apple.com/ca/app/tailscale/id1475387142?mt=12",
"instructions": "\u003col\u003e\n\u003cli\u003eDownload and open the Tailscale macOS app from the App Store, or \u003ca href=\"/kb/1065/macos-variants/#automating-app-store-installs\"\u003eusing the \u003ccode\u003emas\u003c/code\u003e CLI tool\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eAccept any prompts to install VPN configurations that may appear\u003c/li\u003e\n\u003cli\u003eClick \u003cstrong\u003eLog in\u003c/strong\u003e from the Tailscale menu bar item and authenticate in your browser\u003c/li\u003e\n\u003cli\u003eSign up with your team email address\u003c/li\u003e\n\u003c/ol\u003e\n"
},
"ios": {
"supportedVersions": "Requires iOS 15 or later.",
"downloadLink": "https://apps.apple.com/us/app/tailscale/id1470499037?ls=1",
"qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAQMAAAD58POIAAAABlBMVEX///8AAABVwtN+AAABeUlEQVR42tzUMY6zMBQE4EEu3MEFrPgaFEhciXRbBVKlC1eylMLXcPQu4O1cWMwvErR/aW/KdYP0NTyPRw9/+2gyvD5ekbEOgAC04wmyYKoDm4Tu0pNqzb+A3IL+V7AppqeTzwGQlRHW/79LCUi5D2d/6uUnsQIAUMxnxxR+XqIA2jI0j29iFOZKkISO334bJb4vV4TXT7mNNpnOLnWQZ3NRdzx97lgHmjdZ8+zRhzlMHwK0Wh/33lIWiXXAReIwp6djtEsVIGjTuQvouL4yLYNWN1mGLqE3x6RFgPkyM69uG9XxDEXQe6q5840j36OXQRHtuGk6krWw5Pmx6W2fFB8CaZoHPZMsZqoDe+NeYbqwb5AqgFb34eyezkx5qoSv0KrYoydRB3v9I87p6UNn6mBfnzPXdBplPTpWBEDi0NAydO9KlcEmufLqbCKPgD6CbWj1CfkYvQriMLNJjAF1AISza9E4teZKIOXqLiPGPKmlCv7O+RcAAP//TMjcklfrHLYAAAAASUVORK5CYII=",
"instructions": "\u003col\u003e\n\u003cli\u003eDownload and open the Tailscale iOS app\u003c/li\u003e\n\u003cli\u003eAccept the prompts to install a VPN configuration and allow push notifications\u003c/li\u003e\n\u003cli\u003eSign up using your team\u0026rsquo;s email address\u003c/li\u003e\n\u003c/ol\u003e\n"
},
"windows": {
"supportedVersions": "Requires Windows 7 SP1 or later.",
"downloadLink": "https://pkgs.tailscale.com/stable/tailscale-setup-1.40.0.exe",
"instructions": "\u003col\u003e\n\u003cli\u003eDownload and run the Windows installer\u003c/li\u003e\n\u003cli\u003eClick on \u003cstrong\u003eLog in\u003c/strong\u003e from the Tailscale icon now in your system tray and authenticate in your browser\u003c/li\u003e\n\u003cli\u003eSign up with your team email address\u003c/li\u003e\n\u003c/ol\u003e\n"
},
"android": {
"supportedVersions": "Requires Android 6 or later.",
"downloadLink": "https://play.google.com/store/apps/details?id=com.tailscale.ipn",
"qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAQMAAAD58POIAAAABlBMVEX///8AAABVwtN+AAABwklEQVR42tzVsY6bQBAG4H+FlG2spXWBtM9w3V6TfSVWaU8G5NaCVxo3t935FZC2SIvlZiMhJrJ9chonTMpkOr4K5p8Z8F9VyWzRdDHPm4azCAy0LVr4OKOGk4GP4D5E2DYsvwNbBWb3V6At9y6nWQzQelaTI24fb7oCJfM29SG6dHj0YwUAWASONL49+rwC5qsfR1N7jbf6NT+D8kxjGhYQNkaRCNQpYmw6clXZXZ8FUJ5Ip67Lng/4IgO1aKRppz1fOGYRwGdOPDlY5h8yUIvWlWmyS62KJAOm7+nMlFHyMT8D8xL12HDEDOOlQKh2tSfUn0GtgvrQ2zRMzhXcHWVQkkPqjfPFpX8lEVw/v5iaSMUwkBNBeSRbmcC+2txG/Ql8+NFOO3DaL5ABFI3VLmTmS3ffhlUwL9HaSUXm/fmW3Drcl6a5hnM+ZhGoE7Mdzsy2xb1jq2A8WdvWiMWejzKA5xGqi9kO/O6eAmCrMEQ/b1TMIrid4LBowia8OxEY6O1o4FxxUCQEHzHvFLliuOckgm0Vrv+G4jMoCdjKNNcZC/wcoHVaaq3nb3ybqXW4neChd5rb8Osm/xH+2foZAAD//9x6p846avjtAAAAAElFTkSuQmCC",
"instructions": "\u003col\u003e\n\u003cli\u003eDownload and the Tailscale app from the Play Store\u003c/li\u003e\n\u003cli\u003eAccept the prompts to install a VPN configuration\u003c/li\u003e\n\u003cli\u003eSign up with your team\u0026rsquo;s email address\u003c/li\u003e\n\u003c/ol\u003e\n"
}
}
*/
</script>
</body>
+156 -1
View File
@@ -4,5 +4,160 @@ const props = defineProps({
});
</script>
<template>
<div class="text-center">暂未提供Linux版</div>
<div v-if="downloadDetails.linux.primary == ''" class="text-center">
<code class="rounded-md border border-stone-200 gap-2 max-w-sm bg-stone-50 p-2">
暂未提供Linux版
</code>
</div>
<div
v-if="downloadDetails.linux.primary != ''"
class="pt-2 pb-4 border-b border-gray-200 max-w-xl mx-auto"
>
<div class="text-center">
<code class="rounded-md border border-stone-200 gap-2 max-w-sm bg-stone-50 p-2">
当前最新版本 {{ downloadDetails.linux.primary.split("-")[0] }}
</code>
</div>
</div>
<div v-if="downloadDetails.linux.primary != ''" class="mx-auto max-w-xl">
<header class="my-4">
<h2 class="text-xl font-medium">使用Repo安装 - 适用于DEB及RPM类型包管理器</h2>
</header>
<div class="Markdown mb-4">
<ol>
<li>添加软件源</li>
<p class="pb-2">DEB环境即apt管理</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-scroll whitespace-nowrap"
>
curl -fsSL https://{{
downloadDetails.linux.secondary
}}/download/deb/mirage.list | sudo tee /etc/apt/sources.list.d/mirage.list
</div>
<p class="pb-2">RPM环境即yum/dnf管理</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-scroll whitespace-nowrap"
>
sudo yum-config-manager --add-repo https://{{
downloadDetails.linux.secondary
}}/download/rpm/mirage.repo
</div>
<p class="pb-2"></p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-scroll whitespace-nowrap"
>
sudo dnf config-manager --add-repo https://{{
downloadDetails.linux.secondary
}}/download/rpm/mirage.repo
</div>
<li>进行蜃境客户端安装</li>
<p class="pb-2">DEB环境即apt管理</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
sudo apt update && sudo apt install mirage
</div>
<p class="pb-2">RPM环境即yum/dnf管理</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
sudo yum install mirage
</div>
<p class="pb-2"></p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
sudo dnf install mirage
</div>
<p class="pb-2">使用yum/dnf的情况下安装完成后还需要添加并启用服务</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
sudo systemctl enable --now tailscaled
</div>
<li>接下来您就可以使用蜃境Linux版本命令了例如使用下面命令登录接入</li>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
sudo mirage up
</div>
</ol>
</div>
</div>
<div v-if="downloadDetails.linux.primary != ''" class="mx-auto max-w-xl">
<header class="my-4">
<h2 class="text-xl font-medium">使用二进制发行包 - 适用于其他类型Linux环境</h2>
</header>
<div class="Markdown mb-4">
<ol>
<li>下载二进制发行包</li>
<div class="pt-2">i386架构</div>
<a
:href="
'https://' +
downloadDetails.linux.secondary +
'/download/tgz/mirage_' +
downloadDetails.linux.primary.split('-')[0] +
'_386.tgz'
"
>mirage_{{ downloadDetails.linux.primary.split("-")[0] }}_386.tgz</a
>
<div>amd64架构</div>
<a
:href="
'https://' +
downloadDetails.linux.secondary +
'/download/tgz/mirage_' +
downloadDetails.linux.primary.split('-')[0] +
'_amd64.tgz'
"
>mirage_{{ downloadDetails.linux.primary.split("-")[0] }}_amd64.tgz</a
>
<div>arm架构</div>
<a
:href="
'https://' +
downloadDetails.linux.secondary +
'/download/tgz/mirage_' +
downloadDetails.linux.primary.split('-')[0] +
'_arm.tgz'
"
>mirage_{{ downloadDetails.linux.primary.split("-")[0] }}_arm.tgz</a
>
<div>arm64架构</div>
<a
class="pb-2"
:href="
'https://' +
downloadDetails.linux.secondary +
'/download/tgz/mirage_' +
downloadDetails.linux.primary.split('-')[0] +
'_arm64.tgz'
"
>mirage_{{ downloadDetails.linux.primary.split("-")[0] }}_arm64.tgz</a
>
<li>解压缩发行包</li>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
tar xvf 发行包名称
</div>
<p class="pb-2">注意openwrt之上需要使用下面命令</p>
<div
class="rounded-md border border-stone-200 gap-2 bg-stone-50 p-2 overflow-x-auto whitespace-nowrap"
>
tar x -zvf 发行包名称
</div>
<li>使用</li>
<div class="pb-2">
加压缩之后可以根据个人情况选择性将 miragemiraged 复制/移动到
<div class="rounded-md border border-stone-200 bg-stone-50 px-1 inline-block">
/usr/sbin
</div>
之类的路径并可使用解压缩出的 systemd
目录配置服务以使其可成为服务方便开机运行和管理
</div>
</ol>
</div>
</div>
</template>
+10
View File
@@ -18,6 +18,7 @@ import (
webauthn "github.com/go-webauthn/webauthn/webauthn"
"github.com/gorilla/mux"
"github.com/patrickmn/go-cache"
"github.com/robfig/cron/v3"
"github.com/rs/zerolog/log"
"go4.org/netipx"
"golang.org/x/sync/errgroup"
@@ -39,6 +40,8 @@ type Cockpit struct {
author *webauthn.WebAuthn
superAdmin *MirageSuperAdmin
authCache *cache.Cache
BuildCron *cron.Cron
}
type CtrlMsg struct {
@@ -81,11 +84,14 @@ func NewCockpit(sysAddr string, ctrlChn, msgChn chan CtrlMsg, db *gorm.DB) (*Coc
serviceState: false,
CtrlChn: ctrlChn,
MsgChn: msgChn,
BuildCron: cron.New(),
}
cockpit.authCache = cache.New(0, 0)
// cockpit.superAdmin, cockpit.hasAdmin = cockpit.GetAdmin()
cockpit.superAdmin = cockpit.GetSuperAdmin()
cockpit.BuildCron.AddFunc("0 0 * * *", cockpit.BuildLinuxClient)
return cockpit, nil
}
@@ -172,6 +178,7 @@ func (c *Cockpit) createRouter() *mux.Router {
cockpit_router.HandleFunc("/api/service/state", c.GetServiceState).Methods(http.MethodGet)
cockpit_router.HandleFunc("/api/setting/general", c.GetSettingGeneral).Methods(http.MethodGet)
cockpit_router.HandleFunc("/api/tenants", c.CAPIGetTenant).Methods(http.MethodGet)
cockpit_router.HandleFunc("/api/publish", c.GetPublishInfo).Methods(http.MethodGet)
cockpit_router.HandleFunc("/api/derp/query", c.CAPIQueryDERP).Methods(http.MethodGet)
cockpit_router.PathPrefix("/api/derp/{id}").HandlerFunc(c.CAPIDelNaviNode).Methods(http.MethodDelete)
@@ -972,6 +979,9 @@ func (c *Cockpit) Run() error {
errorGroup.Go(func() error { return httpServer.Serve(httpListener) })
// 启动buildCron
c.BuildCron.Start()
msgFunc := func(c *Cockpit) {
for {
msg := <-c.MsgChn
+34 -1
View File
@@ -102,7 +102,7 @@ func (c *Cockpit) CAPIPublishClient(
reqData.Url = "https://" + sysCfg.ServerURL + "/download/" + fileName
}
if reqData.Url == "" || reqData.Version == "" {
if reqData.Url == "" || reqData.Version == "" && osType != "linux" {
c.doAPIResponse(w, "客户端发布请求处理失败", nil)
return
}
@@ -118,6 +118,15 @@ func (c *Cockpit) CAPIPublishClient(
sysCfg.ClientVersion.NaviAMD64 = reqData.Version
case "navi_aarch64":
sysCfg.ClientVersion.NaviAARCH64 = reqData.Version
case "linux":
sysCfg.ClientVersion.Linux.Url = reqData.Url
sysCfg.ClientVersion.Linux.BuildState = "正在进行"
if reqData.Version != "" {
sysCfg.ClientVersion.Linux.RepoCred = reqData.Version
if reqData.Version == "clear" {
sysCfg.ClientVersion.Linux.RepoCred = ""
}
}
default:
c.doAPIResponse(w, "未支持的客户端类型", nil)
return
@@ -127,6 +136,10 @@ func (c *Cockpit) CAPIPublishClient(
return
}
if osType == "linux" {
go c.BuildLinuxClient()
}
if c.serviceState {
newCfg, err := c.GetSysCfg().toSrvConfig()
if err != nil {
@@ -141,3 +154,23 @@ func (c *Cockpit) CAPIPublishClient(
c.GetSettingGeneral(w, r)
}
type PublishInfoData struct {
UploadURL string `json:"upload_url"`
ClientVersion ClientVersionInfo `json:"client_version"`
}
func (c *Cockpit) GetPublishInfo(
w http.ResponseWriter,
r *http.Request,
) {
sysCfg := c.GetSysCfg()
if sysCfg == nil {
c.doAPIResponse(w, "获取系统配置失败", nil)
return
}
c.doAPIResponse(w, "", PublishInfoData{
UploadURL: "https://" + sysCfg.ServerURL + "/cockpit/api/publish",
ClientVersion: sysCfg.ClientVersion,
})
}
+295
View File
@@ -0,0 +1,295 @@
package controller
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
"errors"
"github.com/rs/zerolog/log"
)
func (c *Cockpit) BuildLinuxClient() {
sysCfg := c.GetSysCfg()
if sysCfg == nil || sysCfg.ClientVersion.Linux.Url == "" {
return
} // 未设置Linux客户端源码仓库,无需构建
repoURL := sysCfg.ClientVersion.Linux.Url
if sysCfg.ClientVersion.Linux.RepoCred != "" {
repoURL = strings.Replace(repoURL, "://", "://"+sysCfg.ClientVersion.Linux.RepoCred+"@", 1)
}
var repoHash string
if _, err := os.Stat("src/linux"); err != nil && !os.IsNotExist(err) {
log.Error().Caller().Err(err).Msg("Linux 源码文件夹检查失败")
c.markLinuxLastBuildFail()
return
} else if err == nil {
// 获取本地Hash
cmd := exec.Command("git", "ls-remote", "src/linux")
var out bytes.Buffer
cmd.Stdout = &out
var stderr bytes.Buffer
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
log.Error().Caller().Msg("检查本地Linux源码仓库Hash出错" + stderr.String())
c.markLinuxLastBuildFail()
return
}
lines := strings.Split(out.String(), "\n")
localHash := lines[0][:39]
// 获取远程Hash
cmd = exec.Command("git", "ls-remote", repoURL)
cmd.Stdout = &out
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
log.Error().Caller().Msg("检查远程Linux源码仓库Hash出错" + stderr.String())
c.markLinuxLastBuildFail()
return
}
lines = strings.Split(out.String(), "\n")
repoHash = lines[0][:39]
if localHash != repoHash {
err = os.RemoveAll("src/linux")
if err != nil {
log.Error().Caller().Err(err).Msg("Linux源码文件夹删除失败")
c.markLinuxLastBuildFail()
return
}
err = gitCloneRepo(repoURL, "src/linux")
if err != nil {
log.Warn().Caller().Err(err).Msg("Linux源码仓库更新失败")
c.markLinuxLastBuildFail()
return
}
} else if sysCfg.ClientVersion.Linux.BuildState == "成功" {
log.Info().Caller().Msg("已成功构建过同样Hash版本,无需重复构建")
return
}
} else if os.IsNotExist(err) {
if _, err := os.Stat("src"); os.IsNotExist(err) {
err = os.Mkdir("src", os.ModePerm)
if err != nil {
log.Error().Caller().Err(err).Msg("源码文件夹创建失败")
c.markLinuxLastBuildFail()
return
}
} else if err != nil {
log.Error().Caller().Err(err).Msg("源码文件夹检查失败")
c.markLinuxLastBuildFail()
return
}
err = gitCloneRepo(repoURL, "src/linux")
if err != nil {
log.Error().Caller().Err(err).Msg("Linux源码仓库更新失败")
c.markLinuxLastBuildFail()
return
}
}
// 以上保证需要构建的代码仓库已放到本地src/linux
cmd := exec.Command("go", "run", "cmd/dist/dist.go", "build", "all")
cmd.Dir = "src/linux"
var out bytes.Buffer
cmd.Stdout = &out
var stderr bytes.Buffer
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Error().Caller().Msg("Linux客户端构建失败:" + stderr.String())
c.markLinuxLastBuildFail()
return
}
lines := strings.Split(out.String(), "\n")
shortVersion := strings.Split(lines[len(lines)-3], "=")[1]
log.Info().Caller().Msg("Linux客户端构建成功! 版本号:" + shortVersion)
// 检查发布路径情况
_, err = os.Stat("download")
if err != nil {
err = os.Mkdir("download", os.ModePerm)
if err != nil {
log.Error().Caller().Err(err).Msg("下载文件夹创建失败")
c.markLinuxLastBuildFail()
return
}
}
if err = ReleaseDeb(sysCfg.ServerURL); err != nil {
log.Error().Caller().Err(err).Msg("deb发布失败")
c.markLinuxLastBuildFail()
return
}
if err = ReleaseRpm(sysCfg.ServerURL); err != nil {
log.Error().Caller().Err(err).Msg("rpm发布失败")
c.markLinuxLastBuildFail()
return
}
if err = ReleaseTgz(); err != nil {
log.Error().Caller().Err(err).Msg("tgz发布失败")
c.markLinuxLastBuildFail()
return
}
// 记录构建成功,更新版本信息
sysCfg = c.GetSysCfg()
if sysCfg == nil {
log.Error().Caller().Msg("构建完成,但获取系统配置失败")
c.markLinuxLastBuildFail()
return
}
sysCfg.ClientVersion.Linux.BuildState = "成功"
sysCfg.ClientVersion.Linux.Version = shortVersion
sysCfg.ClientVersion.Linux.Hash = repoHash
if err := c.db.Model(&sysCfg).Update("client_version", sysCfg.ClientVersion).Error; err != nil {
log.Error().Caller().Err(err).Msg("记录Linux客户端最近一次构建成功信息未能完成!")
}
log.Info().Msg("Linux客户端构建成功!")
}
func gitCloneRepo(repo, target string) error {
cmd := exec.Command("git", "clone", "--recurse-submodules", repo, target)
var stderr bytes.Buffer
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
return nil
}
func ReleaseDeb(srvURL string) error {
_, err := os.Stat("download/deb")
if err != nil {
err = os.Mkdir("download/deb", os.ModePerm)
if err != nil {
log.Error().Caller().Err(err).Msg("deb发布文件夹创建失败")
return err
}
}
cmd := exec.Command("sh", "-c", "mv src/linux/dist/*.deb download/deb/")
var stderr bytes.Buffer
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
// 执行packages构建
cmd = exec.Command("sh", "-c", "dpkg-scanpackages deb /dev/null | gzip -9c > deb/Packages.gz")
cmd.Dir = "download"
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
// 创建list文件
file, err := os.Create("download/deb/mirage.list")
if err != nil {
return err
}
defer file.Close()
debList :=
`# Mirage Repo for deb format
deb https://%s/download deb`
_, err = fmt.Fprintf(file, debList, srvURL)
if err != nil {
return err
}
return nil
}
func ReleaseRpm(srvURL string) error {
_, err := os.Stat("download/rpm")
if err != nil {
err = os.Mkdir("download/rpm", os.ModePerm)
if err != nil {
log.Error().Caller().Err(err).Msg("rpm发布文件夹创建失败")
return err
}
}
cmd := exec.Command("sh", "-c", "mv src/linux/dist/*.rpm download/rpm/")
var stderr bytes.Buffer
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
// 执行packages构建 - 默认在ubuntu下执行,使用createrepo_c
cmd = exec.Command("lsb_release", "-d")
output, _ := cmd.CombinedOutput()
if strings.Contains(string(output), "Ubuntu") {
cmd = exec.Command("createrepo_c", "rpm", "--update")
} else {
cmd = exec.Command("createrepo", "rpm", "--update")
}
cmd.Dir = "download"
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
// 创建repo文件
file, err := os.Create("download/rpm/mirage.repo")
if err != nil {
return err
}
defer file.Close()
rpmRepo :=
`[mirage]
name=Mirage
baseurl=https://%s/download/rpm
enabled=1
type=rpm
repo_gpgcheck=0
gpgcheck=0`
_, err = fmt.Fprintf(file, rpmRepo, srvURL)
if err != nil {
return err
}
return nil
}
func ReleaseTgz() error {
_, err := os.Stat("download/tgz")
if err != nil {
err = os.Mkdir("download/tgz", os.ModePerm)
if err != nil {
log.Error().Caller().Err(err).Msg("tgz发布文件夹创建失败")
return err
}
}
cmd := exec.Command("sh", "-c", "mv src/linux/dist/*.tgz download/tgz/")
var stderr bytes.Buffer
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
return nil
}
func (c *Cockpit) markLinuxLastBuildFail() {
sysCfg := c.GetSysCfg()
if sysCfg == nil {
return
}
sysCfg.ClientVersion.Linux.BuildState = "失败"
if err := c.db.Model(&sysCfg).Update("client_version", sysCfg.ClientVersion).Error; err != nil {
log.Error().Caller().Err(err).Msg("记录Linux客户端最近一次构建失败信息未能完成!")
return
}
}
+17 -10
View File
@@ -260,16 +260,15 @@ func (ghCfg AppleCfg) Value() (driver.Value, error) {
}
type ClientVersionInfo struct {
NaviAMD64 string `json:"naviAmd64"`
NaviAARCH64 string `json:"naviAarch64"`
Win ClientVer `json:"win"`
MacStore ClientVer `json:"mac_store"`
MacTestFlight ClientVer `json:"mac_test"`
LinuxAMD64 ClientVer `json:"linuxAmd64"`
LinuxAARCH64 ClientVer `json:"linuxAarch64"`
Android ClientVer `json:"android"`
IOSStore ClientVer `json:"ios_store"`
IOSTestFlight ClientVer `json:"ios_test"`
NaviAMD64 string `json:"naviAmd64"`
NaviAARCH64 string `json:"naviAarch64"`
Win ClientVer `json:"win"`
MacStore ClientVer `json:"mac_store"`
MacTestFlight ClientVer `json:"mac_test"`
Linux LinuxBuildInfo `json:"linux"`
Android ClientVer `json:"android"`
IOSStore ClientVer `json:"ios_store"`
IOSTestFlight ClientVer `json:"ios_test"`
}
func (c *ClientVersionInfo) Scan(value interface{}) error {
@@ -292,3 +291,11 @@ type ClientVer struct {
Version string `json:"version"`
Url string `json:"url"`
}
type LinuxBuildInfo struct {
Version string `json:"version"` // 当前版本号
Url string `json:"url"` // 当前仓库地址
RepoCred string `json:"repo_cred"` // 当前仓库凭据
Hash string `json:"hash"` // 当前发布hash
BuildState string `json:"buildst"` // 最近一次构建状态 - 尚未进行、正在进行、成功、失败
}
+2 -2
View File
@@ -56,8 +56,8 @@ func (m *Mirage) sendDownloadsPage(
Primary: clientsInfo.Win.Url,
},
Linux: DownloadLinks{
Primary: clientsInfo.LinuxAMD64.Url,
Secondary: clientsInfo.LinuxAARCH64.Url,
Primary: clientsInfo.Linux.Version,
Secondary: m.cfg.ServerURL,
},
Android: DownloadLinks{
Primary: clientsInfo.Android.Url,
+5 -4
View File
@@ -22,6 +22,7 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/sftp v1.13.5
github.com/puzpuzpuz/xsync/v2 v2.4.0
github.com/robfig/cron/v3 v3.0.1
github.com/rs/zerolog v1.29.1
github.com/samber/lo v1.38.1
github.com/sirupsen/logrus v1.9.0
@@ -29,8 +30,8 @@ require (
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35
golang.org/x/crypto v0.8.0
golang.org/x/net v0.9.0
golang.org/x/oauth2 v0.7.0
golang.org/x/net v0.10.0
golang.org/x/oauth2 v0.8.0
golang.org/x/sync v0.2.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/gorm v1.25.0
@@ -57,14 +58,14 @@ require (
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
github.com/aliyun/credentials-go v1.2.7 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/beevik/etree v1.1.3 // indirect
github.com/beevik/etree v1.1.4 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/clbanning/mxj/v2 v2.5.7 // indirect
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/dexidp/dex/api/v2 v2.0.0-00010101000000-000000000000 // indirect
github.com/dexidp/dex/api/v2 v2.1.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/elastic/elastic-transport-go/v8 v8.2.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
+9 -7
View File
@@ -115,8 +115,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beevik/etree v1.1.3 h1:RM50lzyrX4BhfIR7LI7LKq2HQtcksDWasTBnE2PaV7o=
github.com/beevik/etree v1.1.3/go.mod h1:MEjUJqV1InUci5lSfeIonCXMjsMW9yC3APDqKtnyNQg=
github.com/beevik/etree v1.1.4 h1:34PFKrJczQ1qXVC4QCqvY0Iz7m3xu89OShTjYRl4Nbk=
github.com/beevik/etree v1.1.4/go.mod h1:aiPf89g/1k3AShMVAzriilpcE4R/Vuor90y83zVZWFc=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -489,6 +489,8 @@ github.com/puzpuzpuz/xsync/v2 v2.4.0/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2z
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -712,8 +714,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -724,8 +726,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -801,7 +803,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=