mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-11-06 14:49:52 +00:00
Compare commits
133 Commits
v0.4.3-alp
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d3b2f444e | ||
|
|
030bcd1095 | ||
|
|
dad2f3f8c2 | ||
|
|
b09160e76b | ||
|
|
12fc102753 | ||
|
|
6ffe2cc89d | ||
|
|
b9098101e2 | ||
|
|
a6ff39e47d | ||
|
|
23eb739f01 | ||
|
|
ba285cb8bd | ||
|
|
63f01489a8 | ||
|
|
6bbb0802aa | ||
|
|
c26cf4dbec | ||
|
|
958a483385 | ||
|
|
16e97ec66f | ||
|
|
5ea588b813 | ||
|
|
7da0f0d49e | ||
|
|
2adb795896 | ||
|
|
8b251dc407 | ||
|
|
e4bf67dad5 | ||
|
|
e8f9d3aaf5 | ||
|
|
bb0d9ac25c | ||
|
|
3a835c00e3 | ||
|
|
e4447981cb | ||
|
|
170b599e86 | ||
|
|
18ce1d6342 | ||
|
|
1c483a5d9c | ||
|
|
8f7c99779f | ||
|
|
0883f5f3aa | ||
|
|
36dda53e9c | ||
|
|
53c3879907 | ||
|
|
ef57d3348d | ||
|
|
7a76aca022 | ||
|
|
fffdc7fd5e | ||
|
|
29d16d13ba | ||
|
|
54a115ae89 | ||
|
|
17fa7868a4 | ||
|
|
27d6dd86e2 | ||
|
|
ae50a9bb17 | ||
|
|
caf3347da9 | ||
|
|
718a08eab2 | ||
|
|
6f722b3506 | ||
|
|
e722d841a9 | ||
|
|
3ccf58695b | ||
|
|
c52386cef4 | ||
|
|
acac2df40f | ||
|
|
0b507cb7ad | ||
|
|
ac90509c66 | ||
|
|
abf7134710 | ||
|
|
f9a26af93f | ||
|
|
33eacbf4b3 | ||
|
|
262e0d49c8 | ||
|
|
689b0f769a | ||
|
|
8f8a082888 | ||
|
|
9b8c6f4299 | ||
|
|
657cbe5c41 | ||
|
|
b17bff68dd | ||
|
|
7807cfdb01 | ||
|
|
9e5381710f | ||
|
|
fa62c65526 | ||
|
|
3aea945277 | ||
|
|
4d8ca182cb | ||
|
|
b727606a0a | ||
|
|
428be5f2c2 | ||
|
|
995d67543d | ||
|
|
590beac43a | ||
|
|
e7bf227232 | ||
|
|
eedfdde311 | ||
|
|
38c7b5a569 | ||
|
|
8c0b219621 | ||
|
|
23fc677f30 | ||
|
|
a06508783c | ||
|
|
37fee157dd | ||
|
|
3f1c7098bd | ||
|
|
b11d046c52 | ||
|
|
d6a9ba65ed | ||
|
|
5f1df76dbf | ||
|
|
0cf353c56e | ||
|
|
5dc6297047 | ||
|
|
f26ae2793c | ||
|
|
d7641e1b93 | ||
|
|
37c496fd6a | ||
|
|
cb15c06f7e | ||
|
|
89a0ea34b0 | ||
|
|
d8dd815baa | ||
|
|
a77b5d1954 | ||
|
|
d0fb2f06f5 | ||
|
|
dd8032a8be | ||
|
|
760882e147 | ||
|
|
dfeed76a66 | ||
|
|
28d724731a | ||
|
|
4549d8778b | ||
|
|
05cadaabf3 | ||
|
|
1a0c15208c | ||
|
|
4f5b4b0887 | ||
|
|
cbfe44be61 | ||
|
|
e1bbb998df | ||
|
|
f48cddf924 | ||
|
|
23ce3487e1 | ||
|
|
6246421dae | ||
|
|
f867453573 | ||
|
|
78e7a8b411 | ||
|
|
1aa8fb600b | ||
|
|
7ecfea71ab | ||
|
|
d911d80254 | ||
|
|
9bfe37305c | ||
|
|
94dd2e00c7 | ||
|
|
c5d2cebe92 | ||
|
|
955e8dea07 | ||
|
|
4c7b3a749b | ||
|
|
e86a61596b | ||
|
|
c9617e583f | ||
|
|
dda15b0821 | ||
|
|
50816c68b0 | ||
|
|
c5de0319fb | ||
|
|
78b7c6ce09 | ||
|
|
b420a2d930 | ||
|
|
c67ee1731c | ||
|
|
eaca399ef9 | ||
|
|
e0e9f97764 | ||
|
|
2fefee87fa | ||
|
|
280ad4fcf9 | ||
|
|
538639b623 | ||
|
|
39535d6a38 | ||
|
|
4d977d7a62 | ||
|
|
08c500c434 | ||
|
|
705bf1facb | ||
|
|
aae1802191 | ||
|
|
8e1b9b82c1 | ||
|
|
af440eac55 | ||
|
|
34b4e154a1 | ||
|
|
79db93ec02 | ||
|
|
f8ec3b20cd |
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -8,39 +8,57 @@ assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
> A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
> Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
> A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
> If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
|
||||
```
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
```
|
||||
|
||||
**System Time**
|
||||
|
||||
> Run `timedatectl` and share the output
|
||||
|
||||
```
|
||||
(timedatectl output here)
|
||||
```
|
||||
|
||||
**Logs**
|
||||
|
||||
run following command to collect corresponding logs:
|
||||
> Run following command to collect corresponding logs:
|
||||
|
||||
```bash
|
||||
sudo journalctl -xef -u casaos-gateway
|
||||
sudo journalctl -xef -u casaos-user-service
|
||||
sudo journalctl -xef -u casaos-local-storage
|
||||
sudo journalctl -xef -u casaos-app-management
|
||||
sudo journalctl -xef -u casaos.service
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
> Add any other context about the problem here.
|
||||
>
|
||||
> If you are a Zimaboard user, make it explicit with when you got your Zimaboard.
|
||||
|
||||
23
.github/ISSUE_TEMPLATE/feedback.yml
vendored
23
.github/ISSUE_TEMPLATE/feedback.yml
vendored
@ -1,23 +0,0 @@
|
||||
name: "Feedback"
|
||||
description: Feedback, showcases, thoughts, needs and questions, etc.
|
||||
title: "[Feedback] "
|
||||
labels: ["feedback"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
### ❤️ Thanks for your feedback!
|
||||
> Come join our [Discord community](https://discord.gg/knqAbbBbeX) and paint the ideal home cloud with us.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
placeholder: What do you want to tell us?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Please add logs/files/screenshots if you have them to help us better understanding.
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
@ -1,15 +0,0 @@
|
||||
---
|
||||
name: Submit application
|
||||
about: Add an app to this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: LinkLeong
|
||||
|
||||
---
|
||||
|
||||
Tested platform
|
||||
e.g. linux/amd64,linux/arm-v7,linux-arm64
|
||||
|
||||
|
||||
|
||||
Please export and upload the configuration file of this application
|
||||
19
.github/sync_openapi.yml
vendored
Normal file
19
.github/sync_openapi.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Sync OpenAPI
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
project-name:
|
||||
required: true
|
||||
type: string
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
uses: IceWhaleTech/github/.github/workflows/sync_openapi.yml@main
|
||||
with:
|
||||
project-name: casaos
|
||||
secrets:
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
2
.github/workflows/casa.yml
vendored
2
.github/workflows/casa.yml
vendored
@ -65,7 +65,7 @@ jobs:
|
||||
# ls
|
||||
|
||||
|
||||
- name: Set enviroment for github-release
|
||||
- name: Set environment for github-release
|
||||
run: |
|
||||
echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||
echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||
|
||||
2
.github/workflows/codecov.yml
vendored
2
.github/workflows/codecov.yml
vendored
@ -20,6 +20,8 @@ jobs:
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- name: generate OPENAPI
|
||||
run: go generate
|
||||
- name: Run coverage
|
||||
run: go test -race -failfast -coverprofile=coverage.txt -covermode=atomic -v ./...
|
||||
- name: Upload coverage to Codecov
|
||||
|
||||
11
.github/workflows/demo.yml
vendored
11
.github/workflows/demo.yml
vendored
@ -33,9 +33,10 @@ jobs:
|
||||
|
||||
- name: Get old instance and snapshot name, create new instance name
|
||||
run: |
|
||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "updateto_to_0.4.1-1676285322' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
echo "NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=CasaOS-v0.4.4-3-Demo-1700132299" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | tail -1 | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
# echo "OLD_INSTANCE_NAME=CasaOS-Demo-1687680295" >> $GITHUB_ENV
|
||||
echo "NEW_INSTANCE_NAME= CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||
|
||||
- name: Create instances from snapshot
|
||||
run: |
|
||||
@ -75,5 +76,9 @@ jobs:
|
||||
run: |
|
||||
aws lightsail delete-instance \
|
||||
--instance-name ${{ env.OLD_INSTANCE_NAME }}
|
||||
- name: Demo Reset Error Handling
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"Demo Reset Error"}}' ${{ secrets.SSH_ROBOT_URL }}
|
||||
|
||||
|
||||
|
||||
46
.github/workflows/publish_npm.yaml
vendored
Normal file
46
.github/workflows/publish_npm.yaml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: publish npm
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
publish-npm:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- run: git tag --sort=-creatordate | head -n 1
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo "VERSION=$(git tag --sort=-creatordate | head -n 1)" >> $GITHUB_OUTPUT
|
||||
- name: Get commit id
|
||||
id: get_commit_id
|
||||
run: echo "COMMIT_ID=$( git rev-parse --short "$GITHUB_SHA" )" >> $GITHUB_OUTPUT
|
||||
|
||||
- run: echo "${{ steps.get_version.outputs.VERSION }}-${{ steps.get_commit_id.outputs.COMMIT_ID }}"
|
||||
- name: Set version
|
||||
run: |
|
||||
sudo apt-get install jq
|
||||
jq '.version="${{ steps.get_version.outputs.VERSION }}-${{ steps.get_commit_id.outputs.COMMIT_ID }}"' package.json > package.json.new
|
||||
mv package.json.new package.json
|
||||
- name: Generate SDK
|
||||
run: |
|
||||
npm cache clean --force
|
||||
npm install @openapitools/openapi-generator-cli -g
|
||||
- run: npm i
|
||||
- run: npm run start
|
||||
- run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
6
.github/workflows/push_events_to_discord.yml
vendored
6
.github/workflows/push_events_to_discord.yml
vendored
@ -40,9 +40,3 @@ jobs:
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_Bug_Webhook }}
|
||||
|
||||
- name: Alpha Issues & Comments
|
||||
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'alpha') }}
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_Alpha_Webhook }}
|
||||
|
||||
12
.github/workflows/push_test_server.yml
vendored
12
.github/workflows/push_test_server.yml
vendored
@ -3,6 +3,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
@ -19,7 +21,7 @@ jobs:
|
||||
- name: git global
|
||||
run: sudo git config --global --add safe.directory '*'
|
||||
- name: set version
|
||||
run: sudo git tag v99.99.99-alpha
|
||||
run: sudo git tag v00.00.00-alpha
|
||||
|
||||
- name: Fetch all tags
|
||||
run: sudo git fetch --force --tags
|
||||
@ -44,10 +46,16 @@ jobs:
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
version: 1.14.1
|
||||
args: release --rm-dist --snapshot
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GoogleID: ${{ secrets.GoogleID }}
|
||||
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||
DropboxKey: ${{ secrets.DropboxKey }}
|
||||
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||
OneDriveID: ${{ secrets.OneDriveID }}
|
||||
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
|
||||
|
||||
68
.github/workflows/release.yml
vendored
68
.github/workflows/release.yml
vendored
@ -7,57 +7,19 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install dependencies for cross-compiling
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt-get --no-install-recommends --yes install \
|
||||
upx libc6-dev-amd64-cross \
|
||||
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
|
||||
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Fetch all tags
|
||||
run: git fetch --force --tags
|
||||
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
|
||||
- name: Upload to oss
|
||||
id: upload_to_oss
|
||||
uses: tvrcgo/upload-to-oss@master
|
||||
with:
|
||||
key-id: ${{ secrets.OSS_KEY_ID }}
|
||||
key-secret: ${{ secrets.OSS_KEY_SECRET }}
|
||||
region: oss-cn-shanghai
|
||||
bucket: casaos
|
||||
assets: |
|
||||
dist/checksums.txt:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/checksums.txt
|
||||
dist/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
call-workflow-passing-data:
|
||||
uses: IceWhaleTech/github/.github/workflows/go_release.yml@main
|
||||
with:
|
||||
project-name: CasaOS
|
||||
file-name: casaos
|
||||
secrets:
|
||||
GoogleID: ${{ secrets.GoogleID }}
|
||||
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||
DropboxKey: ${{ secrets.DropboxKey }}
|
||||
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||
OneDriveID: ${{ secrets.OneDriveID }}
|
||||
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||
OneDrivePublic: ${{ secrets.OneDrivePublic }}
|
||||
OSS_KEY_ID: ${{ secrets.OSS_KEY_ID }}
|
||||
OSS_KEY_SECRET: ${{ secrets.OSS_KEY_SECRET }}
|
||||
19
.github/workflows/sync_openapi.yml
vendored
Normal file
19
.github/workflows/sync_openapi.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Sync OpenAPI
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
project-name:
|
||||
required: true
|
||||
type: string
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
uses: IceWhaleTech/github/.github/workflows/sync_openapi.yml@main
|
||||
with:
|
||||
project-name: casaos
|
||||
secrets:
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -37,6 +37,7 @@ github.com
|
||||
.all-contributorsrc
|
||||
dist
|
||||
CasaOS
|
||||
/codegen
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
|
||||
@ -59,6 +59,22 @@ builds:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-riscv64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
env:
|
||||
- CC=riscv64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- riscv64
|
||||
- id: casaos-migration-tool-amd64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
@ -112,25 +128,42 @@ builds:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-migration-tool-riscv64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=riscv64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- riscv64
|
||||
archives:
|
||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}"
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||
id: casaos
|
||||
builds:
|
||||
- casaos-amd64
|
||||
- casaos-arm64
|
||||
- casaos-arm-7
|
||||
replacements:
|
||||
arm: arm-7
|
||||
- casaos-riscv64
|
||||
files:
|
||||
- build/**/*
|
||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}"
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}
|
||||
id: casaos-migration-tool
|
||||
builds:
|
||||
- casaos-migration-tool-amd64
|
||||
- casaos-migration-tool-arm64
|
||||
- casaos-migration-tool-arm-7
|
||||
replacements:
|
||||
arm: arm-7
|
||||
- casaos-migration-tool-riscv64
|
||||
files:
|
||||
- build/sysroot/etc/**/*
|
||||
checksum:
|
||||
|
||||
@ -19,6 +19,12 @@ builds:
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
@ -32,14 +38,20 @@ builds:
|
||||
- amd64
|
||||
- id: casaos-arm64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
# hooks:
|
||||
# post:
|
||||
# - upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
@ -61,6 +73,12 @@ builds:
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
@ -74,6 +92,30 @@ builds:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-riscv64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
env:
|
||||
- CC=riscv64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- riscv64
|
||||
- id: casaos-migration-tool-amd64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
hooks:
|
||||
@ -98,9 +140,9 @@ builds:
|
||||
- amd64
|
||||
- id: casaos-migration-tool-arm64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
# hooks:
|
||||
# post:
|
||||
# - upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
@ -142,25 +184,44 @@ builds:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-migration-tool-riscv64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=riscv64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- riscv64
|
||||
archives:
|
||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}"
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||
id: casaos
|
||||
builds:
|
||||
- casaos-amd64
|
||||
- casaos-arm64
|
||||
- casaos-arm-7
|
||||
replacements:
|
||||
arm: arm-7
|
||||
- casaos-riscv64
|
||||
files:
|
||||
- build/**/*
|
||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}"
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}
|
||||
id: casaos-migration-tool
|
||||
builds:
|
||||
- casaos-migration-tool-amd64
|
||||
- casaos-migration-tool-arm64
|
||||
- casaos-migration-tool-arm-7
|
||||
replacements:
|
||||
arm: arm-7
|
||||
- casaos-migration-tool-riscv64
|
||||
files:
|
||||
- build/sysroot/etc/**/*
|
||||
checksum:
|
||||
|
||||
83
README.md
83
README.md
@ -1,6 +1,4 @@
|
||||
# CasaOS - Your Home Cloud OS
|
||||
|
||||
|
||||
# CasaOS - Your Personal Cloud
|
||||
<!-- Readme i18n links -->
|
||||
<!-- > English | [中文](#) | [Français](#) -->
|
||||
|
||||
@ -12,7 +10,7 @@
|
||||
<img alt="CasaOS" src="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800x300.png">
|
||||
</picture>
|
||||
<br/>
|
||||
<i>Connect with the community developing HOME CLOUD, creating self-sovereign, and defining the future of the distributed cloud.</i>
|
||||
<i>Connect with the community, establish autonomy, reduce the cost of SaaS, and MAXIMIZE the potential for a personalized copilot.</i>
|
||||
<br/>
|
||||
<br/>
|
||||
<!-- CasaOS Badges -->
|
||||
@ -46,8 +44,20 @@
|
||||
<img alt="CasaOS GitHub Discussions" src="https://img.shields.io/github/discussions/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Discussions&logo=github" />
|
||||
</a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
<a href="#credits"><img alt="All Contributors" src="https://img.shields.io/static/v1?label=All%20Contributors&message=15&color=162453&style=flat-square&logo=Handshake&logoColor=fff" /></a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
<a href="#credits">
|
||||
<img alt="All Contributors" src="https://img.shields.io/static/v1?label=All%20Contributors&message=15&color=162453&style=flat-square&logo=Handshake&logoColor=fff" />
|
||||
</a>
|
||||
<!-- CasaOS YouTube -->
|
||||
<a href="https://www.youtube.com/channel/UC2zMrUYT17AJhIl9XWZzT8g" target="_blank">
|
||||
<img alt="YouTube Tutorial Views" src="https://img.shields.io/youtube/channel/views/UC2zMrUYT17AJhIl9XWZzT8g?style=flat-square&logo=youtube&logoColor=red&label=YouTube%20Tutorial%20Views" />
|
||||
</a>
|
||||
<br/>
|
||||
<a href="http://bit.ly/45JQIiL" target="_blank">
|
||||
<img alt="twitter ZimaSpace" src="https://img.shields.io/twitter/follow/ZimaSpace?style=flat-square&logo=X&label=Contact%20Us%20%40%20ZimaSpace&labelColor=555&color=555" />
|
||||
</a>
|
||||
<a href="http://bit.ly/4lgHj7V" target="_blank">
|
||||
<img alt="facebook ZimaSpace" src="https://img.shields.io/badge/ZimaSpace-1877F2?style=flat-square&logo=Facebook&logoColor=fff&label=Contact%20Us&labelColor=555&color=162453" />
|
||||
</a>
|
||||
<br/>
|
||||
<!-- CasaOS Links -->
|
||||
<a href="https://www.casaos.io" target="_blank">Website</a> |
|
||||
@ -65,18 +75,16 @@
|
||||
</kbd>
|
||||
</p>
|
||||
|
||||
## Why do we need Home Cloud?
|
||||
## Why do you need Personal Cloud?
|
||||
|
||||
Think about it seriously. Is control of our data, smart devices and digital assets now only in the hands of some big company?
|
||||
In 2020, the team noticed three important trends:
|
||||
- The cost of computing power and storage was decreasing fast.
|
||||
- A part of cloud computing was moving towards edge computing.
|
||||
- The issue of consumer data asset ownership and attribution had been ignored.
|
||||
|
||||
- Is your photo album saved in their cloud service?
|
||||
- Do your thermostats, monitors, lamps need to be used through their cloud services?
|
||||
- Do your personal documents, memos, contacts, passwords, etc. reside in their cloud storage services?
|
||||
- Are you just going to have to accept their decisions when they decide to change prices, review content or even discontinue services?
|
||||
Based on these trends, the team proposed a thought experiment internally: what if personal clouds were available under $100 in next five years? This personal cloud would provide a low-cost data collaboration solution as a personal data center, storing and managing data for creators and small organizations. A distributed collaborative computing network can be formed by personal servers located around the world. It could also control and connect all smart devices, providing cross-ecosystem local intelligent services.
|
||||
|
||||
It sounds ridiculous, doesn't it? We are losing control of our own data!
|
||||
|
||||
Our ideal home cloud is one where you can manage all your data, devices and data assets very easily. In your own home, you have absolute control.
|
||||
Furthermore, the personal cloud could combine personal data to train personalized AI assistants. The idea is that this technology would be an effective way to solve the issue of consumer data asset ownership and , as well as provide a more affordable and efficient computing solution for individuals and small organizations.
|
||||
|
||||
> If you think what we are doing is valuable. Please **give us a star ⭐** and **fork it 🤞**!
|
||||
|
||||
@ -87,7 +95,7 @@ Our ideal home cloud is one where you can manage all your data, devices and data
|
||||
- Multiple hardware and base system support
|
||||
- ZimaBoard, NUC, RPi, old computers, whatever is available.
|
||||
- Selected apps in the app store, one-click installation
|
||||
- Nextcloud, HomeAssiant, AdGuard, Jellyfin, *arr and more!
|
||||
- Nextcloud, HomeAssistant, AdGuard, Jellyfin, *arr and more!
|
||||
- Easily install numerous Docker apps
|
||||
- Over 100,000 apps from the Docker ecosystem can be easily installed
|
||||
- Elegant drive and file management
|
||||
@ -108,7 +116,7 @@ CasaOS fully supports ZimaBoard, Intel NUC, and Raspberry Pi. Also, more compute
|
||||
### System Compatibility
|
||||
|
||||
Official Support
|
||||
- Debian 11 (✅ Tested, Recommended)
|
||||
- Debian 12 (✅ Tested, Recommended)
|
||||
- Ubuntu Server 20.04 (✅ Tested)
|
||||
- Raspberry Pi OS (✅ Tested)
|
||||
|
||||
@ -133,6 +141,30 @@ or
|
||||
curl -fsSL https://get.casaos.io | sudo bash
|
||||
```
|
||||
|
||||
### Update CasaOS
|
||||
|
||||
CasaOS can be updated from the User Interface (UI), via `Settings ... Update`.
|
||||
|
||||
Alternatively it can be updated from a terminal session. To update from a terminal session, it must be done either from a secure shell (ssh) session to the device or from a directly attached terminal and keyboard to the device running CasaOS, this cannot be done from the terminal via the CasaOS User Interface (UI). To update to the latest release of CasaOS from a terminal session run this command:
|
||||
|
||||
```sh
|
||||
wget -qO- https://get.casaos.io/update | sudo bash
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```sh
|
||||
curl -fsSL https://get.casaos.io/update | sudo bash
|
||||
```
|
||||
|
||||
To determine version of CasaOS from a terminal session run this command:
|
||||
|
||||
```sh
|
||||
casaos -v
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Uninstall CasaOS
|
||||
|
||||
|
||||
@ -150,13 +182,13 @@ curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | sudo bash
|
||||
|
||||
## Community
|
||||
|
||||
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for the crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||
|
||||
After looking at many systems and software on the market, the team found no server system designed for home scenarios, sadly true.
|
||||
|
||||
So, we set out to build this open source project to develop CasaOS with our own hands, everyone in the community, and you.
|
||||
So, we set out to build this open-source project to develop CasaOS with our own hands, everyone in the community, and you.
|
||||
|
||||
We believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||
We believe that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||
|
||||
**A warm welcome for you to get help or share great ideas in the [Discord](https://discord.gg/knqAbbBbeX)!**
|
||||
|
||||
@ -166,8 +198,9 @@ We believes that through community-driven collaborative innovation and open comm
|
||||
|
||||
CasaOS is a community-driven open source project and the people involved are CasaOS users. That means CasaOS will always need contributions from community members just like you!
|
||||
|
||||
- See <https://wiki.casaos.io/en/contribute> for ways of contribution to CasaOS
|
||||
- See <https://wiki.casaos.io/en/contribute/development> if you want to be involved in code contribution specificially
|
||||
- See <https://wiki.casaos.io/en/contribute> for ways of contributing to CasaOS
|
||||
- See <https://wiki.casaos.io/en/contribute/development> if you want to be involved in code contribution specifically
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
@ -182,7 +215,7 @@ Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontribu
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/jerrykuku"><img src="https://avatars.githubusercontent.com/u/9485680?v=4?s=100" width="100px;" alt=""/><br /><sub><b>老竭力</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=jerrykuku" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=jerrykuku" title="Documentation">📖</a> <a href="#ideas-jerrykuku" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-jerrykuku" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-jerrykuku" title="Maintenance">🚧</a> <a href="#platform-jerrykuku" title="Packaging/porting to new platform">📦</a> <a href="#question-jerrykuku" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3Ajerrykuku" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/LinkLeong"><img src="https://avatars.githubusercontent.com/u/13556972?v=4?s=100" width="100px;" alt=""/><br /><sub><b>link</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=LinkLeong" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=LinkLeong" title="Documentation">📖</a> <a href="#ideas-LinkLeong" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-LinkLeong" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-LinkLeong" title="Maintenance">🚧</a> <a href="#question-LinkLeong" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3ALinkLeong" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/tigerinus"><img src="https://avatars.githubusercontent.com/u/7172560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tiger Wang (王豫)</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Documentation">📖</a> <a href="#ideas-tigerinus" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-tigerinus" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-tigerinus" title="Maintenance">🚧</a> <a href="#mentoring-tigerinus" title="Mentoring">🧑🏫</a> <a href="#security-tigerinus" title="Security">🛡️</a> <a href="#question-tigerinus" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3Atigerinus" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/tigerinus"><img src="https://avatars.githubusercontent.com/u/7172560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>太戈</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Documentation">📖</a> <a href="#ideas-tigerinus" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-tigerinus" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-tigerinus" title="Maintenance">🚧</a> <a href="#mentoring-tigerinus" title="Mentoring">🧑🏫</a> <a href="#security-tigerinus" title="Security">🛡️</a> <a href="#question-tigerinus" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3Atigerinus" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/Lauren-ED209"><img src="https://avatars.githubusercontent.com/u/8243355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lauren</b></sub></a><br /><a href="#ideas-Lauren-ED209" title="Ideas, Planning, & Feedback">🤔</a> <a href="#fundingFinding-Lauren-ED209" title="Funding Finding">🔍</a> <a href="#projectManagement-Lauren-ED209" title="Project Management">📆</a> <a href="#question-Lauren-ED209" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=Lauren-ED209" title="Tests">⚠️</a></td>
|
||||
<td align="center"><a href="https://JohnGuan.Cn"><img src="https://avatars.githubusercontent.com/u/3358477?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John Guan</b></sub></a><br /><a href="#blog-JohnGuan" title="Blogposts">📝</a> <a href="#content-JohnGuan" title="Content">🖋</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=JohnGuan" title="Documentation">📖</a> <a href="#ideas-JohnGuan" title="Ideas, Planning, & Feedback">🤔</a> <a href="#eventOrganizing-JohnGuan" title="Event Organizing">📋</a> <a href="#mentoring-JohnGuan" title="Mentoring">🧑🏫</a> <a href="#question-JohnGuan" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3AJohnGuan" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://blog.tippybits.com"><img src="https://avatars.githubusercontent.com/u/17506770?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Tippett</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=dtaivpp" title="Documentation">📖</a> <a href="#ideas-dtaivpp" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-dtaivpp" title="Answering Questions">💬</a></td>
|
||||
@ -199,6 +232,8 @@ Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontribu
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/llwaini"><img src="https://avatars.githubusercontent.com/u/59589857?v=4?s=100" width="100px;" alt=""/><br /><sub><b>llwaini</b></sub></a><br /><a href="#projectManagement-llwaini" title="Project Management">📆</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=llwaini" title="Tests">⚠️</a> <a href="#tutorial-llwaini" title="Tutorials">✅</a></td>
|
||||
<td align="center"><a href="https://github.com/CorrectRoadH"><img src="https://avatars.githubusercontent.com/u/29306285?v=4?s=100" width="100px;" alt=""/><br /><sub><b>CorrectRoadH</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=correctroadh" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=correctroadh" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/zhanghengxin"><img src="https://avatars.githubusercontent.com/u/24197448?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zhanghengxin</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=zhanghengxin" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=zhanghengxin" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -207,7 +242,7 @@ Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontribu
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
@ -20,10 +20,11 @@ servers:
|
||||
tags:
|
||||
- name: Health methods
|
||||
description: |-
|
||||
(TODO)
|
||||
- name: File methods
|
||||
These methods are used to check the health and status of the CasaOS API and associated services.
|
||||
|
||||
- name: File methods
|
||||
description: |-
|
||||
(TODO)
|
||||
The File methods allow you to interact with files and directories on the CasaOS system.
|
||||
|
||||
x-tagGroups:
|
||||
- name: Methods
|
||||
@ -47,6 +48,35 @@ paths:
|
||||
$ref: "#/components/responses/GetHealthServicesOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/health/ports:
|
||||
get:
|
||||
tags:
|
||||
- Health methods
|
||||
summary: Get port in use
|
||||
operationId: getHealthPorts
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetHealthPortsOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
/health/logs:
|
||||
get:
|
||||
tags:
|
||||
- Health methods
|
||||
summary: Get log
|
||||
operationId: getHealthlogs
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/file/test:
|
||||
get:
|
||||
tags:
|
||||
@ -60,6 +90,153 @@ paths:
|
||||
$ref: "#/components/responses/ResponseOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/file/upload:
|
||||
get:
|
||||
tags:
|
||||
- File
|
||||
summary: Check upload chunk
|
||||
parameters:
|
||||
- name: path
|
||||
in: query
|
||||
description: File path
|
||||
required: true
|
||||
example: "/DATA/test.log"
|
||||
schema:
|
||||
type: string
|
||||
- name: relativePath
|
||||
in: query
|
||||
description: File path
|
||||
required: true
|
||||
example: "/DATA/test.log"
|
||||
schema:
|
||||
type: string
|
||||
- name: filename
|
||||
in: query
|
||||
description: File name
|
||||
required: true
|
||||
example: "test.log"
|
||||
schema:
|
||||
type: string
|
||||
- name: chunkNumber
|
||||
in: query
|
||||
description: chunk number
|
||||
required: true
|
||||
example: 1
|
||||
schema:
|
||||
type: string
|
||||
- name: totalChunks
|
||||
in: query
|
||||
description: total chunks
|
||||
example: 2
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
description: Check if the file block has been uploaded (needs to be modified later)
|
||||
operationId: checkUploadChunk
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ResponseStringOK"
|
||||
"400":
|
||||
$ref: "#/components/responses/ResponseClientError"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
post:
|
||||
tags:
|
||||
- File
|
||||
summary: Upload file
|
||||
description: Upload file
|
||||
operationId: postUploadFile
|
||||
requestBody:
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
relativePath:
|
||||
type: string
|
||||
example: "/DATA/test.log"
|
||||
filename:
|
||||
type: string
|
||||
example: "/DATA/test2.log"
|
||||
totalChunks:
|
||||
type: string
|
||||
example: "2"
|
||||
chunkNumber:
|
||||
type: string
|
||||
example: "20"
|
||||
path:
|
||||
type: string
|
||||
example: "/DATA"
|
||||
file:
|
||||
type: string
|
||||
format: binary
|
||||
chunkSize:
|
||||
type: string
|
||||
example: "1024"
|
||||
currentChunkSize:
|
||||
type: string
|
||||
example: "1024"
|
||||
totalSize:
|
||||
type: string
|
||||
example: "1024"
|
||||
identifier:
|
||||
type: string
|
||||
example: "test.log"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ResponseStringOK"
|
||||
"400":
|
||||
$ref: "#/components/responses/ResponseClientError"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/zt/info:
|
||||
get:
|
||||
tags:
|
||||
- Zerotier methods
|
||||
summary: Get Zerotier info
|
||||
description: |-
|
||||
Get Zerotier info.
|
||||
operationId: getZerotierInfo
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetZTInfoOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
/zt/{network_id}/status:
|
||||
put:
|
||||
tags:
|
||||
- Zerotier methods
|
||||
summary: Set Zerotier network status
|
||||
description: |-
|
||||
Set Zerotier network status.
|
||||
operationId: setZerotierNetworkStatus
|
||||
parameters:
|
||||
- name: network_id
|
||||
in: path
|
||||
description: network id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
enum:
|
||||
- online
|
||||
- offline
|
||||
type: string
|
||||
example: "online"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetZTInfoOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
access_token:
|
||||
@ -75,6 +252,20 @@ components:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BaseResponse"
|
||||
|
||||
ResponseStringOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SuccessResponseString"
|
||||
|
||||
ResponseClientError:
|
||||
description: Client Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BaseResponse"
|
||||
|
||||
ResponseInternalServerError:
|
||||
description: Internal Server Error
|
||||
content:
|
||||
@ -93,6 +284,24 @@ components:
|
||||
data:
|
||||
$ref: "#/components/schemas/HealthServices"
|
||||
|
||||
GetHealthPortsOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseResponse"
|
||||
- properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/HealthPorts"
|
||||
GetZTInfoOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ZTInfo"
|
||||
|
||||
|
||||
schemas:
|
||||
BaseResponse:
|
||||
properties:
|
||||
@ -101,6 +310,14 @@ components:
|
||||
description: message returned by server side if there is any
|
||||
type: string
|
||||
example: ""
|
||||
|
||||
SuccessResponseString:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseResponse"
|
||||
- properties:
|
||||
data:
|
||||
type: string
|
||||
description: When the interface returns success, this field is the specific success information
|
||||
|
||||
HealthServices:
|
||||
properties:
|
||||
@ -114,3 +331,29 @@ components:
|
||||
items:
|
||||
type: string
|
||||
example: "casaos.service"
|
||||
|
||||
HealthPorts:
|
||||
properties:
|
||||
tcp:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
example: 80
|
||||
x-go-name: TCP
|
||||
udp:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
example: 53
|
||||
x-go-name: UDP
|
||||
ZTInfo:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "1234567890"
|
||||
name:
|
||||
type: string
|
||||
example: "CasaOS"
|
||||
status:
|
||||
type: string
|
||||
example: "online"
|
||||
|
||||
@ -111,6 +111,9 @@ aarch64)
|
||||
armv7l)
|
||||
ARCH="arm-7"
|
||||
;;
|
||||
riscv64)
|
||||
ARCH="riscv64"
|
||||
;;
|
||||
*)
|
||||
__error "Unsupported architecture"
|
||||
;;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
[Unit]
|
||||
After=casaos-message-bus.service
|
||||
After=rclone.service
|
||||
ConditionFileNotEmpty=/etc/casaos/casaos.conf
|
||||
Description=CasaOS Main Service
|
||||
|
||||
[Service]
|
||||
|
||||
28
cmd/message-bus-docgen/main.go
Normal file
28
cmd/message-bus-docgen/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func main() {
|
||||
eventTypes := lo.Map(common.EventTypes, func(item message_bus.EventType, index int) external.EventType {
|
||||
return external.EventType{
|
||||
Name: item.Name,
|
||||
SourceID: item.SourceID,
|
||||
PropertyTypeList: lo.Map(
|
||||
item.PropertyTypeList, func(item message_bus.PropertyType, index int) external.PropertyType {
|
||||
return external.PropertyType{
|
||||
Name: item.Name,
|
||||
Description: item.Description,
|
||||
Example: item.Example,
|
||||
}
|
||||
},
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
external.PrintEventTypesAsMarkdown(common.SERVICENAME, common.VERSION, eventTypes)
|
||||
}
|
||||
@ -77,7 +77,7 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
config.InitSetup(configFlag)
|
||||
config.InitSetup(configFlag, "")
|
||||
|
||||
if len(dbFlag) == 0 {
|
||||
dbFlag = config.AppInfo.DBPath + "/db"
|
||||
|
||||
@ -1,210 +0,0 @@
|
||||
// Package codegen provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
Access_tokenScopes = "access_token.Scopes"
|
||||
)
|
||||
|
||||
// BaseResponse defines model for BaseResponse.
|
||||
type BaseResponse struct {
|
||||
// Message message returned by server side if there is any
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// HealthServices defines model for HealthServices.
|
||||
type HealthServices struct {
|
||||
NotRunning *[]string `json:"not_running,omitempty"`
|
||||
Running *[]string `json:"running,omitempty"`
|
||||
}
|
||||
|
||||
// GetHealthServicesOK defines model for GetHealthServicesOK.
|
||||
type GetHealthServicesOK struct {
|
||||
Data *HealthServices `json:"data,omitempty"`
|
||||
|
||||
// Message message returned by server side if there is any
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
||||
type ResponseInternalServerError = BaseResponse
|
||||
|
||||
// ResponseOK defines model for ResponseOK.
|
||||
type ResponseOK = BaseResponse
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
// Test file methods
|
||||
// (GET /file/test)
|
||||
GetFileTest(ctx echo.Context) error
|
||||
// Get service status
|
||||
// (GET /health/services)
|
||||
GetHealthServices(ctx echo.Context) error
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
}
|
||||
|
||||
// GetFileTest converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetFileTest(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetFileTest(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHealthServices converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHealthServices(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetHealthServices(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// This is a simple interface which specifies echo.Route addition functions which
|
||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
||||
// either of them for path registration
|
||||
type EchoRouter interface {
|
||||
CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
}
|
||||
|
||||
// RegisterHandlers adds each server route to the EchoRouter.
|
||||
func RegisterHandlers(router EchoRouter, si ServerInterface) {
|
||||
RegisterHandlersWithBaseURL(router, si, "")
|
||||
}
|
||||
|
||||
// Registers handlers, and prepends BaseURL to the paths, so that the paths
|
||||
// can be served under a prefix.
|
||||
func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {
|
||||
|
||||
wrapper := ServerInterfaceWrapper{
|
||||
Handler: si,
|
||||
}
|
||||
|
||||
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
||||
|
||||
}
|
||||
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/7xW70/jRhD9V1bTfoDKxBGoUmXpPnC9wiFUpSpIrUSi3GY9sfewd92ZcSBF/t+rXZtL",
|
||||
"SCiC649PiffHe2/e7szsAxhfN96hE4bsAQi58Y4xfpyjfERdSXmFtLIGeXIZho13gk7CX900lTVarHfp",
|
||||
"Z/YujLEpsdZxtqomS8huHuBbwiVk8E26YUv7dZy+14y/DrTQJQ/QkG+QxPYici0R7CWIpyqh67pZ13UJ",
|
||||
"5MiGbBPkQQaTS+gSeKS6cILkdBV2If1E5OlNwb0+pH0lj9yqJ1c9+5a4Nxr9T7QEV7pkAIuOP9mR7Z5H",
|
||||
"jcy6iBNPgYYJRSgtOczVYq24j49tjsoulZRIqCwr7daQAN7ruqkQMoAECHU+cdUaMqEWE5B1E2ZYyLqi",
|
||||
"F75zzHvSnJc5tc6FDdkDWME6jm94jGbtecQ9BOyxfBnQRHodvl+Dd1RowTu9fj1uDIfRtGRlfRWs7yPQ",
|
||||
"xiDzXPwtxiO2wdgSdY4ECThdB4zTVkpP9s94GzZcurGXuO6dsm7p909o2o7HJ6axRlrC+IFTp5RS/QT7",
|
||||
"lgyqGnOr303hoCFcIvGR8ZWno3hBMFO5ptvDKSgmwyjvplCKNJylKem7UWGlbBctIw13d2R8nV4Y/K3U",
|
||||
"FV6jKdPKFz6ttXVpb97wM19o55DmAX7ubFHK/IfxuLkfNa6YwteKrQLQf6hW7mykmC+qFl8WbOtC6SpI",
|
||||
"+FGznlz1ov5/Rb2adOcWTF2vSp3+cqEa8iubI6vassGq0g59y6pGKX3OaulJ5Xa5REInig06TdbzKKCc",
|
||||
"eVKWucWQ47nKLZuW2XrHiWoq1IxqZdlKKAXq5tzKx3ahCBvPVjytZwePbvRO7IffyzxUntRnb5268S2p",
|
||||
"D5aNp3yzO+8HRkWR3ro/TheL9wv8/XA0jeliJebuJmBIYIXEfZKsjkO6+gadbixkcDIaj04ggUZLGXM0",
|
||||
"XdoKU0GOhblA2U+0a2RRYdmjZyOIkBRT9iKHLPTWMxtiYonFb6vtHo/Hf1fUv6xLtzpFl8D3b9nyXOeL",
|
||||
"9aita03r5/QH23TBkN3A2fbwLOxLy1iXU94qzM/aco6ihnqqWLS0rPxSoTal+jRU0u8+qQHmWct2OsDX",
|
||||
"GPfco+bfdzCEOgQyhLplYc+/beJWN4jvpad94GbWzcKCQMZxvqUKMkhXx0P2Q1gwwO+6fnA9+TA53LSP",
|
||||
"Hfbw4np5w5MTD0T3R6KLc/Jt0/MN637euyt7gc66vwIAAP//o5zNVnEKAAA=",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
// or error if failed to decode
|
||||
func decodeSpec() ([]byte, error) {
|
||||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error base64 decoding spec: %s", err)
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(zipped))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err = buf.ReadFrom(zr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var rawSpec = decodeSpecCached()
|
||||
|
||||
// a naive cached of a decoded swagger spec
|
||||
func decodeSpecCached() func() ([]byte, error) {
|
||||
data, err := decodeSpec()
|
||||
return func() ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
|
||||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) {
|
||||
var res = make(map[string]func() ([]byte, error))
|
||||
if len(pathToFile) > 0 {
|
||||
res[pathToFile] = rawSpec
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GetSwagger returns the Swagger specification corresponding to the generated code
|
||||
// in this file. The external references of Swagger specification are resolved.
|
||||
// The logic of resolving external references is tightly connected to "import-mapping" feature.
|
||||
// Externally referenced files must be embedded in the corresponding golang packages.
|
||||
// Urls can be supported but this task was out of the scope.
|
||||
func GetSwagger() (swagger *openapi3.T, err error) {
|
||||
var resolvePath = PathToRawSpec("")
|
||||
|
||||
loader := openapi3.NewLoader()
|
||||
loader.IsExternalRefsAllowed = true
|
||||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) {
|
||||
var pathToFile = url.String()
|
||||
pathToFile = path.Clean(pathToFile)
|
||||
getSpec, ok := resolvePath[pathToFile]
|
||||
if !ok {
|
||||
err1 := fmt.Errorf("path not found: %s", pathToFile)
|
||||
return nil, err1
|
||||
}
|
||||
return getSpec()
|
||||
}
|
||||
var specData []byte
|
||||
specData, err = rawSpec()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
swagger, err = loader.LoadFromData(specData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ package common
|
||||
|
||||
const (
|
||||
SERVICENAME = "casaos"
|
||||
VERSION = "0.4.2"
|
||||
VERSION = "0.4.15"
|
||||
BODY = " "
|
||||
RANW_NAME = "IceWhale-RemoteAccess"
|
||||
)
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||
)
|
||||
|
||||
var (
|
||||
// devtype -> action -> event
|
||||
EventTypes map[string]map[string]message_bus.EventType
|
||||
|
||||
PropertyNameLookupMaps = map[string]map[string]string{
|
||||
"system": {
|
||||
fmt.Sprintf("%s:%s", SERVICENAME, "utilization"): "ID_BUS",
|
||||
},
|
||||
}
|
||||
|
||||
ActionPastTense = map[string]string{
|
||||
"add": "added",
|
||||
"remove": "removed",
|
||||
}
|
||||
)
|
||||
// devtype -> action -> event
|
||||
var EventTypes = []message_bus.EventType{
|
||||
{Name: "casaos:system:utilization", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
{Name: "casaos:file:recover", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
{Name: "casaos:file:operate", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package drivers
|
||||
import (
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||
)
|
||||
|
||||
// All do nothing,just for import
|
||||
|
||||
@ -96,5 +96,8 @@ func (d *Dropbox) Remove(ctx context.Context, obj model.Obj) error {
|
||||
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||
return nil
|
||||
}
|
||||
func (d *Dropbox) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*Dropbox)(nil)
|
||||
|
||||
@ -2,12 +2,9 @@ package dropbox
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/Dropbox.svg"
|
||||
const APPKEY = "tciqajyazzdygt9"
|
||||
const APPSECRET = "e7gtmv441cwdf0n"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
@ -15,7 +12,7 @@ type Addition struct {
|
||||
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
||||
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://www.dropbox.com/oauth2/authorize?client_id=tciqajyazzdygt9&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
@ -25,9 +22,3 @@ var config = driver.Config{
|
||||
OnlyProxy: true,
|
||||
DefaultRoot: "root",
|
||||
}
|
||||
|
||||
func init() {
|
||||
op.RegisterDriver(func() driver.Driver {
|
||||
return &Dropbox{}
|
||||
})
|
||||
}
|
||||
|
||||
@ -10,6 +10,11 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
app_key = "private build"
|
||||
app_secret = "private build"
|
||||
)
|
||||
|
||||
func (d *Dropbox) getRefreshToken() error {
|
||||
url := "https://api.dropbox.com/oauth2/token"
|
||||
var resp base.TokenResp
|
||||
@ -100,3 +105,12 @@ func (d *Dropbox) getFiles(path string) ([]File, error) {
|
||||
|
||||
return res, nil
|
||||
}
|
||||
func GetConfig() Dropbox {
|
||||
dp := Dropbox{}
|
||||
dp.RootFolderID = ""
|
||||
dp.AuthUrl = "https://www.dropbox.com/oauth2/authorize?client_id=" + app_key + "&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"
|
||||
dp.AppKey = app_key
|
||||
dp.AppSecret = app_secret
|
||||
dp.Icon = "./img/driver/Dropbox.svg"
|
||||
return dp
|
||||
}
|
||||
|
||||
@ -80,6 +80,9 @@ func (d *GoogleDrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||
return user.User.EmailAddress, nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||
data := base.Json{
|
||||
"name": dirName,
|
||||
|
||||
@ -2,22 +2,19 @@ package google_drive
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/GoogleDrive.svg"
|
||||
const CLIENTID = "921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com"
|
||||
const CLIENTSECRET = "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"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
ClientID string `json:"client_id" required:"true" default:"921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com" omit:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true" default:"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" omit:"true"`
|
||||
ClientID string `json:"client_id" required:"true" default:"" omit:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true" default:"" omit:"true"`
|
||||
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
@ -27,9 +24,3 @@ var config = driver.Config{
|
||||
OnlyProxy: true,
|
||||
DefaultRoot: "root",
|
||||
}
|
||||
|
||||
func init() {
|
||||
op.RegisterDriver(func() driver.Driver {
|
||||
return &GoogleDrive{}
|
||||
})
|
||||
}
|
||||
|
||||
@ -16,6 +16,11 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
client_id = "private build"
|
||||
client_secret = "private build"
|
||||
)
|
||||
|
||||
// do others that not defined in Driver interface
|
||||
|
||||
func (d *GoogleDrive) getRefreshToken() error {
|
||||
@ -150,3 +155,13 @@ func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func GetConfig() GoogleDrive {
|
||||
config := GoogleDrive{}
|
||||
config.ClientID = client_id
|
||||
config.ClientSecret = client_secret
|
||||
config.RootFolderID = "root"
|
||||
config.AuthUrl = "https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=" + client_id + "&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"
|
||||
config.Icon = "./img/driver/GoogleDrive.svg"
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
73
drivers/onedrive/drive.go
Normal file
73
drivers/onedrive/drive.go
Normal file
@ -0,0 +1,73 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Onedrive struct {
|
||||
model.StorageA
|
||||
Addition
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (d *Onedrive) Config() driver.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetAddition() driver.Additional {
|
||||
return &d.Addition
|
||||
}
|
||||
|
||||
func (d *Onedrive) Init(ctx context.Context) error {
|
||||
if d.ChunkSize < 1 {
|
||||
d.ChunkSize = 5
|
||||
}
|
||||
if len(d.RefreshToken) == 0 {
|
||||
return d.getRefreshToken()
|
||||
}
|
||||
return d.refreshToken()
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
url := d.GetMetaUrl(false, "/")
|
||||
user := Info{}
|
||||
_, err := d.Request(url, http.MethodGet, nil, &user)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return user.CreatedBy.User.Email, user.ParentReference.DriveID, user.ParentReference.DriveType, nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetSpaceSize(ctx context.Context) (used string, total string, err error) {
|
||||
host := onedriveHostMap[d.Region]
|
||||
url := fmt.Sprintf("%s/v1.0/me/drive/quota", host.Api)
|
||||
size := About{}
|
||||
resp, err := d.Request(url, http.MethodGet, nil, &size)
|
||||
if err != nil {
|
||||
return used, total, err
|
||||
}
|
||||
logger.Info("resp", zap.Any("resp", resp))
|
||||
used = strconv.Itoa(size.Used)
|
||||
total = strconv.Itoa(size.Total)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Onedrive) Drop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*Onedrive)(nil)
|
||||
62
drivers/onedrive/meta.go
Normal file
62
drivers/onedrive/meta.go
Normal file
@ -0,0 +1,62 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/OneDrive.svg"
|
||||
|
||||
type Host struct {
|
||||
Oauth string
|
||||
Api string
|
||||
}
|
||||
|
||||
type TokenErr struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
|
||||
type RespErr struct {
|
||||
Error struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
type Addition struct {
|
||||
Region string `json:"region" type:"select" required:"true" options:"global,cn,us,de" default:"global"`
|
||||
IsSharepoint bool `json:"is_sharepoint"`
|
||||
ClientID string `json:"client_id" required:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true"`
|
||||
RedirectUri string `json:"redirect_uri" required:"true" default:""`
|
||||
RefreshToken string `json:"refresh_token" required:"true"`
|
||||
SiteId string `json:"site_id"`
|
||||
ChunkSize int64 `json:"chunk_size" type:"number" default:"5"`
|
||||
RootFolderID string `json:"root_folder_id"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:""`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
type About struct {
|
||||
Total int `json:"total"`
|
||||
Used int `json:"used"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
CreatedBy struct {
|
||||
User struct {
|
||||
Email string `json:"email"`
|
||||
DisplayName string `json:"displayName"`
|
||||
} `json:"user"`
|
||||
} `json:"createdBy"`
|
||||
ParentReference struct {
|
||||
DriveID string `json:"driveId"`
|
||||
DriveType string `json:"driveType"`
|
||||
} `json:"parentReference"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
Name: "Onedrive",
|
||||
LocalSort: true,
|
||||
DefaultRoot: "/",
|
||||
}
|
||||
160
drivers/onedrive/util.go
Normal file
160
drivers/onedrive/util.go
Normal file
@ -0,0 +1,160 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
client_id = "private build"
|
||||
client_secret = "private build"
|
||||
)
|
||||
|
||||
var onedriveHostMap = map[string]Host{
|
||||
"global": {
|
||||
Oauth: "https://login.microsoftonline.com",
|
||||
Api: "https://graph.microsoft.com",
|
||||
},
|
||||
"cn": {
|
||||
Oauth: "https://login.chinacloudapi.cn",
|
||||
Api: "https://microsoftgraph.chinacloudapi.cn",
|
||||
},
|
||||
"us": {
|
||||
Oauth: "https://login.microsoftonline.us",
|
||||
Api: "https://graph.microsoft.us",
|
||||
},
|
||||
"de": {
|
||||
Oauth: "https://login.microsoftonline.de",
|
||||
Api: "https://graph.microsoft.de",
|
||||
},
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetMetaUrl(auth bool, path string) string {
|
||||
host := onedriveHostMap[d.Region]
|
||||
path = utils.EncodePath(path, true)
|
||||
if auth {
|
||||
return host.Oauth
|
||||
}
|
||||
if d.IsSharepoint {
|
||||
if path == "/" || path == "\\" {
|
||||
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, d.SiteId)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, d.SiteId, path)
|
||||
}
|
||||
} else {
|
||||
if path == "/" || path == "\\" {
|
||||
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Onedrive) refreshToken() error {
|
||||
var err error
|
||||
for i := 0; i < 3; i++ {
|
||||
err = d._refreshToken()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Onedrive) getRefreshToken() error {
|
||||
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenErr
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"code": d.Code,
|
||||
"redirect_uri": d.RedirectUri,
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf("%s", e.ErrorDescription)
|
||||
}
|
||||
if resp.RefreshToken == "" {
|
||||
return errors.New("refresh token is empty")
|
||||
}
|
||||
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) _refreshToken() error {
|
||||
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenErr
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"redirect_uri": d.RedirectUri,
|
||||
"refresh_token": d.RefreshToken,
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf("%s", e.ErrorDescription)
|
||||
}
|
||||
if resp.RefreshToken == "" {
|
||||
return errors.New("refresh token is empty")
|
||||
}
|
||||
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||
req := base.RestyClient.R()
|
||||
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||
if callback != nil {
|
||||
callback(req)
|
||||
}
|
||||
if resp != nil {
|
||||
req.SetResult(resp)
|
||||
}
|
||||
var e RespErr
|
||||
req.SetError(&e)
|
||||
res, err := req.Execute(method, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.Error.Code != "" {
|
||||
if e.Error.Code == "InvalidAuthenticationToken" {
|
||||
err = d.refreshToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.Request(url, method, callback, resp)
|
||||
}
|
||||
return nil, errors.New(e.Error.Message)
|
||||
}
|
||||
return res.Body(), nil
|
||||
}
|
||||
|
||||
func GetConfig() Onedrive {
|
||||
config := Onedrive{}
|
||||
config.ClientID = client_id
|
||||
config.ClientSecret = client_secret
|
||||
config.RootFolderID = "/"
|
||||
config.AuthUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + client_id + "&response_type=code&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=offline_access+files.readwrite.all&state=${HOST}%2Fv1%2Frecover%2FOnedrive"
|
||||
config.Icon = "./img/driver/OneDrive.svg"
|
||||
config.Region = "global"
|
||||
config.RedirectUri = "https://cloudoauth.files.casaos.app"
|
||||
|
||||
return config
|
||||
}
|
||||
77
go.mod
77
go.mod
@ -1,30 +1,29 @@
|
||||
module github.com/IceWhaleTech/CasaOS
|
||||
|
||||
go 1.20
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.11-alpha4
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||
github.com/deckarep/golang-set/v2 v2.3.0
|
||||
github.com/deepmap/oapi-codegen v1.12.4
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85
|
||||
github.com/getkin/kin-openapi v0.115.0
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
github.com/glebarez/sqlite v1.7.0
|
||||
github.com/dsoprea/go-exif/v3 v3.0.1
|
||||
github.com/getkin/kin-openapi v0.117.0
|
||||
github.com/glebarez/sqlite v1.8.0
|
||||
github.com/go-ini/ini v1.67.0
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gomodule/redigo v1.8.9
|
||||
github.com/google/go-github/v36 v36.0.0
|
||||
github.com/google/uuid v1.5.0
|
||||
github.com/googollee/go-socket.io v1.7.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/hirochachacha/go-smb2 v1.1.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/labstack/echo/v4 v4.12.0
|
||||
github.com/maruel/natural v1.1.0
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/mileusna/useragent v1.2.1
|
||||
@ -33,80 +32,74 @@ require (
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/samber/lo v1.38.1
|
||||
github.com/shirou/gopsutil/v3 v3.23.2
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/tidwall/gjson v1.17.0
|
||||
go.uber.org/goleak v1.2.1
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.7.0
|
||||
golang.org/x/oauth2 v0.6.0
|
||||
golang.org/x/sync v0.1.0
|
||||
gorm.io/gorm v1.24.6
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/oauth2 v0.7.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/sys v0.20.0
|
||||
gorm.io/gorm v1.25.0
|
||||
gotest.tools v2.2.0+incompatible
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/bytedance/sonic v1.8.5 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/benbjohnson/clock v1.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/geoffgarside/ber v1.1.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.1 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
||||
github.com/goccy/go-json v0.10.1 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.3 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.2 // indirect
|
||||
github.com/labstack/echo-jwt/v4 v4.2.0 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
@ -114,20 +107,20 @@ require (
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||
golang.org/x/image v0.6.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.22.3 // indirect
|
||||
modernc.org/libc v1.22.4 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.21.0 // indirect
|
||||
modernc.org/sqlite v1.21.2 // indirect
|
||||
mvdan.cc/sh/v3 v3.7.0 // indirect
|
||||
)
|
||||
|
||||
183
go.sum
183
go.sum
@ -1,22 +1,16 @@
|
||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
|
||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3 h1:WJUYo+hJpLmza7mQngoJVeUJOfnrZevNrX5wzTuOJo0=
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3/go.mod h1:xcemiRsXcs1zrmQxYMyExDjZ7UHYwkJqYE71IDIV0xA=
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.11-alpha4 h1:W+kOJ3NcWCEAnZdjqmnjnhAG+aLbiVNXnOvV+1bHsB0=
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.11-alpha4/go.mod h1:513p+6RXPBFr98GQZbY1TCyt6Q0jWiuK6vh+gBTmNwA=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.1 h1:Heo0FGXzOxUHquZbraxt+tT7UXVDhesUQH5ISbsOkCQ=
|
||||
github.com/benbjohnson/clock v1.3.1/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.5 h1:kjX0/vo5acEQ/sinD/18SkA/lDDUk23F0RcaHvI7omc=
|
||||
github.com/bytedance/sonic v1.8.5/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
@ -39,8 +33,8 @@ github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221003160559-cf5cd88aa559/go.mod h1:rW6DMEv25U9zCtE5ukC7ttBRllXj7g7TAHl7tQrT5No=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221003171958-de6cb6e380a8/go.mod h1:akyZEJZ/k5bmbC9gA612ZLQkcED8enS9vuTiuAkENr0=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85 h1:vZkWA0Lduu9QB6qRBtsLy7m5uO/RFNCDH2pzMLTxGts=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85/go.mod h1:10HkA1Wz3h398cDP66L+Is9kKDmlqlIJGPv8pk4EWvc=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.1 h1:/IE4iW7gvY7BablV1XY0unqhMv26EYpOquVMwoBo/wc=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.1/go.mod h1:10HkA1Wz3h398cDP66L+Is9kKDmlqlIJGPv8pk4EWvc=
|
||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
||||
@ -53,21 +47,16 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
|
||||
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
||||
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
||||
github.com/getkin/kin-openapi v0.115.0 h1:c8WHRLVY3G8m9jQTy0/DnIuljgRwTCB5twZytQS4JyU=
|
||||
github.com/getkin/kin-openapi v0.115.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
||||
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
||||
github.com/glebarez/go-sqlite v1.21.0 h1:b8MHPtBagkSD2gntImZPsG3o3QEXgMDxguW/GLUonHQ=
|
||||
github.com/glebarez/go-sqlite v1.21.0/go.mod h1:GodsA6yGSa3eKbvpr7dS+JaqazzVfMcjIXvx6KHhW/c=
|
||||
github.com/glebarez/sqlite v1.7.0 h1:A7Xj/KN2Lvie4Z4rrgQHY8MsbebX3NyWsL3n2i82MVI=
|
||||
github.com/glebarez/sqlite v1.7.0/go.mod h1:PkeevrRlF/1BhQBCnzcMWzgrIk7IOop+qS2jUYLfHhk=
|
||||
github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDcUFE8A=
|
||||
github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
||||
github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY=
|
||||
github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E=
|
||||
github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc=
|
||||
github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
@ -83,24 +72,10 @@ github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaL
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.1 h1:lEs5Ob+oOG/Ze199njvzHbhn6p9T+h64F5hRj69iTTo=
|
||||
github.com/goccy/go-json v0.10.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@ -111,6 +86,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
|
||||
@ -131,8 +108,9 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
||||
github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
@ -140,8 +118,11 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f h1:o2yGZLlsOj5H5uvtQNEdi6DeA0GbUP3lm0gWW5RvY0s=
|
||||
github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f/go.mod h1:H3K1Iu/utuCfa10JO+GsmKUYSWi7ug57Rk6GaDRHaaQ=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googollee/go-socket.io v1.7.0 h1:ODcQSAvVIPvKozXtUGuJDV3pLwdpBLDs1Uoq/QHIlY8=
|
||||
github.com/googollee/go-socket.io v1.7.0/go.mod h1:0vGP8/dXR9SZUMMD4+xxaGo/lohOw3YWMh2WRiWeKxg=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
@ -169,30 +150,25 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
|
||||
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
||||
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
|
||||
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
|
||||
github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c=
|
||||
github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU=
|
||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de h1:V53FWzU6KAZVi1tPp5UIsMoUWJ2/PNwYIDXnu7QuBCE=
|
||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
@ -202,13 +178,11 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ=
|
||||
github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/mileusna/useragent v1.2.1 h1:p3RJWhi3LfuI6BHdddojREyK3p6qX67vIfOVMnUIVr0=
|
||||
@ -229,15 +203,11 @@ github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9l
|
||||
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
||||
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -250,32 +220,29 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
||||
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/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU=
|
||||
github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
@ -285,8 +252,6 @@ github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+Kd
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
@ -297,7 +262,6 @@ github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||
@ -310,20 +274,18 @@ go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4=
|
||||
golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0=
|
||||
@ -344,16 +306,17 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -365,12 +328,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -378,22 +336,25 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@ -408,14 +369,12 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -425,20 +384,20 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s=
|
||||
gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU=
|
||||
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
|
||||
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
|
||||
modernc.org/libc v1.22.4 h1:wymSbZb0AlrjdAVX3cjreCHTPCpPARbQXNz6BHPzdwQ=
|
||||
modernc.org/libc v1.22.4/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow=
|
||||
modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
modernc.org/sqlite v1.21.2 h1:ixuUG0QS413Vfzyx6FWx6PYTmHaOegTY+hjzhn7L+a0=
|
||||
modernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=
|
||||
mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg=
|
||||
mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8=
|
||||
|
||||
@ -34,14 +34,16 @@ type Reader interface {
|
||||
// List files in the path
|
||||
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
||||
// if identify files by id, need to set ID with corresponding id
|
||||
List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
||||
// List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
||||
// Link get url/filepath/reader of file
|
||||
Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
||||
// Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
||||
}
|
||||
type User interface {
|
||||
// GetRoot get root directory of user
|
||||
GetUserInfo(ctx context.Context) (string, error)
|
||||
GetInfo(ctx context.Context) (string, string, string, error)
|
||||
}
|
||||
|
||||
type Getter interface {
|
||||
GetRoot(ctx context.Context) (model.Obj, error)
|
||||
}
|
||||
|
||||
30
main.go
30
main.go
@ -13,17 +13,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/model"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
|
||||
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/cache"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/route"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
@ -48,6 +47,9 @@ var (
|
||||
//go:embed api/casaos/openapi.yaml
|
||||
_docYAML string
|
||||
|
||||
//go:embed build/sysroot/etc/casaos/casaos.conf.sample
|
||||
_confSample string
|
||||
|
||||
configFlag = flag.String("c", "", "config address")
|
||||
dbFlag = flag.String("db", "", "db path")
|
||||
versionFlag = flag.Bool("v", false, "version")
|
||||
@ -63,7 +65,7 @@ func init() {
|
||||
println("git commit:", commit)
|
||||
println("build date:", date)
|
||||
|
||||
config.InitSetup(*configFlag)
|
||||
config.InitSetup(*configFlag, _confSample)
|
||||
|
||||
logger.LogInit(config.AppInfo.LogPath, config.AppInfo.LogSaveName, config.AppInfo.LogFileExt)
|
||||
if len(*dbFlag) == 0 {
|
||||
@ -81,9 +83,10 @@ func init() {
|
||||
|
||||
route.InitFunction()
|
||||
|
||||
//service.MyService.System().GenreateSystemEntry()
|
||||
///
|
||||
// service.MountLists = make(map[string]*mountlib.MountPoint)
|
||||
// configfile.Install()
|
||||
//service.MountLists = make(map[string]*mountlib.MountPoint)
|
||||
//configfile.Install()
|
||||
}
|
||||
|
||||
// @title casaOS API
|
||||
@ -101,20 +104,17 @@ func main() {
|
||||
if *versionFlag {
|
||||
return
|
||||
}
|
||||
|
||||
v1Router := route.InitV1Router()
|
||||
|
||||
v2Router := route.InitV2Router()
|
||||
v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML)
|
||||
v3file := route.InitFile()
|
||||
v4dir := route.InitDir()
|
||||
v3File := route.InitFile()
|
||||
mux := &util_http.HandlerMultiplexer{
|
||||
HandlerMap: map[string]http.Handler{
|
||||
"v1": v1Router,
|
||||
"v2": v2Router,
|
||||
"v3": v3File,
|
||||
"doc": v2DocRouter,
|
||||
"v3": v3file,
|
||||
"v4": v4dir,
|
||||
},
|
||||
}
|
||||
|
||||
@ -143,6 +143,8 @@ func main() {
|
||||
"/v1/cloud",
|
||||
"/v1/recover",
|
||||
"/v1/other",
|
||||
"/v1/zt",
|
||||
"/v1/test",
|
||||
route.V2APIPath,
|
||||
route.V2DocPath,
|
||||
route.V3FilePath,
|
||||
@ -152,19 +154,15 @@ func main() {
|
||||
Path: apiPath,
|
||||
Target: "http://" + listener.Addr().String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("err", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
var events []message_bus.EventType
|
||||
events = append(events, message_bus.EventType{Name: "casaos:system:utilization", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
||||
events = append(events, message_bus.EventType{Name: "casaos:file:recover", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
||||
events = append(events, message_bus.EventType{Name: "casaos:file:operate", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
||||
|
||||
// register at message bus
|
||||
for i := 0; i < 10; i++ {
|
||||
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), events)
|
||||
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), common.EventTypes)
|
||||
if err != nil {
|
||||
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.Error(err))
|
||||
}
|
||||
|
||||
7
model/drive.go
Normal file
7
model/drive.go
Normal file
@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type Drive struct {
|
||||
Name string `json:"name"`
|
||||
Icon string `json:"icon"`
|
||||
AuthUrl string `json:"auth_url"`
|
||||
}
|
||||
@ -70,7 +70,8 @@ type FileSetting struct {
|
||||
DownloadDir string `json:"download_dir"`
|
||||
}
|
||||
type BaseInfo struct {
|
||||
Hash string `json:"i"`
|
||||
Version string `json:"v"`
|
||||
Channel string `json:"c,omitempty"`
|
||||
Hash string `json:"i"`
|
||||
Version string `json:"v"`
|
||||
Channel string `json:"c,omitempty"`
|
||||
DriveModel string `json:"m,omitempty"`
|
||||
}
|
||||
|
||||
@ -23,3 +23,14 @@ type Path struct {
|
||||
Write bool `json:"write"`
|
||||
Extensions map[string]interface{} `json:"extensions"`
|
||||
}
|
||||
|
||||
type DeviceInfo struct {
|
||||
LanIpv4 []string `json:"lan_ipv4"`
|
||||
Port int `json:"port"`
|
||||
DeviceName string `json:"device_name"`
|
||||
DeviceModel string `json:"device_model"`
|
||||
DeviceSN string `json:"device_sn"`
|
||||
Initialized bool `json:"initialized"`
|
||||
OS_Version string `json:"os_version"`
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
39
package.json
Normal file
39
package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@icewhale/casaos-openapi",
|
||||
"version": "0.0.1",
|
||||
|
||||
"scripts": {
|
||||
"clean": "rm -rf generate",
|
||||
"build": "rm -rf dist && tsc && yarn clean",
|
||||
"generate:local": "openapi-generator-cli generate -g typescript-axios -i ./api/casaos/openapi.yaml -o ./generate",
|
||||
"generate:npx": "npx @openapitools/openapi-generator-cli generate -g typescript-axios -i ./api/casaos/openapi.yaml -o ./generate",
|
||||
"generate:ts": "npx openapi-typescript-codegen --input ./api/casaos/openapi.yaml --output ./generate",
|
||||
"start": "yarn generate:local && yarn build"
|
||||
},
|
||||
"homepage": "https://github.com/IceWhaleTech/CasaOS#readme",
|
||||
"description": "Casaos Typescript+Axios SDK",
|
||||
"keywords": [
|
||||
"CasaOS",
|
||||
"SDK",
|
||||
"CasaOS Axios"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"dist",
|
||||
"generate"
|
||||
],
|
||||
"dependencies": {
|
||||
"axios": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"all-contributors-cli": "^6.24.0",
|
||||
"@openapitools/openapi-generator-cli": "2.5.2",
|
||||
"@types/node": "^18.8.3",
|
||||
"openapi-typescript-codegen": "^0.23.0",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"author": "casaos",
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
@ -10,6 +10,10 @@
|
||||
*/
|
||||
package config
|
||||
|
||||
const (
|
||||
USERCONFIGURL = "/etc/casaos/casaos.conf"
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
||||
)
|
||||
|
||||
var CasaOSConfigFilePath = filepath.Join(constants.DefaultConfigPath, "casaos.conf")
|
||||
|
||||
@ -14,80 +14,72 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/go-ini/ini"
|
||||
)
|
||||
|
||||
// 系统配置
|
||||
var SysInfo = &model.SysInfoModel{}
|
||||
var (
|
||||
SysInfo = &model.SysInfoModel{}
|
||||
AppInfo = &model.APPModel{
|
||||
DBPath: constants.DefaultDataPath,
|
||||
LogPath: constants.DefaultLogPath,
|
||||
LogSaveName: common.SERVICENAME,
|
||||
LogFileExt: "log",
|
||||
ShellPath: "/usr/share/casaos/shell",
|
||||
UserDataPath: filepath.Join(constants.DefaultDataPath, "conf"),
|
||||
}
|
||||
CommonInfo = &model.CommonModel{
|
||||
RuntimePath: constants.DefaultRuntimePath,
|
||||
}
|
||||
ServerInfo = &model.ServerModel{}
|
||||
SystemConfigInfo = &model.SystemConfig{}
|
||||
FileSettingInfo = &model.FileSetting{}
|
||||
|
||||
// 用户相关
|
||||
var AppInfo = &model.APPModel{}
|
||||
|
||||
var CommonInfo = &model.CommonModel{}
|
||||
|
||||
// var RedisInfo = &model.RedisModel{}
|
||||
|
||||
// server相关
|
||||
var ServerInfo = &model.ServerModel{}
|
||||
|
||||
var SystemConfigInfo = &model.SystemConfig{}
|
||||
|
||||
var FileSettingInfo = &model.FileSetting{}
|
||||
|
||||
var Cfg *ini.File
|
||||
Cfg *ini.File
|
||||
ConfigFilePath string
|
||||
)
|
||||
|
||||
// 初始化设置,获取系统的部分信息。
|
||||
func InitSetup(config string) {
|
||||
configDir := USERCONFIGURL
|
||||
func InitSetup(config string, sample string) {
|
||||
ConfigFilePath = CasaOSConfigFilePath
|
||||
if len(config) > 0 {
|
||||
configDir = config
|
||||
ConfigFilePath = config
|
||||
}
|
||||
if runtime.GOOS == "darwin" {
|
||||
configDir = "./conf/conf.conf"
|
||||
}
|
||||
var err error
|
||||
// 读取文件
|
||||
Cfg, err = ini.Load(configDir)
|
||||
if err != nil {
|
||||
Cfg, err = ini.Load("/etc/casaos.conf")
|
||||
|
||||
// create default config file if not exist
|
||||
if _, err := os.Stat(ConfigFilePath); os.IsNotExist(err) {
|
||||
fmt.Println("config file not exist, create it")
|
||||
// create config file
|
||||
file, err := os.Create(ConfigFilePath)
|
||||
if err != nil {
|
||||
Cfg, err = ini.Load("/casaOS/server/conf/conf.ini")
|
||||
if err != nil {
|
||||
fmt.Printf("Fail to read file: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// write default config
|
||||
_, err = file.WriteString(sample)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
// 读取文件
|
||||
Cfg, err = ini.Load(ConfigFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mapTo("app", AppInfo)
|
||||
// mapTo("redis", RedisInfo)
|
||||
mapTo("server", ServerInfo)
|
||||
mapTo("system", SystemConfigInfo)
|
||||
mapTo("file", FileSettingInfo)
|
||||
mapTo("common", CommonInfo)
|
||||
SystemConfigInfo.ConfigPath = configDir
|
||||
if len(AppInfo.DBPath) == 0 {
|
||||
AppInfo.DBPath = "/var/lib/casaos"
|
||||
}
|
||||
if len(AppInfo.LogPath) == 0 {
|
||||
AppInfo.LogPath = "/var/log/casaos/"
|
||||
}
|
||||
if len(AppInfo.ShellPath) == 0 {
|
||||
AppInfo.ShellPath = "/usr/share/casaos/shell"
|
||||
}
|
||||
if len(AppInfo.UserDataPath) == 0 {
|
||||
AppInfo.UserDataPath = "/var/lib/casaos/conf"
|
||||
}
|
||||
if len(CommonInfo.RuntimePath) == 0 {
|
||||
CommonInfo.RuntimePath = "/var/run/casaos"
|
||||
}
|
||||
Cfg.SaveTo(configDir)
|
||||
// AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd()
|
||||
}
|
||||
|
||||
// 映射
|
||||
@ -97,21 +89,3 @@ func mapTo(section string, v interface{}) {
|
||||
log.Fatalf("Cfg.MapTo %s err: %v", section, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前执行文件绝对路径(go run)
|
||||
func getCurrentAbPathByCaller() string {
|
||||
var abPath string
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if ok {
|
||||
abPath = path.Dir(filename)
|
||||
}
|
||||
return abPath
|
||||
}
|
||||
|
||||
func getCurrentDirectory() string {
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return strings.Replace(dir, "\\", "/", -1)
|
||||
}
|
||||
|
||||
@ -1,159 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func OnlyExec(cmdStr string) {
|
||||
cmd := exec.Command("/bin/bash", "-c", cmdStr)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func ExecResultStrArray(cmdStr string) []string {
|
||||
cmd := exec.Command("/bin/bash", "-c", cmdStr)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return nil
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err = cmd.Start(); err != nil {
|
||||
fmt.Println(err)
|
||||
return nil
|
||||
}
|
||||
// str, err := ioutil.ReadAll(stdout)
|
||||
networklist := []string{}
|
||||
outputBuf := bufio.NewReader(stdout)
|
||||
for {
|
||||
output, _, err := outputBuf.ReadLine()
|
||||
if err != nil {
|
||||
if err.Error() != "EOF" {
|
||||
fmt.Printf("Error :%s\n", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
networklist = append(networklist, string(output))
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return networklist
|
||||
}
|
||||
|
||||
func ExecResultStr(cmdStr string) string {
|
||||
cmd := exec.Command("/bin/bash", "-c", cmdStr)
|
||||
println(cmd.String())
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
str, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return string(str)
|
||||
}
|
||||
|
||||
// 执行 lsblk 命令
|
||||
func ExecLSBLK() []byte {
|
||||
output, err := exec.Command("lsblk", "-O", "-J", "-b").Output()
|
||||
if err != nil {
|
||||
fmt.Println("lsblk", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// 执行 lsblk 命令
|
||||
func ExecLSBLKByPath(path string) []byte {
|
||||
output, err := exec.Command("lsblk", path, "-O", "-J", "-b").Output()
|
||||
if err != nil {
|
||||
fmt.Println("lsblk", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func ExecuteScripts(scriptDirectory string) {
|
||||
if _, err := os.Stat(scriptDirectory); os.IsNotExist(err) {
|
||||
fmt.Printf("No post-start scripts at %s\n", scriptDirectory)
|
||||
return
|
||||
}
|
||||
|
||||
files, err := os.ReadDir(scriptDirectory)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to read from script directory %s: %s\n", scriptDirectory, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
scriptFilepath := filepath.Join(scriptDirectory, file.Name())
|
||||
|
||||
f, err := os.Open(scriptFilepath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to open script file %s: %s\n", scriptFilepath, err.Error())
|
||||
continue
|
||||
}
|
||||
f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
scanner.Scan()
|
||||
shebang := scanner.Text()
|
||||
|
||||
interpreter := "/bin/sh"
|
||||
if strings.HasPrefix(shebang, "#!") {
|
||||
interpreter = shebang[2:]
|
||||
}
|
||||
|
||||
cmd := exec.Command(interpreter, scriptFilepath)
|
||||
|
||||
fmt.Printf("Executing post-start script %s using %s\n", scriptFilepath, interpreter)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to execute post-start script %s: %s\n", scriptFilepath, err.Error())
|
||||
}
|
||||
}
|
||||
fmt.Println("Finished executing post-start scripts.")
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package command_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"go.uber.org/goleak"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func TestExecuteScripts(t *testing.T) {
|
||||
goleak.VerifyNone(t)
|
||||
|
||||
// make a temp directory
|
||||
tmpDir, err := os.MkdirTemp("", "casaos-test-*")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
command.ExecuteScripts(tmpDir)
|
||||
|
||||
// create a sample script under tmpDir
|
||||
script := tmpDir + "/test.sh"
|
||||
f, err := os.Create(script)
|
||||
assert.NilError(t, err)
|
||||
defer f.Close()
|
||||
|
||||
// write a sample script
|
||||
_, err = f.WriteString("#!/bin/bash\necho 123")
|
||||
assert.NilError(t, err)
|
||||
|
||||
command.ExecuteScripts(tmpDir)
|
||||
}
|
||||
11
pkg/utils/default_post_form.go
Normal file
11
pkg/utils/default_post_form.go
Normal file
@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func DefaultPostForm(ctx echo.Context, key, defaultValue string) string {
|
||||
value := ctx.Request().Form.Get(key)
|
||||
if value == "" {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
11
pkg/utils/default_query.go
Normal file
11
pkg/utils/default_query.go
Normal file
@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func DefaultQuery(ctx echo.Context, key string, defaultValue string) string {
|
||||
if value := ctx.QueryParam(key); value != "" {
|
||||
return value
|
||||
}
|
||||
|
||||
return defaultValue
|
||||
}
|
||||
@ -77,6 +77,22 @@ func RMDir(src string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemoveAll(dir string) error {
|
||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return os.Remove(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Remove(dir)
|
||||
}
|
||||
|
||||
// Open a file according to a specific mode
|
||||
func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
|
||||
f, err := os.OpenFile(name, flag, perm)
|
||||
@ -163,7 +179,7 @@ func CreateFileAndWriteContent(path string, content string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsNotExistMkDir create a directory if it does not exist
|
||||
// IsNotExistCreateFile create a file if it does not exist
|
||||
func IsNotExistCreateFile(src string) error {
|
||||
if notExist := CheckNotExist(src); notExist {
|
||||
if err := CreateFile(src); err != nil {
|
||||
@ -431,7 +447,9 @@ func AddFile(ar archiver.Writer, path, commonPath string) error {
|
||||
defer file.Close()
|
||||
|
||||
if path != commonPath {
|
||||
filename := info.Name()
|
||||
//filename := info.Name()
|
||||
filename := strings.TrimPrefix(path, commonPath)
|
||||
filename = strings.TrimPrefix(filename, string(filepath.Separator))
|
||||
err = ar.Write(archiver.File{
|
||||
FileInfo: archiver.FileInfo{
|
||||
FileInfo: info,
|
||||
|
||||
78
pkg/utils/httper/zerotier.go
Normal file
78
pkg/utils/httper/zerotier.go
Normal file
@ -0,0 +1,78 @@
|
||||
package httper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ZTGet(url string) ([]byte, error) {
|
||||
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build the target URL
|
||||
targetURL := fmt.Sprintf("http://localhost:%s%s", strings.TrimSpace(string(port)), url)
|
||||
|
||||
// Create a new request
|
||||
req, err := http.NewRequest("GET", targetURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add the X-ZT1-AUTH header
|
||||
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
|
||||
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return respBody, nil
|
||||
}
|
||||
func ZTPost(url string, body string) ([]byte, error) {
|
||||
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Build the target URL
|
||||
targetURL := fmt.Sprintf("http://localhost:%s%s", strings.TrimSpace(string(port)), url)
|
||||
|
||||
// Create a new request
|
||||
req, err := http.NewRequest("POST", targetURL, strings.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add the X-ZT1-AUTH header
|
||||
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
|
||||
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return respBody, nil
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package ip_helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
@ -56,7 +57,30 @@ func GetDeviceAllIP(port string) []string {
|
||||
}
|
||||
return address
|
||||
}
|
||||
func GetDeviceAllIPv4() map[string]string {
|
||||
address := make(map[string]string)
|
||||
addrs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return address
|
||||
}
|
||||
for _, a := range addrs {
|
||||
if a.Flags&net.FlagLoopback != 0 || a.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
}
|
||||
addrs, err := a.Addrs()
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
|
||||
address[a.Name] = ipnet.IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
return address
|
||||
}
|
||||
func HasLocalIP(ip net.IP) bool {
|
||||
if ip.IsLoopback() {
|
||||
return true
|
||||
|
||||
@ -17,6 +17,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
file1 "github.com/IceWhaleTech/CasaOS-Common/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
@ -24,6 +25,7 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/samba"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
v1 "github.com/IceWhaleTech/CasaOS/route/v1"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@ -31,6 +33,7 @@ import (
|
||||
func InitFunction() {
|
||||
go InitNetworkMount()
|
||||
go InitInfo()
|
||||
//go InitZerotier()
|
||||
}
|
||||
|
||||
func InitInfo() {
|
||||
@ -51,6 +54,12 @@ func InitInfo() {
|
||||
}
|
||||
mb.Hash = encryption.GetMD5ByStr(mac)
|
||||
mb.Version = common.VERSION
|
||||
osRelease, _ := file1.ReadOSRelease()
|
||||
|
||||
mb.DriveModel = osRelease["MODEL"]
|
||||
if len(mb.DriveModel) == 0 {
|
||||
mb.DriveModel = "Casa"
|
||||
}
|
||||
os.Remove(config.AppInfo.DBPath + "/baseinfo.conf")
|
||||
by, err := json.Marshal(mb)
|
||||
if err != nil {
|
||||
@ -92,6 +101,12 @@ func InitNetworkMount() {
|
||||
}
|
||||
connection.Directories = strings.Join(directories, ",")
|
||||
service.MyService.Connections().UpdateConnection(&connection)
|
||||
service.MyService.Storage().CheckAndMountAll()
|
||||
}
|
||||
err := service.MyService.Storage().CheckAndMountAll()
|
||||
if err != nil {
|
||||
logger.Error("mount storage err", zap.Any("err", err))
|
||||
}
|
||||
}
|
||||
func InitZerotier() {
|
||||
v1.CheckNetwork()
|
||||
}
|
||||
|
||||
92
route/v1.go
92
route/v1.go
@ -1,45 +1,69 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"os"
|
||||
"crypto/ecdsa"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/middleware"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
v1 "github.com/IceWhaleTech/CasaOS/route/v1"
|
||||
|
||||
"github.com/gin-contrib/gzip"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
echo_middleware "github.com/labstack/echo/v4/middleware"
|
||||
)
|
||||
|
||||
func InitV1Router() *gin.Engine {
|
||||
ginMode := gin.ReleaseMode
|
||||
if config.ServerInfo.RunMode != "" {
|
||||
ginMode = config.ServerInfo.RunMode
|
||||
}
|
||||
if os.Getenv(gin.EnvGinMode) != "" {
|
||||
ginMode = os.Getenv(gin.EnvGinMode)
|
||||
}
|
||||
gin.SetMode(ginMode)
|
||||
func InitV1Router() http.Handler {
|
||||
e := echo.New()
|
||||
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
r.Use(middleware.Cors())
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
if ginMode != gin.ReleaseMode {
|
||||
r.Use(middleware.WriteLog())
|
||||
}
|
||||
e.Use((echo_middleware.CORSWithConfig(echo_middleware.CORSConfig{
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowMethods: []string{echo.POST, echo.GET, echo.OPTIONS, echo.PUT, echo.DELETE},
|
||||
AllowHeaders: []string{echo.HeaderAuthorization, echo.HeaderContentLength, echo.HeaderXCSRFToken, echo.HeaderContentType, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders, echo.HeaderAccessControlAllowMethods, echo.HeaderConnection, echo.HeaderOrigin, echo.HeaderXRequestedWith},
|
||||
ExposeHeaders: []string{echo.HeaderContentLength, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders},
|
||||
MaxAge: 172800,
|
||||
AllowCredentials: true,
|
||||
})))
|
||||
e.Use(echo_middleware.Gzip())
|
||||
e.Use(echo_middleware.Recover())
|
||||
e.Use(echo_middleware.Logger())
|
||||
|
||||
r.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug
|
||||
e.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug
|
||||
|
||||
r.GET("/v1/sys/version/check", v1.GetSystemCheckVersion)
|
||||
r.GET("/ping", func(ctx *gin.Context) {
|
||||
ctx.String(200, "pong")
|
||||
e.GET("/v1/sys/version/check", v1.GetSystemCheckVersion)
|
||||
e.GET("/v1/sys/version/current", func(ctx echo.Context) error {
|
||||
return ctx.String(200, common.VERSION)
|
||||
})
|
||||
r.GET("/v1/recover/:type", v1.GetRecoverStorage)
|
||||
v1Group := r.Group("/v1")
|
||||
e.GET("/ping", func(ctx echo.Context) error {
|
||||
return ctx.String(200, "pong")
|
||||
})
|
||||
e.GET("/v1/recover/:type", v1.GetRecoverStorage)
|
||||
v1Group := e.Group("/v1")
|
||||
// e.Any("/v1/test", v1.CheckNetwork)
|
||||
v1Group.Use(echo_middleware.JWTWithConfig(echo_middleware.JWTConfig{
|
||||
Skipper: func(c echo.Context) bool {
|
||||
return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1"
|
||||
},
|
||||
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
|
||||
valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||
if err != nil || !valid {
|
||||
return nil, echo.ErrUnauthorized
|
||||
}
|
||||
|
||||
v1Group.Use(jwt.ExceptLocalhost())
|
||||
c.Request().Header.Set("user_id", strconv.Itoa(claims.ID))
|
||||
|
||||
return claims, nil
|
||||
},
|
||||
TokenLookupFuncs: []echo_middleware.ValuesExtractor{
|
||||
func(ctx echo.Context) ([]string, error) {
|
||||
if len(ctx.Request().Header.Get(echo.HeaderAuthorization)) > 0 {
|
||||
return []string{ctx.Request().Header.Get(echo.HeaderAuthorization)}, nil
|
||||
}
|
||||
return []string{ctx.QueryParam("token")}, nil
|
||||
},
|
||||
},
|
||||
}))
|
||||
{
|
||||
|
||||
v1SysGroup := v1Group.Group("/sys")
|
||||
@ -73,6 +97,7 @@ func InitV1Router() *gin.Engine {
|
||||
// v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||
v1SysGroup.GET("/proxy", v1.GetSystemProxy)
|
||||
v1SysGroup.PUT("/state/:state", v1.PutSystemState)
|
||||
v1SysGroup.GET("/entry", v1.GetSystemEntry)
|
||||
}
|
||||
v1PortGroup := v1Group.Group("/port")
|
||||
v1PortGroup.Use()
|
||||
@ -80,7 +105,6 @@ func InitV1Router() *gin.Engine {
|
||||
v1PortGroup.GET("/", v1.GetPort) // app/port
|
||||
v1PortGroup.GET("/state/:port", v1.PortCheck) // app/check/:port
|
||||
}
|
||||
|
||||
v1FileGroup := v1Group.Group("/file")
|
||||
v1FileGroup.Use()
|
||||
{
|
||||
@ -92,7 +116,7 @@ func InitV1Router() *gin.Engine {
|
||||
v1FileGroup.GET("/content", v1.GetFilerContent) // file/read
|
||||
|
||||
// File uploads need to be handled separately, and will not be modified here
|
||||
//v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||
// v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||
v1FileGroup.POST("/upload", v1.PostFileUpload)
|
||||
v1FileGroup.GET("/upload", v1.GetFileUpload)
|
||||
// v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
||||
@ -165,9 +189,13 @@ func InitV1Router() *gin.Engine {
|
||||
v1OtherGroup.Use()
|
||||
{
|
||||
v1OtherGroup.GET("/search", v1.GetSearchResult)
|
||||
|
||||
}
|
||||
v1ZerotierGroup := v1Group.Group("/zt")
|
||||
v1ZerotierGroup.Use()
|
||||
{
|
||||
v1ZerotierGroup.Any("/*url", v1.ZerotierProxy)
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
return e
|
||||
}
|
||||
|
||||
@ -6,37 +6,19 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func ListStorages(c *gin.Context) {
|
||||
// var req model.PageReq
|
||||
// if err := c.ShouldBind(&req); err != nil {
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
|
||||
// return
|
||||
// }
|
||||
// req.Validate()
|
||||
|
||||
//logger.Info("ListStorages", zap.Any("req", req))
|
||||
//storages, total, err := service.MyService.Storage().GetStorages(req.Page, req.PerPage)
|
||||
// if err != nil {
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
// return
|
||||
// }
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: model.PageResp{
|
||||
// Content: storages,
|
||||
// Total: total,
|
||||
// }})
|
||||
func ListStorages(ctx echo.Context) error {
|
||||
r, err := service.MyService.Storage().GetStorages()
|
||||
|
||||
if err != nil {
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
|
||||
for i := 0; i < len(r.MountPoints); i++ {
|
||||
@ -51,51 +33,47 @@ func ListStorages(c *gin.Context) {
|
||||
if dataMap["type"] == "dropbox" {
|
||||
r.MountPoints[i].Icon = dropbox.ICONURL
|
||||
}
|
||||
if dataMap["type"] == "onedrive" {
|
||||
r.MountPoints[i].Icon = onedrive.ICONURL
|
||||
}
|
||||
r.MountPoints[i].Name = dataMap["username"]
|
||||
}
|
||||
list := []httper.MountPoint{}
|
||||
|
||||
for _, v := range r.MountPoints {
|
||||
list = append(list, httper.MountPoint{
|
||||
Fs: v.Fs,
|
||||
Icon: v.Icon,
|
||||
MountPoint: v.MountPoint,
|
||||
Name: v.Name,
|
||||
})
|
||||
list = append(list, httper.MountPoint(v))
|
||||
}
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||
}
|
||||
|
||||
func UmountStorage(c *gin.Context) {
|
||||
func UmountStorage(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
mountPoint := json["mount_point"]
|
||||
if mountPoint == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "mount_point is empty"})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "mount_point is empty"})
|
||||
}
|
||||
err := service.MyService.Storage().UnmountStorage(mountPoint)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
service.MyService.Storage().DeleteConfigByName(strings.ReplaceAll(mountPoint, "/mnt/", ""))
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "success"})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "success"})
|
||||
}
|
||||
|
||||
func GetStorage(c *gin.Context) {
|
||||
|
||||
// idStr := c.Query("id")
|
||||
func GetStorage(ctx echo.Context) error {
|
||||
// idStr := ctx.QueryParam("id")
|
||||
// id, err := strconv.Atoi(idStr)
|
||||
// if err != nil {
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
|
||||
// return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
|
||||
// return
|
||||
// }
|
||||
// storage, err := service.MyService.Storage().GetStorageById(uint(id))
|
||||
// if err != nil {
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
// return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
// return
|
||||
// }
|
||||
// c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storage})
|
||||
// return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storage})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1,12 +1,34 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/model"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/op"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func ListDriverInfo(c *gin.Context) {
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: op.GetDriverInfoMap()})
|
||||
func ListDriverInfo(ctx echo.Context) error {
|
||||
list := []model.Drive{}
|
||||
|
||||
google := google_drive.GetConfig()
|
||||
list = append(list, model.Drive{
|
||||
Name: "Google Drive",
|
||||
Icon: google.Icon,
|
||||
AuthUrl: google.AuthUrl,
|
||||
})
|
||||
dp := dropbox.GetConfig()
|
||||
list = append(list, model.Drive{
|
||||
Name: "Dropbox",
|
||||
Icon: dp.Icon,
|
||||
AuthUrl: dp.AuthUrl,
|
||||
})
|
||||
od := onedrive.GetConfig()
|
||||
list = append(list, model.Drive{
|
||||
Name: "OneDrive",
|
||||
Icon: od.Icon,
|
||||
AuthUrl: od.AuthUrl,
|
||||
})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||
}
|
||||
|
||||
400
route/v1/file.go
400
route/v1/file.go
@ -20,16 +20,17 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/h2non/filetype"
|
||||
@ -38,8 +39,9 @@ import (
|
||||
type ListReq struct {
|
||||
model.PageReq
|
||||
Path string `json:"path" form:"path"`
|
||||
//Refresh bool `json:"refresh"`
|
||||
// Refresh bool `json:"refresh"`
|
||||
}
|
||||
|
||||
type ObjResp struct {
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
@ -82,58 +84,53 @@ var (
|
||||
// @Param path query string true "路径"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/read [get]
|
||||
func GetFilerContent(c *gin.Context) {
|
||||
filePath := c.Query("path")
|
||||
func GetFilerContent(ctx echo.Context) error {
|
||||
filePath := ctx.QueryParam("path")
|
||||
if len(filePath) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
Success: common_err.INVALID_PARAMS,
|
||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !file.Exists(filePath) {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
})
|
||||
return
|
||||
}
|
||||
// 文件读取任务是将文件内容读取到内存中。
|
||||
info, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
Success: common_err.FILE_READ_ERROR,
|
||||
Message: common_err.GetMsg(common_err.FILE_READ_ERROR),
|
||||
Data: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
result := string(info)
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{
|
||||
Success: common_err.SUCCESS,
|
||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
func GetLocalFile(c *gin.Context) {
|
||||
path := c.Query("path")
|
||||
func GetLocalFile(ctx echo.Context) error {
|
||||
path := ctx.QueryParam("path")
|
||||
if len(path) == 0 {
|
||||
c.JSON(http.StatusOK, model.Result{
|
||||
return ctx.JSON(http.StatusOK, model.Result{
|
||||
Success: common_err.INVALID_PARAMS,
|
||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !file.Exists(path) {
|
||||
c.JSON(http.StatusOK, model.Result{
|
||||
return ctx.JSON(http.StatusOK, model.Result{
|
||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
})
|
||||
return
|
||||
}
|
||||
c.File(path)
|
||||
return ctx.File(path)
|
||||
}
|
||||
|
||||
// @Summary download
|
||||
@ -145,42 +142,39 @@ func GetLocalFile(c *gin.Context) {
|
||||
// @Param files query string true "file list eg: filename1,filename2,filename3 "
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/download [get]
|
||||
func GetDownloadFile(c *gin.Context) {
|
||||
t := c.Query("format")
|
||||
func GetDownloadFile(ctx echo.Context) error {
|
||||
t := ctx.QueryParam("format")
|
||||
|
||||
files := c.Query("files")
|
||||
files := ctx.QueryParam("files")
|
||||
|
||||
if len(files) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
Success: common_err.INVALID_PARAMS,
|
||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||
})
|
||||
return
|
||||
}
|
||||
list := strings.Split(files, ",")
|
||||
for _, v := range list {
|
||||
if !file.Exists(v) {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Header("Content-Type", "application/octet-stream")
|
||||
c.Header("Content-Transfer-Encoding", "binary")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
ctx.Request().Header.Add("Content-Type", "application/octet-stream")
|
||||
ctx.Request().Header.Add("Content-Transfer-Encoding", "binary")
|
||||
ctx.Request().Header.Add("Cache-Control", "no-cache")
|
||||
// handles only single files not folders and multiple files
|
||||
if len(list) == 1 {
|
||||
|
||||
filePath := list[0]
|
||||
info, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, model.Result{
|
||||
return ctx.JSON(http.StatusOK, model.Result{
|
||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !info.IsDir() {
|
||||
|
||||
@ -190,29 +184,26 @@ func GetDownloadFile(c *gin.Context) {
|
||||
|
||||
// 获取文件的名称
|
||||
fileName := path.Base(filePath)
|
||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||
c.File(filePath)
|
||||
return
|
||||
ctx.Response().Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||
ctx.File(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
extension, ar, err := file.GetCompressionAlgorithm(t)
|
||||
if err != nil {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
Success: common_err.INVALID_PARAMS,
|
||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = ar.Create(c.Writer)
|
||||
err = ar.Create(ctx.Response().Writer)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
Success: common_err.SERVICE_ERROR,
|
||||
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
|
||||
Data: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer ar.Close()
|
||||
commonDir := file.CommonPrefix(filepath.Separator, list...)
|
||||
@ -221,27 +212,27 @@ func GetDownloadFile(c *gin.Context) {
|
||||
|
||||
name := "_" + currentPath
|
||||
name += extension
|
||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||
ctx.Request().Header.Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||
for _, fname := range list {
|
||||
err = file.AddFile(ar, fname, commonDir)
|
||||
if err != nil {
|
||||
log.Printf("Failed to archive %s: %v", fname, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDownloadSingleFile(c *gin.Context) {
|
||||
filePath := c.Query("path")
|
||||
func GetDownloadSingleFile(ctx echo.Context) error {
|
||||
filePath := ctx.QueryParam("path")
|
||||
if len(filePath) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||
Success: common_err.INVALID_PARAMS,
|
||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||
})
|
||||
return
|
||||
}
|
||||
fileName := path.Base(filePath)
|
||||
// c.Header("Content-Disposition", "inline")
|
||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||
ctx.Request().Header.Add("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||
|
||||
fi, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
@ -255,31 +246,28 @@ func GetDownloadSingleFile(c *gin.Context) {
|
||||
|
||||
kind, _ := filetype.Match(buffer)
|
||||
if kind != filetype.Unknown {
|
||||
c.Header("Content-Type", kind.MIME.Value)
|
||||
ctx.Request().Header.Add("Content-Type", kind.MIME.Value)
|
||||
}
|
||||
node, err := os.Stat(filePath)
|
||||
// Set the Last-Modified header to the timestamp
|
||||
c.Header("Last-Modified", node.ModTime().UTC().Format(http.TimeFormat))
|
||||
ctx.Request().Header.Add("Last-Modified", node.ModTime().UTC().Format(http.TimeFormat))
|
||||
|
||||
knownSize := node.Size() >= 0
|
||||
if knownSize {
|
||||
c.Header("Content-Length", strconv.FormatInt(node.Size(), 10))
|
||||
ctx.Request().Header.Add("Content-Length", strconv.FormatInt(node.Size(), 10))
|
||||
}
|
||||
http.ServeContent(c.Writer, c.Request, fileName, node.ModTime(), fi)
|
||||
//http.ServeFile(c.Writer, c.Request, filePath)
|
||||
http.ServeContent(ctx.Response().Writer, ctx.Request(), fileName, node.ModTime(), fi)
|
||||
defer fi.Close()
|
||||
return
|
||||
fileTmp, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer fileTmp.Close()
|
||||
|
||||
c.File(filePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// @Summary 获取目录列表
|
||||
@ -290,17 +278,14 @@ func GetDownloadSingleFile(c *gin.Context) {
|
||||
// @Param path query string false "路径"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/dirpath [get]
|
||||
func DirPath(c *gin.Context) {
|
||||
func DirPath(ctx echo.Context) error {
|
||||
var req ListReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
|
||||
return
|
||||
}
|
||||
path := ctx.QueryParam("path")
|
||||
req.Path = path
|
||||
req.Validate()
|
||||
info, err := service.MyService.System().GetDirPath(req.Path)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
shares := service.MyService.Shares().GetSharesList()
|
||||
sharesMap := make(map[string]string)
|
||||
@ -308,7 +293,7 @@ func DirPath(c *gin.Context) {
|
||||
sharesMap[v.Path] = fmt.Sprint(v.ID)
|
||||
}
|
||||
// if len(info) <= (req.Page-1)*req.Size {
|
||||
// c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "page out of range"})
|
||||
// return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "page out of range"})
|
||||
// return
|
||||
// }
|
||||
forEnd := req.Index * req.Size
|
||||
@ -380,7 +365,7 @@ func DirPath(c *gin.Context) {
|
||||
Index: req.Index,
|
||||
Size: req.Size,
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: flist})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: flist})
|
||||
}
|
||||
|
||||
// @Summary rename file or dir
|
||||
@ -392,23 +377,21 @@ func DirPath(c *gin.Context) {
|
||||
// @Param newpath body string true "path of new"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/rename [put]
|
||||
func RenamePath(c *gin.Context) {
|
||||
func RenamePath(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
op := json["old_path"]
|
||||
np := json["new_path"]
|
||||
if len(op) == 0 || len(np) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
mounted := service.IsMounted(op)
|
||||
if mounted {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
}
|
||||
|
||||
success, err := service.MyService.System().RenameFile(op, np)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
|
||||
}
|
||||
|
||||
// @Summary create folder
|
||||
@ -419,22 +402,21 @@ func RenamePath(c *gin.Context) {
|
||||
// @Param path body string true "path of folder"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/mkdir [post]
|
||||
func MkdirAll(c *gin.Context) {
|
||||
func MkdirAll(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
path := json["path"]
|
||||
var code int
|
||||
if len(path) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
// decodedPath, err := url.QueryUnescape(path)
|
||||
// if err != nil {
|
||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return ctx.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
code, _ = service.MyService.System().MkdirAll(path)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||
}
|
||||
|
||||
// @Summary create file
|
||||
@ -445,22 +427,21 @@ func MkdirAll(c *gin.Context) {
|
||||
// @Param path body string true "path of folder (path need to url encode)"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/create [post]
|
||||
func PostCreateFile(c *gin.Context) {
|
||||
func PostCreateFile(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
path := json["path"]
|
||||
var code int
|
||||
if len(path) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
// decodedPath, err := url.QueryUnescape(path)
|
||||
// if err != nil {
|
||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return ctx.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
code, _ = service.MyService.System().CreateFile(path)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||
}
|
||||
|
||||
// @Summary upload file
|
||||
@ -472,14 +453,17 @@ func PostCreateFile(c *gin.Context) {
|
||||
// @Param file formData file true "file"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/upload [get]
|
||||
func GetFileUpload(c *gin.Context) {
|
||||
relative := c.Query("relativePath")
|
||||
fileName := c.Query("filename")
|
||||
chunkNumber := c.Query("chunkNumber")
|
||||
totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0"))
|
||||
path := c.Query("path")
|
||||
func GetFileUpload(ctx echo.Context) error {
|
||||
relative := ctx.QueryParam("relativePath")
|
||||
fileName := ctx.QueryParam("filename")
|
||||
chunkNumber := ctx.QueryParam("chunkNumber")
|
||||
totalChunks, _ := strconv.Atoi(utils.DefaultQuery(ctx, "totalChunks", "0"))
|
||||
path := ctx.QueryParam("path")
|
||||
dirPath := ""
|
||||
hash := file.GetHashByContent([]byte(fileName))
|
||||
if file.Exists(path + "/" + relative) {
|
||||
return ctx.JSON(http.StatusConflict, model.Result{Success: http.StatusConflict, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
}
|
||||
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
|
||||
if fileName != relative {
|
||||
dirPath = strings.TrimSuffix(relative, fileName)
|
||||
@ -488,11 +472,10 @@ func GetFileUpload(c *gin.Context) {
|
||||
}
|
||||
tempDir += chunkNumber
|
||||
if !file.CheckNotExist(tempDir) {
|
||||
c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
}
|
||||
|
||||
c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary upload file
|
||||
@ -504,21 +487,20 @@ func GetFileUpload(c *gin.Context) {
|
||||
// @Param file formData file true "file"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/upload [post]
|
||||
func PostFileUpload(c *gin.Context) {
|
||||
f, _, _ := c.Request.FormFile("file")
|
||||
relative := c.PostForm("relativePath")
|
||||
fileName := c.PostForm("filename")
|
||||
totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0"))
|
||||
chunkNumber := c.PostForm("chunkNumber")
|
||||
func PostFileUpload(ctx echo.Context) error {
|
||||
f, _, _ := ctx.Request().FormFile("file")
|
||||
relative := ctx.FormValue("relativePath")
|
||||
fileName := ctx.FormValue("filename")
|
||||
totalChunks, _ := strconv.Atoi(utils.DefaultPostForm(ctx, "totalChunks", "0"))
|
||||
chunkNumber := ctx.FormValue("chunkNumber")
|
||||
dirPath := ""
|
||||
path := c.PostForm("path")
|
||||
path := ctx.FormValue("path")
|
||||
|
||||
hash := file.GetHashByContent([]byte(fileName))
|
||||
|
||||
if len(path) == 0 {
|
||||
logger.Error("path should not be empty")
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/"
|
||||
|
||||
@ -527,8 +509,7 @@ func PostFileUpload(c *gin.Context) {
|
||||
tempDir += dirPath
|
||||
if err := file.MkDir(path + "/" + dirPath); err != nil {
|
||||
logger.Error("error when trying to create `"+path+"/"+dirPath+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,108 +518,94 @@ func PostFileUpload(c *gin.Context) {
|
||||
if !file.CheckNotExist(tempDir + chunkNumber) {
|
||||
if err := file.RMDir(tempDir + chunkNumber); err != nil {
|
||||
logger.Error("error when trying to remove existing `"+tempDir+chunkNumber+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
}
|
||||
|
||||
if totalChunks > 1 {
|
||||
if err := file.IsNotExistMkDir(tempDir); err != nil {
|
||||
logger.Error("error when trying to create `"+tempDir+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
|
||||
out, err := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0o644)
|
||||
if err != nil {
|
||||
logger.Error("error when trying to open `"+tempDir+chunkNumber+"` for creation", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
|
||||
defer out.Close()
|
||||
|
||||
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
|
||||
logger.Error("error when trying to write to `"+tempDir+chunkNumber+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
|
||||
fileNum, err := ioutil.ReadDir(tempDir)
|
||||
if err != nil {
|
||||
logger.Error("error when trying to read number of files under `"+tempDir+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
|
||||
if totalChunks == len(fileNum) {
|
||||
if err := file.SpliceFiles(tempDir, path, totalChunks, 1); err != nil {
|
||||
logger.Error("error when trying to splice files under `"+tempDir+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := file.RMDir(tempDir); err != nil {
|
||||
logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
go func() {
|
||||
time.Sleep(11 * time.Second)
|
||||
if err := file.RMDir(tempDir); err != nil {
|
||||
logger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
}
|
||||
} else {
|
||||
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)
|
||||
if err != nil {
|
||||
logger.Error("error when trying to open `"+path+"` for creation", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
|
||||
defer out.Close()
|
||||
|
||||
if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy
|
||||
logger.Error("error when trying to write to `"+path+"`", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
func PostFileOctet(c *gin.Context) {
|
||||
|
||||
content_length := c.Request.ContentLength
|
||||
func PostFileOctet(ctx echo.Context) error {
|
||||
content_length := ctx.Request().ContentLength
|
||||
if content_length <= 0 || content_length > 1024*1024*1024*2*1024 {
|
||||
log.Printf("content_length error\n")
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "content_length error"})
|
||||
return
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "content_length error"})
|
||||
}
|
||||
content_type_, has_key := c.Request.Header["Content-Type"]
|
||||
content_type_, has_key := ctx.Request().Header["Content-Type"]
|
||||
if !has_key {
|
||||
log.Printf("Content-Type error\n")
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error"})
|
||||
return
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error"})
|
||||
}
|
||||
if len(content_type_) != 1 {
|
||||
log.Printf("Content-Type count error\n")
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type count error"})
|
||||
return
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type count error"})
|
||||
}
|
||||
content_type := content_type_[0]
|
||||
const BOUNDARY string = "; boundary="
|
||||
loc := strings.Index(content_type, BOUNDARY)
|
||||
if loc == -1 {
|
||||
log.Printf("Content-Type error, no boundary\n")
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error, no boundary"})
|
||||
return
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Content-Type error, no boundary"})
|
||||
}
|
||||
boundary := []byte(content_type[(loc + len(BOUNDARY)):])
|
||||
log.Printf("[%s]\n\n", boundary)
|
||||
read_data := make([]byte, 1024*24)
|
||||
var read_total int = 0
|
||||
for {
|
||||
file_header, file_data, err := file.ParseFromHead(read_data, read_total, append(boundary, []byte("\r\n")...), c.Request.Body)
|
||||
file_header, file_data, err := file.ParseFromHead(read_data, read_total, append(boundary, []byte("\r\n")...), ctx.Request().Body)
|
||||
if err != nil {
|
||||
log.Printf("%v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("file :%s\n", file_header)
|
||||
//
|
||||
@ -646,16 +613,14 @@ func PostFileOctet(c *gin.Context) {
|
||||
f, err := os.OpenFile(file_header["path"]+"/"+file_header["filename"], os.O_WRONLY|os.O_CREATE, 0o644)
|
||||
if err != nil {
|
||||
log.Printf("create file fail:%v\n", err)
|
||||
return
|
||||
}
|
||||
f.Write(file_data)
|
||||
file_data = nil
|
||||
|
||||
temp_data, reach_end, err := file.ReadToBoundary(boundary, c.Request.Body, f)
|
||||
temp_data, reach_end, err := file.ReadToBoundary(boundary, ctx.Request().Body, f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
log.Printf("%v\n", err)
|
||||
return
|
||||
}
|
||||
if reach_end {
|
||||
break
|
||||
@ -665,7 +630,7 @@ func PostFileOctet(c *gin.Context) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary copy or move file
|
||||
@ -676,17 +641,15 @@ func PostFileOctet(c *gin.Context) {
|
||||
// @Param body body model.FileOperate true "type:move,copy"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/operate [post]
|
||||
func PostOperateFileOrDir(c *gin.Context) {
|
||||
func PostOperateFileOrDir(ctx echo.Context) error {
|
||||
list := model.FileOperate{}
|
||||
c.ShouldBind(&list)
|
||||
ctx.Bind(&list)
|
||||
|
||||
if len(list.Item) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)})
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
@ -701,8 +664,7 @@ func PostOperateFileOrDir(c *gin.Context) {
|
||||
if list.Type == "move" {
|
||||
mounted := service.IsMounted(list.Item[i].From)
|
||||
if mounted {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -710,7 +672,7 @@ func PostOperateFileOrDir(c *gin.Context) {
|
||||
list.TotalSize = total
|
||||
list.ProcessedSize = 0
|
||||
|
||||
uid := uuid.NewV4().String()
|
||||
uid := uuid.NewString()
|
||||
service.FileQueue.Store(uid, list)
|
||||
service.OpStrArr = append(service.OpStrArr, uid)
|
||||
if len(service.OpStrArr) == 1 {
|
||||
@ -721,7 +683,7 @@ func PostOperateFileOrDir(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary delete file
|
||||
@ -732,33 +694,30 @@ func PostOperateFileOrDir(c *gin.Context) {
|
||||
// @Param body body string true "paths eg ["/a/b/c","/d/e/f"]"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/delete [delete]
|
||||
func DeleteFile(c *gin.Context) {
|
||||
func DeleteFile(ctx echo.Context) error {
|
||||
paths := []string{}
|
||||
c.ShouldBind(&paths)
|
||||
ctx.Bind(&paths)
|
||||
if len(paths) == 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
}
|
||||
// path := c.Query("path")
|
||||
// path := ctx.QueryParam("path")
|
||||
|
||||
// paths := strings.Split(path, ",")
|
||||
for _, v := range paths {
|
||||
mounted := service.IsMounted(v)
|
||||
if mounted {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.MOUNTED_DIRECTIORIES, Message: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES), Data: common_err.GetMsg(common_err.MOUNTED_DIRECTIORIES)})
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range paths {
|
||||
err := os.RemoveAll(v)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary update file
|
||||
@ -770,34 +729,30 @@ func DeleteFile(c *gin.Context) {
|
||||
// @Param content body string true "content"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/update [put]
|
||||
func PutFileContent(c *gin.Context) {
|
||||
func PutFileContent(ctx echo.Context) error {
|
||||
fi := model.FileUpdate{}
|
||||
c.ShouldBind(&fi)
|
||||
ctx.Bind(&fi)
|
||||
|
||||
// path := c.PostForm("path")
|
||||
// content := c.PostForm("content")
|
||||
// path := ctx.FormValue("path")
|
||||
// content := ctx.FormValue("content")
|
||||
if !file.Exists(fi.FilePath) {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
}
|
||||
// err := os.Remove(path)
|
||||
f, err := os.Stat(fi.FilePath)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
}
|
||||
fm := f.Mode()
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
||||
}
|
||||
os.OpenFile(fi.FilePath, os.O_CREATE, fm)
|
||||
err = file.WriteToFullPath([]byte(fi.FileContent), fi.FilePath, fm)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary image thumbnail/original image
|
||||
@ -809,38 +764,34 @@ func PutFileContent(c *gin.Context) {
|
||||
// @Param type query string false "original,thumbnail" Enums(original,thumbnail)
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /file/image [get]
|
||||
func GetFileImage(c *gin.Context) {
|
||||
t := c.Query("type")
|
||||
path := c.Query("path")
|
||||
func GetFileImage(ctx echo.Context) error {
|
||||
t := ctx.QueryParam("type")
|
||||
path := ctx.QueryParam("path")
|
||||
if !file.Exists(path) {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
||||
}
|
||||
if t == "thumbnail" {
|
||||
f, err := file.GetImage(path, 100, 0)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
c.Writer.WriteString(string(f))
|
||||
return
|
||||
ctx.Response().Writer.Write(f)
|
||||
}
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
defer f.Close()
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
c.Writer.WriteString(string(data))
|
||||
ctx.Response().Writer.Write(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteOperateFileOrDir(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
func DeleteOperateFileOrDir(ctx echo.Context) error {
|
||||
id := ctx.Param("id")
|
||||
if id == "0" {
|
||||
service.FileQueue = sync.Map{}
|
||||
service.OpStrArr = []string{}
|
||||
@ -858,30 +809,29 @@ func DeleteOperateFileOrDir(c *gin.Context) {
|
||||
}
|
||||
|
||||
go service.MyService.Notify().SendFileOperateNotify(true)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
func GetSize(c *gin.Context) {
|
||||
|
||||
func GetSize(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
path := json["path"]
|
||||
size, err := file.GetFileOrDirSize(path)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: size})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: size})
|
||||
}
|
||||
|
||||
func GetFileCount(c *gin.Context) {
|
||||
func GetFileCount(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
path := json["path"]
|
||||
list, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: len(list)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: len(list)})
|
||||
}
|
||||
|
||||
type CenterHandler struct {
|
||||
@ -914,17 +864,16 @@ type PeerModel struct {
|
||||
RtcSupported bool `json:"rtcSupported"`
|
||||
}
|
||||
|
||||
func ConnectWebSocket(c *gin.Context) {
|
||||
peerId := c.Query("peer")
|
||||
writer := c.Writer
|
||||
request := c.Request
|
||||
key := uuid.NewV4().String()
|
||||
//peerModel := service.MyService.Peer().GetPeerByUserAgent(c.Request.UserAgent())
|
||||
func ConnectWebSocket(ctx echo.Context) error {
|
||||
peerId := ctx.QueryParam("peer")
|
||||
writer := ctx.Response().Writer
|
||||
request := ctx.Request()
|
||||
key := uuid.NewString()
|
||||
// peerModel := service.MyService.Peer().GetPeerByUserAgent(ctx.Request().UserAgent())
|
||||
peerModel := model2.PeerDriveDBModel{}
|
||||
name := service.GetName(request)
|
||||
if conn, err = upgraderFile.Upgrade(writer, request, writer.Header()); err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
client := &Client{handler: &handler, conn: conn, send: make(chan []byte, 256), ID: service.GetPeerId(request, key), IP: service.GetIP(request), Name: name, RtcSupported: true, TimerId: 0, LastBeat: time.Now()}
|
||||
if peerId != "" || len(peerModel.ID) > 0 {
|
||||
@ -937,7 +886,7 @@ func ConnectWebSocket(c *gin.Context) {
|
||||
client.Name = service.GetNameByDB(peerModel)
|
||||
}
|
||||
}
|
||||
var list = service.MyService.Peer().GetPeers()
|
||||
list := service.MyService.Peer().GetPeers()
|
||||
if len(peerModel.ID) == 0 {
|
||||
peerModel.ID = key
|
||||
peerModel.DisplayName = name.DisplayName
|
||||
@ -945,7 +894,7 @@ func ConnectWebSocket(c *gin.Context) {
|
||||
peerModel.Model = name.Model
|
||||
peerModel.OS = name.OS
|
||||
peerModel.Browser = name.Browser
|
||||
peerModel.UserAgent = c.Request.UserAgent()
|
||||
peerModel.UserAgent = ctx.Request().UserAgent()
|
||||
peerModel.IP = client.IP
|
||||
service.MyService.Peer().CreatePeer(&peerModel)
|
||||
list = append(list, peerModel)
|
||||
@ -989,7 +938,7 @@ func ConnectWebSocket(c *gin.Context) {
|
||||
for _, v := range handler.clients {
|
||||
v.send <- pby
|
||||
}
|
||||
//client.handler.broadcast <- pby
|
||||
// client.handler.broadcast <- pby
|
||||
clients := []PeerModel{}
|
||||
for _, v := range client.handler.clients {
|
||||
if _, ok := handler.clients[v.ID]; ok {
|
||||
@ -1022,31 +971,34 @@ func ConnectWebSocket(c *gin.Context) {
|
||||
// 每个 client 都挂起 2 个新的协程,监控读、写状态
|
||||
go client.writePump()
|
||||
go client.readPump()
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
var handler = CenterHandler{broadcast: make(chan []byte),
|
||||
var handler = CenterHandler{
|
||||
broadcast: make(chan []byte),
|
||||
register: make(chan *Client),
|
||||
unregister: make(chan *Client),
|
||||
clients: make(map[string]*Client)}
|
||||
clients: make(map[string]*Client),
|
||||
}
|
||||
|
||||
func init() {
|
||||
// 起个协程跑起来,监听注册、注销、消息 3 个 channel
|
||||
go handler.monitoring()
|
||||
|
||||
crontab := cron.New(cron.WithSeconds()) //精确到秒
|
||||
//定义定时器调用的任务函数
|
||||
crontab := cron.New(cron.WithSeconds()) // 精确到秒
|
||||
// 定义定时器调用的任务函数
|
||||
|
||||
task := func() {
|
||||
handler.broadcast <- []byte(`{"type":"ping"}`)
|
||||
}
|
||||
//定时任务
|
||||
spec := "*/30 * * * * ?" //cron表达式,每五秒一次
|
||||
// 定时任务
|
||||
spec := "*/30 * * * * ?" // cron表达式,每五秒一次
|
||||
// 添加定时任务,
|
||||
crontab.AddFunc(spec, task)
|
||||
// 启动定时器
|
||||
crontab.Start()
|
||||
}
|
||||
|
||||
func (c *Client) writePump() {
|
||||
defer func() {
|
||||
c.handler.unregister <- c
|
||||
@ -1101,7 +1053,7 @@ func (c *Client) readPump() {
|
||||
// otherBy, err := json.Marshal(other)
|
||||
// fmt.Println(err)
|
||||
c.handler.broadcast <- []byte(`{"type":"peer-left","peerId":"` + c.ID + `"}`)
|
||||
//c.handler.broadcast <- otherBy
|
||||
// c.handler.broadcast <- otherBy
|
||||
break
|
||||
} else if t.String() == "pong" {
|
||||
c.LastBeat = time.Now()
|
||||
@ -1126,6 +1078,7 @@ func (c *Client) readPump() {
|
||||
c.handler.broadcast <- message
|
||||
}
|
||||
}
|
||||
|
||||
func (ch *CenterHandler) monitoring() {
|
||||
for {
|
||||
select {
|
||||
@ -1145,12 +1098,13 @@ func (ch *CenterHandler) monitoring() {
|
||||
}
|
||||
}
|
||||
}
|
||||
func GetPeers(c *gin.Context) {
|
||||
|
||||
func GetPeers(ctx echo.Context) error {
|
||||
peers := service.MyService.Peer().GetPeers()
|
||||
for i := 0; i < len(peers); i++ {
|
||||
if _, ok := handler.clients[peers[i].ID]; ok {
|
||||
peers[i].Online = true
|
||||
}
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: peers})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: peers})
|
||||
}
|
||||
|
||||
@ -6,28 +6,26 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func PostNotifyMessage(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
func PostNotifyMessage(ctx echo.Context) error {
|
||||
name := ctx.Param("name")
|
||||
message := make(map[string]interface{})
|
||||
if err := c.ShouldBind(&message); err != nil {
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
|
||||
return
|
||||
if err := ctx.Bind(&message); err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
|
||||
}
|
||||
|
||||
service.MyService.Notify().SendNotify(name, message)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
func PostSystemStatusNotify(c *gin.Context) {
|
||||
func PostSystemStatusNotify(ctx echo.Context) error {
|
||||
message := make(map[string]interface{})
|
||||
if err := c.ShouldBind(&message); err != nil {
|
||||
c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
|
||||
return
|
||||
if err := ctx.Bind(&message); err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: err.Error()})
|
||||
}
|
||||
|
||||
service.MyService.Notify().SettingSystemTempData(message)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/IceWhaleTech/CasaOS/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
var upGrader = websocket.Upgrader{
|
||||
@ -24,11 +24,11 @@ var upGrader = websocket.Upgrader{
|
||||
// @Param token path string true "token"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /notify/ws [get]
|
||||
func NotifyWS(c *gin.Context) {
|
||||
//升级get请求为webSocket协议
|
||||
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
func NotifyWS(ctx echo.Context) error {
|
||||
// 升级get请求为webSocket协议
|
||||
ws, err := upGrader.Upgrade(ctx.Response().Writer, ctx.Request(), nil)
|
||||
if err != nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
defer ws.Close()
|
||||
service.WebSocketConns = append(service.WebSocketConns, ws)
|
||||
@ -41,7 +41,6 @@ func NotifyWS(c *gin.Context) {
|
||||
mt, message, err := ws.ReadMessage()
|
||||
fmt.Println(mt, message, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// @Summary 标记notify已读
|
||||
@ -51,12 +50,13 @@ func NotifyWS(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /notify/read/{id} [put]
|
||||
func PutNotifyRead(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
func PutNotifyRead(ctx echo.Context) error {
|
||||
id := ctx.Param("id")
|
||||
// if len(id) == 0 {
|
||||
// c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||
// return ctx.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
fmt.Println(id)
|
||||
service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6,25 +6,23 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func GetSearchResult(c *gin.Context) {
|
||||
func GetSearchResult(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
url := json["url"]
|
||||
|
||||
if url == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "key is empty"})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "key is empty"})
|
||||
}
|
||||
//data, err := service.MyService.Other().Search(key)
|
||||
// data, err := service.MyService.Other().Search(key)
|
||||
data, err := service.MyService.Other().AgentSearch(url)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -8,64 +10,54 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func GetRecoverStorage(c *gin.Context) {
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
t := c.Param("type")
|
||||
func GetRecoverStorage(ctx echo.Context) error {
|
||||
t := strings.TrimSuffix(ctx.Param("type"), "/")
|
||||
currentTime := time.Now().UTC()
|
||||
currentDate := time.Now().UTC().Format("2006-01-02")
|
||||
notify := make(map[string]interface{})
|
||||
event := "casaos:file:recover"
|
||||
if t == "GoogleDrive" {
|
||||
add := google_drive.Addition{}
|
||||
add.Code = c.Query("code")
|
||||
if len(add.Code) == 0 {
|
||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||
google_drive := google_drive.GetConfig()
|
||||
google_drive.Code = ctx.QueryParam("code")
|
||||
if len(google_drive.Code) == 0 {
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Code cannot be empty"
|
||||
logger.Error("Then code is empty: ", zap.String("code", add.Code), zap.Any("name", "google_drive"))
|
||||
logger.Error("Then code is empty: ", zap.String("code", google_drive.Code), zap.Any("name", "google_drive"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
return ctx.HTML(http.StatusOK, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||
}
|
||||
|
||||
add.RootFolderID = "root"
|
||||
add.ClientID = google_drive.CLIENTID
|
||||
add.ClientSecret = google_drive.CLIENTSECRET
|
||||
|
||||
var google_drive google_drive.GoogleDrive
|
||||
google_drive.Addition = add
|
||||
err := google_drive.Init(c)
|
||||
err := google_drive.Init(context.Background())
|
||||
if err != nil {
|
||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Initialization failure"
|
||||
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "google_drive"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
|
||||
username, err := google_drive.GetUserInfo(c)
|
||||
username, err := google_drive.GetUserInfo(context.Background())
|
||||
if err != nil {
|
||||
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get user information"
|
||||
logger.Error("Then get user info error: ", zap.Error(err), zap.Any("name", "google_drive"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
dmap := make(map[string]string)
|
||||
dmap["username"] = username
|
||||
configs, err := service.MyService.Storage().GetConfig()
|
||||
if err != nil {
|
||||
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get rclone config"
|
||||
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "google_drive"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
for _, v := range configs.Remotes {
|
||||
cf, err := service.MyService.Storage().GetConfigByName(v)
|
||||
@ -74,15 +66,14 @@ func GetRecoverStorage(c *gin.Context) {
|
||||
continue
|
||||
}
|
||||
if cf["type"] == "drive" && cf["username"] == dmap["username"] {
|
||||
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||
if err != nil {
|
||||
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
||||
}
|
||||
notify["status"] = "warn"
|
||||
notify["message"] = "The same configuration has been added"
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||
}
|
||||
}
|
||||
if len(username) > 0 {
|
||||
@ -90,11 +81,10 @@ func GetRecoverStorage(c *gin.Context) {
|
||||
username = a[0]
|
||||
}
|
||||
|
||||
//username = fileutil.NameAccumulation(username, "/mnt")
|
||||
username += "_google_drive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
dmap["client_id"] = add.ClientID
|
||||
dmap["client_secret"] = add.ClientSecret
|
||||
dmap["client_id"] = google_drive.ClientID
|
||||
dmap["client_secret"] = google_drive.ClientSecret
|
||||
dmap["scope"] = "drive"
|
||||
dmap["mount_point"] = "/mnt/" + username
|
||||
dmap["token"] = `{"access_token":"` + google_drive.AccessToken + `","token_type":"Bearer","refresh_token":"` + google_drive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*1).Add(time.Minute*50).Format("15:04:05") + `Z"}`
|
||||
@ -104,52 +94,45 @@ func GetRecoverStorage(c *gin.Context) {
|
||||
notify["status"] = "success"
|
||||
notify["message"] = "Success"
|
||||
notify["driver"] = "GoogleDrive"
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
} else if t == "Dropbox" {
|
||||
add := dropbox.Addition{}
|
||||
add.Code = c.Query("code")
|
||||
if len(add.Code) == 0 {
|
||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||
dropbox := dropbox.GetConfig()
|
||||
|
||||
dropbox.Code = ctx.QueryParam("code")
|
||||
if len(dropbox.Code) == 0 {
|
||||
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Code cannot be empty"
|
||||
logger.Error("Then code is empty error: ", zap.String("code", add.Code), zap.Any("name", "dropbox"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
logger.Error("Then code is empty error: ", zap.String("code", dropbox.Code), zap.Any("name", "dropbox"))
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||
}
|
||||
add.RootFolderID = ""
|
||||
add.AppKey = dropbox.APPKEY
|
||||
add.AppSecret = dropbox.APPSECRET
|
||||
var dropbox dropbox.Dropbox
|
||||
dropbox.Addition = add
|
||||
err := dropbox.Init(c)
|
||||
err := dropbox.Init(context.Background())
|
||||
if err != nil {
|
||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Initialization failure"
|
||||
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "dropbox"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
username, err := dropbox.GetUserInfo(c)
|
||||
username, err := dropbox.GetUserInfo(context.Background())
|
||||
if err != nil {
|
||||
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get user information"
|
||||
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "dropbox"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
dmap := make(map[string]string)
|
||||
dmap["username"] = username
|
||||
|
||||
configs, err := service.MyService.Storage().GetConfig()
|
||||
if err != nil {
|
||||
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get rclone config"
|
||||
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "dropbox"))
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
for _, v := range configs.Remotes {
|
||||
cf, err := service.MyService.Storage().GetConfigByName(v)
|
||||
@ -158,16 +141,14 @@ func GetRecoverStorage(c *gin.Context) {
|
||||
continue
|
||||
}
|
||||
if cf["type"] == "dropbox" && cf["username"] == dmap["username"] {
|
||||
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||
if err != nil {
|
||||
if err := service.MyService.Storage().CheckAndMountByName(v); err != nil {
|
||||
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
||||
}
|
||||
|
||||
notify["status"] = "warn"
|
||||
notify["message"] = "The same configuration has been added"
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
return
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||
}
|
||||
}
|
||||
if len(username) > 0 {
|
||||
@ -176,30 +157,91 @@ func GetRecoverStorage(c *gin.Context) {
|
||||
}
|
||||
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
dmap["client_id"] = add.AppKey
|
||||
dmap["client_secret"] = add.AppSecret
|
||||
dmap["client_id"] = dropbox.AppKey
|
||||
dmap["client_secret"] = dropbox.AppSecret
|
||||
dmap["token"] = `{"access_token":"` + dropbox.AccessToken + `","token_type":"bearer","refresh_token":"` + dropbox.Addition.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||
dmap["mount_point"] = "/mnt/" + username
|
||||
// data.SetValue(username, "type", "dropbox")
|
||||
// data.SetValue(username, "client_id", add.AppKey)
|
||||
// data.SetValue(username, "client_secret", add.AppSecret)
|
||||
// data.SetValue(username, "mount_point", "/mnt/"+username)
|
||||
|
||||
// data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`)
|
||||
// e = data.Save()
|
||||
// if e != nil {
|
||||
// c.String(200, `<p>保存配置失败:`+e.Error()+`</p>`)
|
||||
|
||||
// return
|
||||
// }
|
||||
service.MyService.Storage().CreateConfig(dmap, username, "dropbox")
|
||||
service.MyService.Storage().MountStorage("/mnt/"+username, username+":")
|
||||
|
||||
notify["status"] = "success"
|
||||
notify["message"] = "Success"
|
||||
notify["driver"] = "Dropbox"
|
||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
} else if t == "Onedrive" {
|
||||
onedrive := onedrive.GetConfig()
|
||||
onedrive.Code = ctx.QueryParam("code")
|
||||
if len(onedrive.Code) == 0 {
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Code cannot be empty"
|
||||
logger.Error("Then code is empty error: ", zap.String("code", onedrive.Code), zap.Any("name", "onedrive"))
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||
}
|
||||
err := onedrive.Init(context.Background())
|
||||
if err != nil {
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Initialization failure"
|
||||
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
username, driveId, driveType, err := onedrive.GetInfo(context.Background())
|
||||
if err != nil {
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get user information"
|
||||
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
dmap := make(map[string]string)
|
||||
dmap["username"] = username
|
||||
|
||||
configs, err := service.MyService.Storage().GetConfig()
|
||||
if err != nil {
|
||||
notify["status"] = "fail"
|
||||
notify["message"] = "Failed to get rclone config"
|
||||
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||
}
|
||||
for _, v := range configs.Remotes {
|
||||
cf, err := service.MyService.Storage().GetConfigByName(v)
|
||||
if err != nil {
|
||||
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
||||
continue
|
||||
}
|
||||
if cf["type"] == "onedrive" && cf["username"] == dmap["username"] {
|
||||
if err := service.MyService.Storage().CheckAndMountByName(v); err != nil {
|
||||
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
||||
}
|
||||
|
||||
notify["status"] = "warn"
|
||||
notify["message"] = "The same configuration has been added"
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
return ctx.HTML(http.StatusOK, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||
}
|
||||
}
|
||||
if len(username) > 0 {
|
||||
a := strings.Split(username, "@")
|
||||
username = a[0]
|
||||
}
|
||||
username += "_onedrive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
dmap["client_id"] = onedrive.ClientID
|
||||
dmap["client_secret"] = onedrive.ClientSecret
|
||||
dmap["token"] = `{"access_token":"` + onedrive.AccessToken + `","token_type":"bearer","refresh_token":"` + onedrive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||
dmap["mount_point"] = "/mnt/" + username
|
||||
dmap["drive_id"] = driveId
|
||||
dmap["drive_type"] = driveType
|
||||
service.MyService.Storage().CreateConfig(dmap, username, "onedrive")
|
||||
service.MyService.Storage().MountStorage("/mnt/"+username, username+":")
|
||||
|
||||
notify["status"] = "success"
|
||||
notify["message"] = "Success"
|
||||
notify["driver"] = "Onedrive"
|
||||
service.MyService.Notify().SendNotify(event, notify)
|
||||
}
|
||||
|
||||
c.String(200, `<p>Just close the page</p><script>window.close()</script>`)
|
||||
return ctx.HTML(200, `<p>Just close the page</p><script>window.close()</script>`)
|
||||
}
|
||||
|
||||
@ -16,32 +16,29 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/systemctl"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/samba"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// service
|
||||
|
||||
func GetSambaStatus(c *gin.Context) {
|
||||
func GetSambaStatus(ctx echo.Context) error {
|
||||
if status, err := systemctl.IsServiceRunning("smbd"); err != nil || !status {
|
||||
c.JSON(http.StatusInternalServerError, model.Result{
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{
|
||||
Success: common_err.SERVICE_NOT_RUNNING,
|
||||
Message: common_err.GetMsg(common_err.SERVICE_NOT_RUNNING),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
needInit := true
|
||||
@ -53,10 +50,10 @@ func GetSambaStatus(c *gin.Context) {
|
||||
}
|
||||
data := make(map[string]string, 1)
|
||||
data["need_init"] = fmt.Sprintf("%v", needInit)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
func GetSambaSharesList(c *gin.Context) {
|
||||
func GetSambaSharesList(ctx echo.Context) error {
|
||||
shares := service.MyService.Shares().GetSharesList()
|
||||
shareList := []model.Shares{}
|
||||
for _, v := range shares {
|
||||
@ -66,28 +63,24 @@ func GetSambaSharesList(c *gin.Context) {
|
||||
ID: v.ID,
|
||||
})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList})
|
||||
}
|
||||
|
||||
func PostSambaSharesCreate(c *gin.Context) {
|
||||
func PostSambaSharesCreate(ctx echo.Context) error {
|
||||
shares := []model.Shares{}
|
||||
c.ShouldBindJSON(&shares)
|
||||
ctx.Bind(&shares)
|
||||
for _, v := range shares {
|
||||
if v.Path == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||
}
|
||||
if !file.Exists(v.Path) {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||
}
|
||||
if len(service.MyService.Shares().GetSharesByPath(v.Path)) > 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)})
|
||||
}
|
||||
if len(service.MyService.Shares().GetSharesByPath(filepath.Base(v.Path))) > 0 {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_NAME_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_NAME_ALREADY_EXISTS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_NAME_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_NAME_ALREADY_EXISTS)})
|
||||
}
|
||||
}
|
||||
for _, v := range shares {
|
||||
@ -99,21 +92,20 @@ func PostSambaSharesCreate(c *gin.Context) {
|
||||
service.MyService.Shares().CreateShare(shareDBModel)
|
||||
}
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares})
|
||||
}
|
||||
|
||||
func DeleteSambaShares(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
func DeleteSambaShares(ctx echo.Context) error {
|
||||
id := ctx.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||
}
|
||||
service.MyService.Shares().DeleteShare(id)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||
}
|
||||
|
||||
// client
|
||||
func GetSambaConnectionsList(c *gin.Context) {
|
||||
func GetSambaConnectionsList(ctx echo.Context) error {
|
||||
connections := service.MyService.Connections().GetConnectionsList()
|
||||
connectionList := []model.Connections{}
|
||||
for _, v := range connections {
|
||||
@ -125,49 +117,46 @@ func GetSambaConnectionsList(c *gin.Context) {
|
||||
MountPoint: v.MountPoint,
|
||||
})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
|
||||
}
|
||||
|
||||
func PostSambaConnectionsCreate(c *gin.Context) {
|
||||
func PostSambaConnectionsCreate(ctx echo.Context) error {
|
||||
connection := model.Connections{}
|
||||
c.ShouldBindJSON(&connection)
|
||||
ctx.Bind(&connection)
|
||||
if connection.Port == "" {
|
||||
connection.Port = "445"
|
||||
}
|
||||
if connection.Username == "" || connection.Host == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
|
||||
}
|
||||
|
||||
if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Password); !ok {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
|
||||
return
|
||||
}
|
||||
if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Username); !ok {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
if !ip_helper.IsIPv4(connection.Host) && !ip_helper.IsIPv6(connection.Host) {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
if ok, _ := regexp.MatchString("^[0-9]{1,6}$", connection.Port); !ok {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
// if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Password); !ok {
|
||||
// return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
|
||||
// return
|
||||
// }
|
||||
// if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Username); !ok {
|
||||
// return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
// if !ip_helper.IsIPv4(connection.Host) && !ip_helper.IsIPv6(connection.Host) {
|
||||
// return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
// if ok, _ := regexp.MatchString("^[0-9]{1,6}$", connection.Port); !ok {
|
||||
// return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||
// return
|
||||
// }
|
||||
|
||||
connection.Host = strings.Split(connection.Host, "/")[0]
|
||||
// check is exists
|
||||
connections := service.MyService.Connections().GetConnectionByHost(connection.Host)
|
||||
if len(connections) > 0 {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)})
|
||||
}
|
||||
// check connect is ok
|
||||
directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
|
||||
connectionDBModel := model2.ConnectionsDBModel{}
|
||||
@ -189,21 +178,19 @@ func PostSambaConnectionsCreate(c *gin.Context) {
|
||||
service.MyService.Connections().CreateConnection(&connectionDBModel)
|
||||
|
||||
connection.ID = connectionDBModel.ID
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection})
|
||||
}
|
||||
|
||||
func DeleteSambaConnections(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
func DeleteSambaConnections(ctx echo.Context) error {
|
||||
id := ctx.Param("id")
|
||||
connection := service.MyService.Connections().GetConnectionByID(id)
|
||||
if connection.Username == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)})
|
||||
}
|
||||
mountPointList, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
|
||||
//mountPointList, err := service.MyService.System().GetDirPath(connection.MountPoint)
|
||||
// mountPointList, err := service.MyService.System().GetDirPath(connection.MountPoint)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
baseHostPath := "/mnt/" + connection.Host
|
||||
for _, v := range mountPointList {
|
||||
@ -211,16 +198,14 @@ func DeleteSambaConnections(c *gin.Context) {
|
||||
err := service.MyService.Connections().UnmountSmaba(baseHostPath + "/" + v)
|
||||
if err != nil {
|
||||
logger.Error("unmount smaba error", zap.Error(err), zap.Any("path", baseHostPath+"/"+v))
|
||||
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
dir, _ := ioutil.ReadDir(connection.MountPoint)
|
||||
if len(dir) == 0 {
|
||||
os.RemoveAll(connection.MountPoint)
|
||||
}
|
||||
service.MyService.Connections().DeleteConnection(id)
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ import (
|
||||
"testing"
|
||||
|
||||
v1 "github.com/IceWhaleTech/CasaOS/route/v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/labstack/echo/v4"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
@ -54,17 +54,22 @@ func performRequest(r http.Handler, method, path string) *httptest.ResponseRecor
|
||||
func TestGetSambaSharesList(t *testing.T) {
|
||||
t.Skip("This test is always failing. Skipped to unblock releasing - MUST FIX!")
|
||||
|
||||
gin.SetMode(gin.TestMode)
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
|
||||
executeWithContext := func() *httptest.ResponseRecorder {
|
||||
response := httptest.NewRecorder()
|
||||
con, ginEngine := gin.CreateTestContext(response)
|
||||
// con, ginEngine := gin.CreateTestContext(response)
|
||||
e := echo.New()
|
||||
|
||||
requestUrl := "/v1/samba/shares"
|
||||
httpRequest, _ := http.NewRequest("GET", requestUrl, nil)
|
||||
|
||||
con := e.NewContext(httpRequest, response)
|
||||
|
||||
v1.GetSambaSharesList(con)
|
||||
ginEngine.ServeHTTP(response, httpRequest)
|
||||
e.ServeHTTP(response, httpRequest)
|
||||
return response
|
||||
}
|
||||
|
||||
|
||||
@ -10,8 +10,9 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
sshHelper "github.com/IceWhaleTech/CasaOS-Common/utils/ssh"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/ssh"
|
||||
@ -26,44 +27,41 @@ var upgrader = websocket.Upgrader{
|
||||
HandshakeTimeout: time.Duration(time.Second * 5),
|
||||
}
|
||||
|
||||
func PostSshLogin(c *gin.Context) {
|
||||
func PostSshLogin(ctx echo.Context) error {
|
||||
j := make(map[string]string)
|
||||
c.ShouldBind(&j)
|
||||
ctx.Bind(&j)
|
||||
userName := j["username"]
|
||||
password := j["password"]
|
||||
port := j["port"]
|
||||
if userName == "" || password == "" || port == "" {
|
||||
c.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"})
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"})
|
||||
}
|
||||
_, err := sshHelper.NewSshClient(userName, password, port)
|
||||
if err != nil {
|
||||
c.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."})
|
||||
logger.Error("connect ssh error", zap.Any("error", err))
|
||||
return
|
||||
return ctx.JSON(common_err.CLIENT_ERROR, modelCommon.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: "Please check if the username and port are correct, and make sure that ssh server is installed."})
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, modelCommon.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, modelCommon.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
func WsSsh(c *gin.Context) {
|
||||
func WsSsh(ctx echo.Context) error {
|
||||
_, e := exec.LookPath("ssh")
|
||||
if e != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR, modelCommon.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"})
|
||||
return
|
||||
return ctx.JSON(common_err.SERVICE_ERROR, modelCommon.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"})
|
||||
}
|
||||
|
||||
userName := c.Query("username")
|
||||
password := c.Query("password")
|
||||
port := c.Query("port")
|
||||
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||
userName := ctx.QueryParam("username")
|
||||
password := ctx.QueryParam("password")
|
||||
port := ctx.QueryParam("port")
|
||||
wsConn, _ := upgrader.Upgrade(ctx.Response().Writer, ctx.Request(), nil)
|
||||
logBuff := new(bytes.Buffer)
|
||||
|
||||
quitChan := make(chan bool, 3)
|
||||
// user := ""
|
||||
// password := ""
|
||||
var login int = 1
|
||||
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
|
||||
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
|
||||
cols, _ := strconv.Atoi(utils.DefaultQuery(ctx, "cols", "200"))
|
||||
rows, _ := strconv.Atoi(utils.DefaultQuery(ctx, "rows", "32"))
|
||||
var client *ssh.Client
|
||||
for login != 0 {
|
||||
|
||||
@ -93,4 +91,5 @@ func WsSsh(c *gin.Context) {
|
||||
go ssConn.SessionWait(quitChan)
|
||||
|
||||
<-quitChan
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -18,12 +19,14 @@ import (
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/IceWhaleTech/CasaOS/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// @Summary check version
|
||||
@ -33,7 +36,7 @@ import (
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/version/check [get]
|
||||
func GetSystemCheckVersion(c *gin.Context) {
|
||||
func GetSystemCheckVersion(ctx echo.Context) error {
|
||||
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
|
||||
if need {
|
||||
installLog := model2.AppNotify{}
|
||||
@ -49,7 +52,7 @@ func GetSystemCheckVersion(c *gin.Context) {
|
||||
data["need_update"] = need
|
||||
data["version"] = version
|
||||
data["current_version"] = common.VERSION
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
// @Summary 系统信息
|
||||
@ -59,12 +62,12 @@ func GetSystemCheckVersion(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/update [post]
|
||||
func SystemUpdate(c *gin.Context) {
|
||||
func SystemUpdate(ctx echo.Context) error {
|
||||
need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion())
|
||||
if need {
|
||||
service.MyService.System().UpdateSystemVersion(version.Version)
|
||||
}
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary get logs
|
||||
@ -74,13 +77,13 @@ func SystemUpdate(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/error/logs [get]
|
||||
func GetCasaOSErrorLogs(c *gin.Context) {
|
||||
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
|
||||
func GetCasaOSErrorLogs(ctx echo.Context) error {
|
||||
line, _ := strconv.Atoi(utils.DefaultQuery(ctx, "line", "100"))
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
|
||||
}
|
||||
|
||||
// 系统配置
|
||||
func GetSystemConfigDebug(c *gin.Context) {
|
||||
func GetSystemConfigDebug(ctx echo.Context) error {
|
||||
array := service.MyService.System().GetSystemConfigDebug()
|
||||
disk := service.MyService.System().GetDiskInfo()
|
||||
sys := service.MyService.System().GetSysInfo()
|
||||
@ -98,7 +101,7 @@ func GetSystemConfigDebug(c *gin.Context) {
|
||||
|
||||
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
||||
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
|
||||
}
|
||||
|
||||
// @Summary get casaos server port
|
||||
@ -108,8 +111,8 @@ func GetSystemConfigDebug(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/port [get]
|
||||
func GetCasaOSPort(c *gin.Context) {
|
||||
c.JSON(common_err.SUCCESS,
|
||||
func GetCasaOSPort(ctx echo.Context) error {
|
||||
return ctx.JSON(common_err.SUCCESS,
|
||||
model.Result{
|
||||
Success: common_err.SUCCESS,
|
||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||
@ -125,31 +128,29 @@ func GetCasaOSPort(c *gin.Context) {
|
||||
// @Param port json string true "port"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/port [put]
|
||||
func PutCasaOSPort(c *gin.Context) {
|
||||
func PutCasaOSPort(ctx echo.Context) error {
|
||||
json := make(map[string]string)
|
||||
c.ShouldBind(&json)
|
||||
ctx.Bind(&json)
|
||||
portStr := json["port"]
|
||||
portNumber, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
c.JSON(common_err.SERVICE_ERROR,
|
||||
return ctx.JSON(common_err.SERVICE_ERROR,
|
||||
model.Result{
|
||||
Success: common_err.SERVICE_ERROR,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
isAvailable := port.IsPortAvailable(portNumber, "tcp")
|
||||
if !isAvailable {
|
||||
c.JSON(common_err.SERVICE_ERROR,
|
||||
return ctx.JSON(common_err.SERVICE_ERROR,
|
||||
model.Result{
|
||||
Success: common_err.PORT_IS_OCCUPIED,
|
||||
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
|
||||
})
|
||||
return
|
||||
}
|
||||
service.MyService.System().UpSystemPort(strconv.Itoa(portNumber))
|
||||
c.JSON(common_err.SUCCESS,
|
||||
return ctx.JSON(common_err.SUCCESS,
|
||||
model.Result{
|
||||
Success: common_err.SUCCESS,
|
||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||
@ -163,8 +164,9 @@ func PutCasaOSPort(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/restart [post]
|
||||
func PostKillCasaOS(c *gin.Context) {
|
||||
func PostKillCasaOS(ctx echo.Context) error {
|
||||
os.Exit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
// @Summary get system hardware info
|
||||
@ -174,20 +176,20 @@ func PostKillCasaOS(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/hardware/info [get]
|
||||
func GetSystemHardwareInfo(c *gin.Context) {
|
||||
func GetSystemHardwareInfo(ctx echo.Context) error {
|
||||
data := make(map[string]string, 1)
|
||||
data["drive_model"] = service.MyService.System().GetDeviceTree()
|
||||
data["arch"] = runtime.GOARCH
|
||||
|
||||
if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 {
|
||||
|
||||
c.JSON(common_err.SUCCESS,
|
||||
return ctx.JSON(common_err.SUCCESS,
|
||||
model.Result{
|
||||
Success: common_err.SUCCESS,
|
||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// @Summary system utilization
|
||||
@ -197,7 +199,7 @@ func GetSystemHardwareInfo(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/utilization [get]
|
||||
func GetSystemUtilization(c *gin.Context) {
|
||||
func GetSystemUtilization(ctx echo.Context) error {
|
||||
data := make(map[string]interface{})
|
||||
cpu := service.MyService.System().GetCpuPercent()
|
||||
num := service.MyService.System().GetCpuCoreNum()
|
||||
@ -241,7 +243,7 @@ func GetSystemUtilization(c *gin.Context) {
|
||||
data[key.(string)] = value
|
||||
return true
|
||||
})
|
||||
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return ctx.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
// @Summary get cpu info
|
||||
@ -251,13 +253,13 @@ func GetSystemUtilization(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/cpu [get]
|
||||
func GetSystemCupInfo(c *gin.Context) {
|
||||
func GetSystemCupInfo(ctx echo.Context) error {
|
||||
cpu := service.MyService.System().GetCpuPercent()
|
||||
num := service.MyService.System().GetCpuCoreNum()
|
||||
data := make(map[string]interface{})
|
||||
data["percent"] = cpu
|
||||
data["num"] = num
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
// @Summary get mem info
|
||||
@ -267,9 +269,9 @@ func GetSystemCupInfo(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/mem [get]
|
||||
func GetSystemMemInfo(c *gin.Context) {
|
||||
func GetSystemMemInfo(ctx echo.Context) error {
|
||||
mem := service.MyService.System().GetMemInfo()
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mem})
|
||||
}
|
||||
|
||||
// @Summary get disk info
|
||||
@ -279,9 +281,9 @@ func GetSystemMemInfo(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/disk [get]
|
||||
func GetSystemDiskInfo(c *gin.Context) {
|
||||
func GetSystemDiskInfo(ctx echo.Context) error {
|
||||
disk := service.MyService.System().GetDiskInfo()
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk})
|
||||
}
|
||||
|
||||
// @Summary get Net info
|
||||
@ -291,7 +293,7 @@ func GetSystemDiskInfo(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/net [get]
|
||||
func GetSystemNetInfo(c *gin.Context) {
|
||||
func GetSystemNetInfo(ctx echo.Context) error {
|
||||
netList := service.MyService.System().GetNetInfo()
|
||||
newNet := []model.IOCountersStat{}
|
||||
for _, n := range netList {
|
||||
@ -306,35 +308,36 @@ func GetSystemNetInfo(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
|
||||
}
|
||||
|
||||
func GetSystemProxy(c *gin.Context) {
|
||||
url := c.Query("url")
|
||||
func GetSystemProxy(ctx echo.Context) error {
|
||||
url := ctx.QueryParam("url")
|
||||
resp, err := http2.Get(url, 30*time.Second)
|
||||
if err != nil {
|
||||
return
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
for k, v := range c.Request.Header {
|
||||
c.Header(k, v[0])
|
||||
for k, v := range ctx.Request().Header {
|
||||
ctx.Request().Header.Add(k, v[0])
|
||||
}
|
||||
rda, _ := ioutil.ReadAll(resp.Body)
|
||||
// json.NewEncoder(c.Writer).Encode(json.RawMessage(string(rda)))
|
||||
// 响应状态码
|
||||
c.Writer.WriteHeader(resp.StatusCode)
|
||||
ctx.Response().Writer.WriteHeader(resp.StatusCode)
|
||||
// 复制转发的响应Body到响应Body
|
||||
io.Copy(c.Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
|
||||
io.Copy(ctx.Response().Writer, ioutil.NopCloser(bytes.NewBuffer(rda)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func PutSystemState(c *gin.Context) {
|
||||
state := c.Param("state")
|
||||
func PutSystemState(ctx echo.Context) error {
|
||||
state := ctx.Param("state")
|
||||
if strings.ToLower(state) == "off" {
|
||||
service.MyService.System().SystemShutdown()
|
||||
} else if strings.ToLower(state) == "restart" {
|
||||
service.MyService.System().SystemReboot()
|
||||
}
|
||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: "The operation will be completed shortly."})
|
||||
}
|
||||
|
||||
// @Summary 获取一个可用端口
|
||||
@ -345,8 +348,8 @@ func PutSystemState(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /app/getport [get]
|
||||
func GetPort(c *gin.Context) {
|
||||
t := c.DefaultQuery("type", "tcp")
|
||||
func GetPort(ctx echo.Context) error {
|
||||
t := utils.DefaultQuery(ctx, "type", "tcp")
|
||||
var p int
|
||||
ok := true
|
||||
for ok {
|
||||
@ -354,7 +357,7 @@ func GetPort(c *gin.Context) {
|
||||
ok = !port.IsPortAvailable(p, t)
|
||||
}
|
||||
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
|
||||
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
|
||||
return ctx.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
|
||||
}
|
||||
|
||||
// @Summary 检查端口是否可用
|
||||
@ -366,8 +369,17 @@ func GetPort(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /app/check/{port} [get]
|
||||
func PortCheck(c *gin.Context) {
|
||||
p, _ := strconv.Atoi(c.Param("port"))
|
||||
t := c.DefaultQuery("type", "tcp")
|
||||
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
|
||||
func PortCheck(ctx echo.Context) error {
|
||||
p, _ := strconv.Atoi(ctx.Param("port"))
|
||||
t := utils.DefaultQuery(ctx, "type", "tcp")
|
||||
return ctx.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
|
||||
}
|
||||
|
||||
func GetSystemEntry(ctx echo.Context) error {
|
||||
entry := service.MyService.System().GetSystemEntry()
|
||||
str := json.RawMessage(entry)
|
||||
if !gjson.ValidBytes(str) {
|
||||
return ctx.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: entry, Data: json.RawMessage("[]")})
|
||||
}
|
||||
return ctx.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: str})
|
||||
}
|
||||
|
||||
313
route/v1/zerotier.go
Normal file
313
route/v1/zerotier.go
Normal file
@ -0,0 +1,313 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func ZerotierProxy(ctx echo.Context) error {
|
||||
// Read the port number from the file
|
||||
w := ctx.Response().Writer
|
||||
r := ctx.Request()
|
||||
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Get the request path and remove "/zt"
|
||||
path := strings.TrimPrefix(r.URL.Path, "/v1/zt")
|
||||
fmt.Println(path)
|
||||
|
||||
// Build the target URL
|
||||
targetURL := fmt.Sprintf("http://localhost:%s%s", strings.TrimSpace(string(port)), path)
|
||||
|
||||
// Create a new request
|
||||
req, err := http.NewRequest(r.Method, targetURL, r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Add the X-ZT1-AUTH header
|
||||
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
|
||||
|
||||
copyHeaders(req.Header, r.Header)
|
||||
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
copyHeaders(w.Header(), resp.Header)
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Return the response to the client
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
w.Write(respBody)
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyHeaders(destination, source http.Header) {
|
||||
for key, values := range source {
|
||||
for _, value := range values {
|
||||
destination.Add(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CheckNetwork() {
|
||||
logger.Info("start check network")
|
||||
respBody, err := httper.ZTGet("/controller/network")
|
||||
if err != nil {
|
||||
logger.Error("get network error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
networkId := ""
|
||||
address := ""
|
||||
networkNames := gjson.ParseBytes(respBody).Array()
|
||||
routers := ""
|
||||
for _, v := range networkNames {
|
||||
res, err := httper.ZTGet("/controller/network/" + v.Str)
|
||||
if err != nil {
|
||||
logger.Error("get network error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
name := gjson.GetBytes(res, "name").Str
|
||||
if name == common.RANW_NAME {
|
||||
networkId = gjson.GetBytes(res, "id").Str
|
||||
routers = gjson.GetBytes(res, "routes.0.target").Str
|
||||
break
|
||||
}
|
||||
}
|
||||
ip, s, e, c := getZTIP(routers)
|
||||
logger.Info("ip", zap.Any("ip", ip))
|
||||
if len(networkId) == 0 {
|
||||
if len(address) == 0 {
|
||||
address = GetAddress()
|
||||
}
|
||||
networkId = CreateNet(address, s, e, c)
|
||||
}
|
||||
res, err := httper.ZTGet("/network")
|
||||
if err != nil {
|
||||
logger.Error("get network error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
joined := false
|
||||
networks := gjson.GetBytes(res, "#.id").Array()
|
||||
for _, v := range networks {
|
||||
if v.Str == networkId {
|
||||
joined = true
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Info("joined", zap.Any("joined", joined))
|
||||
if !joined {
|
||||
JoinAndUpdateNet(address, networkId, ip)
|
||||
}
|
||||
}
|
||||
|
||||
func GetAddress() string {
|
||||
nodeRes, err := httper.ZTGet("/status")
|
||||
if err != nil {
|
||||
logger.Error("get status error", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
return gjson.GetBytes(nodeRes, "address").String()
|
||||
}
|
||||
|
||||
func JoinAndUpdateNet(address, networkId, ip string) {
|
||||
logger.Info("start join network", zap.Any("ip", ip))
|
||||
_, err := httper.ZTPost("/network/"+networkId, "")
|
||||
if err != nil {
|
||||
logger.Error(" get network error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
if len(address) == 0 {
|
||||
address = GetAddress()
|
||||
}
|
||||
b := `{
|
||||
"authorized": true,
|
||||
"activeBridge": true,
|
||||
"ipAssignments": [
|
||||
"` + ip + `"
|
||||
]
|
||||
}`
|
||||
_, err = httper.ZTPost("/controller/network/"+networkId+"/member/"+address, b)
|
||||
if err != nil {
|
||||
logger.Error("join network error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func CreateNet(address, s, e, c string) string {
|
||||
body := `{
|
||||
"name": "` + common.RANW_NAME + `",
|
||||
"private": false,
|
||||
"v4AssignMode": {
|
||||
"zt": true
|
||||
},
|
||||
"ipAssignmentPools": [
|
||||
{
|
||||
"ipRangeStart": "` + s + `",
|
||||
"ipRangeEnd": "` + e + `"
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"target": "` + c + `"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"etherType": 2048,
|
||||
"not": true,
|
||||
"or": false,
|
||||
"type": "MATCH_ETHERTYPE"
|
||||
},
|
||||
{
|
||||
"etherType": 2054,
|
||||
"not": true,
|
||||
"or": false,
|
||||
"type": "MATCH_ETHERTYPE"
|
||||
},
|
||||
{
|
||||
"etherType": 34525,
|
||||
"not": true,
|
||||
"or": false,
|
||||
"type": "MATCH_ETHERTYPE"
|
||||
},
|
||||
{
|
||||
"type": "ACTION_DROP"
|
||||
},
|
||||
{
|
||||
"type": "ACTION_ACCEPT"
|
||||
}
|
||||
],
|
||||
"v6AssignMode": {
|
||||
"rfc4193": true
|
||||
}
|
||||
}`
|
||||
createRes, err := httper.ZTPost("/controller/network/"+address+"______", body)
|
||||
if err != nil {
|
||||
logger.Error("post network error", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
return gjson.GetBytes(createRes, "id").Str
|
||||
}
|
||||
|
||||
func GetZTIPs() []gjson.Result {
|
||||
res, err := httper.ZTGet("/network")
|
||||
if err != nil {
|
||||
logger.Error("get network error", zap.Error(err))
|
||||
return []gjson.Result{}
|
||||
}
|
||||
a := gjson.GetBytes(res, "#.routes.0.target")
|
||||
return a.Array()
|
||||
}
|
||||
|
||||
func getZTIP(routes string) (ip, start, end, cidr string) {
|
||||
excluded := GetZTIPs()
|
||||
cidrs := []string{
|
||||
"10.147.11.0/24",
|
||||
"10.147.12.0/24",
|
||||
"10.147.13.0/24",
|
||||
"10.147.14.0/24",
|
||||
"10.147.15.0/24",
|
||||
"10.147.16.0/24",
|
||||
"10.147.17.0/24",
|
||||
"10.147.18.0/24",
|
||||
"10.147.19.0/24",
|
||||
"10.147.20.0/24",
|
||||
"10.240.0.0/16",
|
||||
"10.241.0.0/16",
|
||||
"10.242.0.0/16",
|
||||
"10.243.0.0/16",
|
||||
"10.244.0.0/16",
|
||||
"10.245.0.0/16",
|
||||
"10.246.0.0/16",
|
||||
"10.247.0.0/16",
|
||||
"10.248.0.0/16",
|
||||
"10.249.0.0/16",
|
||||
"172.21.0.0/16",
|
||||
"172.22.0.0/16",
|
||||
"172.23.0.0/16",
|
||||
"172.24.0.0/16",
|
||||
"172.25.0.0/16",
|
||||
"172.26.0.0/16",
|
||||
"172.27.0.0/16",
|
||||
"172.28.0.0/16",
|
||||
"172.29.0.0/16",
|
||||
"172.30.0.0/16",
|
||||
}
|
||||
filteredCidrs := make([]string, 0)
|
||||
if len(routes) > 0 {
|
||||
filteredCidrs = append(filteredCidrs, routes)
|
||||
} else {
|
||||
for _, cidr := range cidrs {
|
||||
isExcluded := false
|
||||
for _, excludedIP := range excluded {
|
||||
if cidr == excludedIP.Str {
|
||||
isExcluded = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isExcluded {
|
||||
filteredCidrs = append(filteredCidrs, cidr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
ip = ""
|
||||
if len(filteredCidrs) > 0 {
|
||||
randomIndex := rnd.Intn(len(filteredCidrs))
|
||||
selectedCIDR := filteredCidrs[randomIndex]
|
||||
_, ipNet, err := net.ParseCIDR(selectedCIDR)
|
||||
if err != nil {
|
||||
logger.Error("ParseCIDR error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
cidr = selectedCIDR
|
||||
startIP := ipNet.IP
|
||||
endIP := make(net.IP, len(startIP))
|
||||
copy(endIP, startIP)
|
||||
|
||||
for i := range startIP {
|
||||
endIP[i] |= ^ipNet.Mask[i]
|
||||
}
|
||||
startIP[3] = 1
|
||||
start = startIP.String()
|
||||
endIP[3] = 254
|
||||
end = endIP.String()
|
||||
ipt := ipNet
|
||||
ipt.IP[3] = 1
|
||||
ip = ipt.IP.String()
|
||||
return
|
||||
} else {
|
||||
logger.Error("No available CIDR found")
|
||||
}
|
||||
return
|
||||
}
|
||||
64
route/v2.go
64
route/v2.go
@ -1,6 +1,7 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -10,9 +11,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
|
||||
v2Route "github.com/IceWhaleTech/CasaOS/route/v2"
|
||||
"github.com/deepmap/oapi-codegen/pkg/middleware"
|
||||
@ -28,7 +30,6 @@ var (
|
||||
V2APIPath string
|
||||
V2DocPath string
|
||||
V3FilePath string
|
||||
V4DirPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -47,7 +48,6 @@ func init() {
|
||||
V2APIPath = strings.TrimRight(u.Path, "/")
|
||||
V2DocPath = "/doc" + V2APIPath
|
||||
V3FilePath = "/v3/file"
|
||||
V4DirPath = "/v4/dir"
|
||||
}
|
||||
|
||||
func InitV2Router() http.Handler {
|
||||
@ -71,21 +71,23 @@ func InitV2Router() http.Handler {
|
||||
e.Use(echo_middleware.JWTWithConfig(echo_middleware.JWTConfig{
|
||||
Skipper: func(c echo.Context) bool {
|
||||
return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1"
|
||||
//return true
|
||||
// return true
|
||||
},
|
||||
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
|
||||
claims, code := jwt.Validate(token)
|
||||
if code != common_err.SUCCESS {
|
||||
valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||
if err != nil || !valid {
|
||||
return nil, echo.ErrUnauthorized
|
||||
}
|
||||
|
||||
c.Request().Header.Set("user_id", strconv.Itoa(claims.ID))
|
||||
|
||||
return claims, nil
|
||||
},
|
||||
TokenLookupFuncs: []echo_middleware.ValuesExtractor{
|
||||
func(c echo.Context) ([]string, error) {
|
||||
return []string{c.Request().Header.Get(echo.HeaderAuthorization)}, nil
|
||||
func(ctx echo.Context) ([]string, error) {
|
||||
if len(ctx.Request().Header.Get(echo.HeaderAuthorization)) > 0 {
|
||||
return []string{ctx.Request().Header.Get(echo.HeaderAuthorization)}, nil
|
||||
}
|
||||
return []string{ctx.QueryParam("token")}, nil
|
||||
},
|
||||
},
|
||||
}))
|
||||
@ -113,6 +115,12 @@ func InitV2Router() http.Handler {
|
||||
// })
|
||||
|
||||
e.Use(middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{
|
||||
Skipper: func(c echo.Context) bool {
|
||||
// jump validate when upload file
|
||||
// because file upload can't pass validate
|
||||
// issue: https://github.com/deepmap/oapi-codegen/issues/514
|
||||
return strings.Contains(c.Request().Header[echo.HeaderContentType][0], "multipart/form-data")
|
||||
},
|
||||
Options: openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc},
|
||||
}))
|
||||
|
||||
@ -137,17 +145,49 @@ func InitV2DocRouter(docHTML string, docYAML string) http.Handler {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func InitFile() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.URL.Query().Get("token")
|
||||
if len(token) == 0 {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"message": "token not found"}`))
|
||||
return
|
||||
}
|
||||
|
||||
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||
if errs != nil || !valid {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"message": "validation failure"}`))
|
||||
return
|
||||
}
|
||||
filePath := r.URL.Query().Get("path")
|
||||
fileName := path.Base(filePath)
|
||||
w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
|
||||
http.ServeFile(w, r, filePath)
|
||||
// http.ServeFile(w, r, filePath)
|
||||
})
|
||||
}
|
||||
|
||||
func InitDir() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.URL.Query().Get("token")
|
||||
if len(token) == 0 {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"message": "token not found"}`))
|
||||
return
|
||||
}
|
||||
|
||||
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||
if errs != nil || !valid {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"message": "validation failure"}`))
|
||||
return
|
||||
}
|
||||
t := r.URL.Query().Get("format")
|
||||
files := r.URL.Query().Get("files")
|
||||
|
||||
@ -161,7 +201,7 @@ func InitDir() http.Handler {
|
||||
list := strings.Split(files, ",")
|
||||
for _, v := range list {
|
||||
if !file.Exists(v) {
|
||||
// c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
// return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
// Success: common_err.FILE_DOES_NOT_EXIST,
|
||||
// Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||
// })
|
||||
@ -174,7 +214,7 @@ func InitDir() http.Handler {
|
||||
// handles only single files not folders and multiple files
|
||||
// if len(list) == 1 {
|
||||
|
||||
//filePath := list[0]
|
||||
// filePath := list[0]
|
||||
// info, err := os.Stat(filePath)
|
||||
// if err != nil {
|
||||
|
||||
@ -197,7 +237,7 @@ func InitDir() http.Handler {
|
||||
|
||||
err = ar.Create(w)
|
||||
if err != nil {
|
||||
// c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
// return ctx.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||
// Success: common_err.SERVICE_ERROR,
|
||||
// Message: common_err.GetMsg(common_err.SERVICE_ERROR),
|
||||
// Data: err.Error(),
|
||||
|
||||
@ -2,7 +2,9 @@ package v2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
@ -15,3 +17,70 @@ func (s *CasaOS) GetFileTest(ctx echo.Context) error {
|
||||
|
||||
return ctx.String(200, "pong")
|
||||
}
|
||||
|
||||
func (c *CasaOS) CheckUploadChunk(ctx echo.Context, params codegen.CheckUploadChunkParams) error {
|
||||
identifier := ctx.QueryParam("identifier")
|
||||
chunkNumber, err := strconv.ParseInt(ctx.QueryParam("chunkNumber"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.NoContent(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
err = c.fileUploadService.TestChunk(ctx, identifier, chunkNumber)
|
||||
if err != nil {
|
||||
return ctx.NoContent(http.StatusNoContent)
|
||||
}
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
func (c *CasaOS) PostUploadFile(ctx echo.Context) error {
|
||||
path := ctx.FormValue("path")
|
||||
|
||||
// handle the request
|
||||
chunkNumber, err := strconv.ParseInt(ctx.FormValue("chunkNumber"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
chunkSize, err := strconv.ParseInt(ctx.FormValue("chunkSize"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
currentChunkSize, err := strconv.ParseInt(ctx.FormValue("currentChunkSize"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
totalChunks, err := strconv.ParseInt(ctx.FormValue("totalChunks"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
totalSize, err := strconv.ParseInt(ctx.FormValue("totalSize"), 10, 64)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
identifier := ctx.FormValue("identifier")
|
||||
fileName := ctx.FormValue("filename")
|
||||
relativePath := ctx.FormValue("relativePath")
|
||||
bin, err := ctx.FormFile("file")
|
||||
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
err = c.fileUploadService.UploadFile(
|
||||
ctx,
|
||||
path,
|
||||
chunkNumber,
|
||||
chunkSize,
|
||||
currentChunkSize,
|
||||
totalChunks,
|
||||
totalSize,
|
||||
identifier,
|
||||
relativePath,
|
||||
fileName,
|
||||
bin,
|
||||
)
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusInternalServerError, err)
|
||||
}
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
@ -2,10 +2,15 @@ package v2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/mholt/archiver/v3"
|
||||
)
|
||||
|
||||
func (s *CasaOS) GetHealthServices(ctx echo.Context) error {
|
||||
@ -24,3 +29,72 @@ func (s *CasaOS) GetHealthServices(ctx echo.Context) error {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *CasaOS) GetHealthPorts(ctx echo.Context) error {
|
||||
tcpPorts, udpPorts, err := service.MyService.Health().Ports()
|
||||
if err != nil {
|
||||
message := err.Error()
|
||||
return ctx.JSON(http.StatusInternalServerError, codegen.ResponseInternalServerError{
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, codegen.GetHealthPortsOK{
|
||||
Data: &codegen.HealthPorts{
|
||||
TCP: &tcpPorts,
|
||||
UDP: &udpPorts,
|
||||
},
|
||||
})
|
||||
}
|
||||
func (c *CasaOS) GetHealthlogs(ctx echo.Context) error {
|
||||
var name, currentPath, commonDir, extension string
|
||||
var err error
|
||||
var ar archiver.Writer
|
||||
fileList, err := os.ReadDir("/var/log/casaos")
|
||||
if err != nil {
|
||||
message := err.Error()
|
||||
return ctx.JSON(http.StatusInternalServerError, codegen.ResponseInternalServerError{
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
extension, ar, err = file.GetCompressionAlgorithm("zip")
|
||||
if err != nil {
|
||||
ctx.Response().Header().Set("Content-Type", "application/json")
|
||||
message := err.Error()
|
||||
return ctx.JSON(http.StatusNotFound, codegen.ResponseInternalServerError{
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
err = ar.Create(ctx.Response().Writer)
|
||||
if err != nil {
|
||||
ctx.Response().Header().Set("Content-Type", "application/json")
|
||||
message := err.Error()
|
||||
return ctx.JSON(http.StatusNotFound, codegen.ResponseInternalServerError{
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
defer ar.Close()
|
||||
|
||||
commonDir = "/var/log/casaos"
|
||||
|
||||
currentPath = filepath.Base(commonDir)
|
||||
|
||||
name = currentPath
|
||||
name += extension
|
||||
ctx.Response().Header().Add("Content-Type", "application/octet-stream")
|
||||
ctx.Response().Header().Add("Content-Transfer-Encoding", "binary")
|
||||
ctx.Response().Header().Add("Cache-Control", "no-cache")
|
||||
ctx.Response().Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||
|
||||
for _, fname := range fileList {
|
||||
err := file.AddFile(ar, filepath.Join("/var/log/casaos", fname.Name()), commonDir)
|
||||
if err != nil {
|
||||
message := err.Error()
|
||||
return ctx.JSON(http.StatusInternalServerError, codegen.ResponseInternalServerError{
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2,10 +2,15 @@ package v2
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
)
|
||||
|
||||
type CasaOS struct{}
|
||||
type CasaOS struct {
|
||||
fileUploadService *service.FileUploadService
|
||||
}
|
||||
|
||||
func NewCasaOS() codegen.ServerInterface {
|
||||
return &CasaOS{}
|
||||
return &CasaOS{
|
||||
fileUploadService: service.NewFileUploadService(),
|
||||
}
|
||||
}
|
||||
|
||||
47
route/v2/zerotier.go
Normal file
47
route/v2/zerotier.go
Normal file
@ -0,0 +1,47 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils"
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
func (s *CasaOS) SetZerotierNetworkStatus(ctx echo.Context, networkId string) error {
|
||||
|
||||
return ctx.JSON(http.StatusOK, nil)
|
||||
}
|
||||
func (s *CasaOS) GetZerotierInfo(ctx echo.Context) error {
|
||||
info := codegen.GetZTInfoOK{}
|
||||
respBody, err := httper.ZTGet("/controller/network")
|
||||
if err != nil {
|
||||
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
||||
}
|
||||
|
||||
networkNames := gjson.ParseBytes(respBody).Array()
|
||||
for _, v := range networkNames {
|
||||
res, err := httper.ZTGet("/controller/network/" + v.Str)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
||||
}
|
||||
name := gjson.GetBytes(res, "name").Str
|
||||
if name == common.RANW_NAME {
|
||||
via := gjson.GetBytes(res, "routes.0.via").Str
|
||||
info.Id = utils.Ptr(gjson.GetBytes(res, "id").Str)
|
||||
info.Name = &name
|
||||
if len(via) == 0 {
|
||||
info.Status = utils.Ptr("online")
|
||||
} else {
|
||||
info.Status = utils.Ptr("offline")
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return ctx.JSON(http.StatusOK, info)
|
||||
}
|
||||
@ -11,11 +11,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"fmt"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/service/model"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/moby/sys/mount"
|
||||
"golang.org/x/sys/unix"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@ -26,7 +27,7 @@ type ConnectionsService interface {
|
||||
CreateConnection(connection *model2.ConnectionsDBModel)
|
||||
DeleteConnection(id string)
|
||||
UpdateConnection(connection *model2.ConnectionsDBModel)
|
||||
MountSmaba(username, host, directory, port, mountPoint, password string) string
|
||||
MountSmaba(username, host, directory, port, mountPoint, password string) error
|
||||
UnmountSmaba(mountPoint string) error
|
||||
}
|
||||
|
||||
@ -38,28 +39,42 @@ func (s *connectionsStruct) GetConnectionByHost(host string) (connections []mode
|
||||
s.db.Select("username,host,status,id").Where("host = ?", host).Find(&connections)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) GetConnectionByID(id string) (connections model2.ConnectionsDBModel) {
|
||||
s.db.Select("username,password,host,status,id,directories,mount_point,port").Where("id = ?", id).First(&connections)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) GetConnectionsList() (connections []model2.ConnectionsDBModel) {
|
||||
s.db.Select("username,host,port,status,id,mount_point").Find(&connections)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) CreateConnection(connection *model2.ConnectionsDBModel) {
|
||||
s.db.Create(connection)
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) UpdateConnection(connection *model2.ConnectionsDBModel) {
|
||||
s.db.Save(connection)
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) DeleteConnection(id string) {
|
||||
s.db.Where("id= ?", id).Delete(&model.ConnectionsDBModel{})
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) MountSmaba(username, host, directory, port, mountPoint, password string) string {
|
||||
str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;MountCIFS " + username + " " + host + " " + directory + " " + port + " " + mountPoint + " " + password)
|
||||
return str
|
||||
func (s *connectionsStruct) MountSmaba(username, host, directory, port, mountPoint, password string) error {
|
||||
err := unix.Mount(
|
||||
fmt.Sprintf("//%s/%s", host, directory),
|
||||
mountPoint,
|
||||
"cifs",
|
||||
unix.MS_NOATIME|unix.MS_NODEV|unix.MS_NOSUID,
|
||||
fmt.Sprintf("username=%s,password=%s", username, password),
|
||||
)
|
||||
return err
|
||||
// str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;MountCIFS " + username + " " + host + " " + directory + " " + port + " " + mountPoint + " " + password)
|
||||
// return str
|
||||
}
|
||||
|
||||
func (s *connectionsStruct) UnmountSmaba(mountPoint string) error {
|
||||
return mount.Unmount(mountPoint)
|
||||
}
|
||||
|
||||
@ -102,16 +102,20 @@ func FileOperate(k string) {
|
||||
os.RemoveAll(temp.To + "/" + lastPath)
|
||||
}
|
||||
}
|
||||
err := os.Rename(v.From, temp.To+"/"+lastPath)
|
||||
if err != nil {
|
||||
logger.Error("file move error", zap.Any("err", err))
|
||||
err = file.MoveFile(v.From, temp.To+"/"+lastPath)
|
||||
err := file.CopyDir(v.From, temp.To, temp.Style)
|
||||
if err == nil {
|
||||
err = os.RemoveAll(v.From)
|
||||
if err != nil {
|
||||
logger.Error("MoveFile error", zap.Any("err", err))
|
||||
continue
|
||||
}
|
||||
logger.Error("file move error", zap.Any("err", err))
|
||||
err = file.MoveFile(v.From, temp.To+"/"+lastPath)
|
||||
if err != nil {
|
||||
logger.Error("MoveFile error", zap.Any("err", err))
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else if temp.Type == "copy" {
|
||||
err := file.CopyDir(v.From, temp.To, temp.Style)
|
||||
if err != nil {
|
||||
|
||||
167
service/file_upload.go
Normal file
167
service/file_upload.go
Normal file
@ -0,0 +1,167 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
init bool
|
||||
uploaded []bool
|
||||
uploadedChunkNum int64
|
||||
}
|
||||
|
||||
type FileUploadService struct {
|
||||
uploadStatus sync.Map
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewFileUploadService() *FileUploadService {
|
||||
return &FileUploadService{
|
||||
uploadStatus: sync.Map{},
|
||||
lock: sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileUploadService) TestChunk(
|
||||
c echo.Context,
|
||||
identifier string,
|
||||
chunkNumber int64,
|
||||
) error {
|
||||
fileInfoTemp, ok := s.uploadStatus.Load(identifier)
|
||||
|
||||
if !ok {
|
||||
return fmt.Errorf("file not found")
|
||||
}
|
||||
|
||||
fileInfo := fileInfoTemp.(*FileInfo)
|
||||
|
||||
if !fileInfo.init {
|
||||
return fmt.Errorf("file not init")
|
||||
}
|
||||
|
||||
// return StatusNoContent instead of 404
|
||||
// the is require by frontend
|
||||
if !fileInfo.uploaded[chunkNumber-1] {
|
||||
return fmt.Errorf("file not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileUploadService) UploadFile(
|
||||
c echo.Context,
|
||||
path string,
|
||||
chunkNumber int64,
|
||||
chunkSize int64,
|
||||
currentChunkSize int64,
|
||||
totalChunks int64,
|
||||
totalSize int64,
|
||||
identifier string,
|
||||
relativePath string,
|
||||
fileName string,
|
||||
bin *multipart.FileHeader,
|
||||
) error {
|
||||
s.lock.Lock()
|
||||
fileInfoTemp, ok := s.uploadStatus.Load(identifier)
|
||||
var fileInfo *FileInfo
|
||||
|
||||
if relativePath != fileName {
|
||||
// uploaded file is folder
|
||||
folderPath := filepath.Dir(path + "/" + relativePath)
|
||||
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(path+"/"+relativePath+".tmp", os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// pre allocate file size
|
||||
fmt.Println("truncate", totalSize)
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// file info init
|
||||
fileInfo = &FileInfo{
|
||||
init: true,
|
||||
uploaded: make([]bool, totalChunks),
|
||||
uploadedChunkNum: 0,
|
||||
}
|
||||
s.uploadStatus.Store(identifier, fileInfo)
|
||||
} else {
|
||||
fileInfo = fileInfoTemp.(*FileInfo)
|
||||
}
|
||||
|
||||
s.lock.Unlock()
|
||||
|
||||
_, err = file.Seek((chunkNumber-1)*chunkSize, io.SeekStart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
src, err := bin.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
_, err = io.Copy(file, src)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
s.lock.Lock()
|
||||
// handle file after write a chunk
|
||||
// handle single chunk upload twice
|
||||
if !fileInfo.uploaded[chunkNumber-1] {
|
||||
fileInfo.uploadedChunkNum++
|
||||
fileInfo.uploaded[chunkNumber-1] = true
|
||||
}
|
||||
|
||||
// handle file after write all chunk
|
||||
if fileInfo.uploadedChunkNum == totalChunks {
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
logger.Error("close file error: ", zap.Error(err))
|
||||
}
|
||||
|
||||
err = os.Rename(path+"/"+relativePath+".tmp", path+"/"+relativePath)
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
logger.Error("rename file error: ", zap.Error(err))
|
||||
}
|
||||
// remove upload status info after upload complete
|
||||
s.uploadStatus.Delete(identifier)
|
||||
}
|
||||
s.lock.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/port"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/systemctl"
|
||||
)
|
||||
|
||||
type HealthService interface {
|
||||
Services() (map[bool]*[]string, error)
|
||||
Ports() ([]int, []int, error)
|
||||
}
|
||||
|
||||
type service struct{}
|
||||
@ -34,6 +36,10 @@ func (s *service) Services() (map[bool]*[]string, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *service) Ports() ([]int, []int, error) {
|
||||
return port.ListPortsInUse()
|
||||
}
|
||||
|
||||
func NewHealthService() HealthService {
|
||||
return &service{}
|
||||
}
|
||||
|
||||
18
service/health_test.go
Normal file
18
service/health_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
package service_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPorts(t *testing.T) {
|
||||
service := service.NewHealthService()
|
||||
|
||||
tcpPorts, udpPorts, err := service.Ports()
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NotEmpty(t, tcpPorts)
|
||||
assert.NotEmpty(t, udpPorts)
|
||||
}
|
||||
@ -14,8 +14,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/service/model"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
@ -47,19 +47,23 @@ func (s *sharesStruct) GetSharesByName(name string) (shares []model2.SharesDBMod
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sharesStruct) GetSharesByPath(path string) (shares []model2.SharesDBModel) {
|
||||
s.db.Select("anonymous,path,id").Where("path = ?", path).Find(&shares)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sharesStruct) GetSharesList() (shares []model2.SharesDBModel) {
|
||||
s.db.Select("anonymous,path,id").Find(&shares)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sharesStruct) CreateShare(share model2.SharesDBModel) {
|
||||
s.db.Create(&share)
|
||||
s.InitSambaConfig()
|
||||
s.UpdateConfigFile()
|
||||
}
|
||||
|
||||
func (s *sharesStruct) DeleteShare(id string) {
|
||||
s.db.Where("id= ?", id).Delete(&model.SharesDBModel{})
|
||||
s.UpdateConfigFile()
|
||||
@ -68,8 +72,8 @@ func (s *sharesStruct) DeleteShare(id string) {
|
||||
func (s *sharesStruct) UpdateConfigFile() {
|
||||
shares := []model2.SharesDBModel{}
|
||||
s.db.Select("anonymous,path").Find(&shares)
|
||||
//generated config file
|
||||
var configStr = ""
|
||||
// generated config file
|
||||
configStr := ""
|
||||
for _, share := range shares {
|
||||
dirName := filepath.Base(share.Path)
|
||||
configStr += `
|
||||
@ -86,12 +90,12 @@ force user = root
|
||||
|
||||
`
|
||||
}
|
||||
//write config file
|
||||
// write config file
|
||||
file.WriteToPath([]byte(configStr), "/etc/samba", "smb.casa.conf")
|
||||
//restart samba
|
||||
command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;RestartSMBD")
|
||||
|
||||
// restart samba
|
||||
command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;RestartSMBD")
|
||||
}
|
||||
|
||||
func (s *sharesStruct) InitSambaConfig() {
|
||||
if file.Exists("/etc/samba/smb.conf") {
|
||||
str := file.ReadLine(1, "/etc/samba/smb.conf")
|
||||
@ -99,7 +103,7 @@ func (s *sharesStruct) InitSambaConfig() {
|
||||
return
|
||||
}
|
||||
file.MoveFile("/etc/samba/smb.conf", "/etc/samba/smb.conf.bak")
|
||||
var smbConf = ""
|
||||
smbConf := ""
|
||||
smbConf += `# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.
|
||||
#
|
||||
#
|
||||
@ -150,7 +154,6 @@ func (s *sharesStruct) InitSambaConfig() {
|
||||
include=/etc/samba/smb.casa.conf`
|
||||
file.WriteToPath([]byte(smbConf), "/etc/samba", "smb.conf")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func NewSharesService(db *gorm.DB) SharesService {
|
||||
|
||||
@ -1,24 +1,30 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
net2 "net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/command"
|
||||
exec2 "github.com/IceWhaleTech/CasaOS-Common/utils/exec"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
@ -49,6 +55,7 @@ type SystemService interface {
|
||||
GetDiskInfo() *disk.UsageStat
|
||||
GetSysInfo() host.InfoStat
|
||||
GetDeviceTree() string
|
||||
GetDeviceInfo() model.DeviceInfo
|
||||
CreateFile(path string) (int, error)
|
||||
RenameFile(oldF, newF string) (int, error)
|
||||
MkdirAll(path string) (int, error)
|
||||
@ -57,9 +64,118 @@ type SystemService interface {
|
||||
GetMacAddress() (string, error)
|
||||
SystemReboot() error
|
||||
SystemShutdown() error
|
||||
GetSystemEntry() string
|
||||
GenreateSystemEntry()
|
||||
}
|
||||
type systemService struct{}
|
||||
|
||||
func (c *systemService) GetDeviceInfo() model.DeviceInfo {
|
||||
m := model.DeviceInfo{}
|
||||
m.OS_Version = common.VERSION
|
||||
err, portStr := MyService.Gateway().GetPort()
|
||||
if err != nil {
|
||||
m.Port = 80
|
||||
} else {
|
||||
port := gjson.Get(portStr, "data")
|
||||
if len(port.Raw) == 0 {
|
||||
m.Port = 80
|
||||
} else {
|
||||
p, err := strconv.Atoi(port.Raw)
|
||||
if err != nil {
|
||||
m.Port = 80
|
||||
} else {
|
||||
m.Port = p
|
||||
}
|
||||
}
|
||||
}
|
||||
allIpv4 := ip_helper.GetDeviceAllIPv4()
|
||||
ip := []string{}
|
||||
nets := MyService.System().GetNet(true)
|
||||
for _, n := range nets {
|
||||
if v, ok := allIpv4[n]; ok {
|
||||
{
|
||||
ip = append(ip, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.LanIpv4 = ip
|
||||
h, err := host.Info() /* */
|
||||
if err == nil {
|
||||
m.DeviceName = h.Hostname
|
||||
}
|
||||
mb := model.BaseInfo{}
|
||||
|
||||
err = json.Unmarshal(file.ReadFullFile(config.AppInfo.DBPath+"/baseinfo.conf"), &mb)
|
||||
if err == nil {
|
||||
m.Hash = mb.Hash
|
||||
}
|
||||
|
||||
osRelease, _ := file.ReadOSRelease()
|
||||
m.DeviceModel = osRelease["MODEL"]
|
||||
m.DeviceSN = osRelease["SN"]
|
||||
res := httper.Get("http://127.0.0.1:"+strconv.Itoa(m.Port)+"/v1/users/status", nil)
|
||||
init := gjson.Get(res, "data.initialized")
|
||||
m.Initialized, _ = strconv.ParseBool(init.Raw)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (c *systemService) GenreateSystemEntry() {
|
||||
modelsPath := "/var/lib/casaos/www/modules"
|
||||
entryFileName := "entry.json"
|
||||
entryFilePath := filepath.Join(config.AppInfo.DBPath, "db", entryFileName)
|
||||
file.IsNotExistCreateFile(entryFilePath)
|
||||
|
||||
dir, err := os.ReadDir(modelsPath)
|
||||
if err != nil {
|
||||
logger.Error("read dir error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
json := "["
|
||||
for _, v := range dir {
|
||||
data, err := os.ReadFile(filepath.Join(modelsPath, v.Name(), entryFileName))
|
||||
if err != nil {
|
||||
logger.Error("read entry file error", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
json += string(data) + ","
|
||||
}
|
||||
json = strings.TrimRight(json, ",")
|
||||
json += "]"
|
||||
err = os.WriteFile(entryFilePath, []byte(json), 0o666)
|
||||
if err != nil {
|
||||
logger.Error("write entry file error", zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *systemService) GetSystemEntry() string {
|
||||
modelsPath := "/var/lib/casaos/www/modules"
|
||||
entryFileName := "entry.json"
|
||||
dir, err := os.ReadDir(modelsPath)
|
||||
if err != nil {
|
||||
logger.Error("read dir error", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
json := "["
|
||||
for _, v := range dir {
|
||||
data, err := os.ReadFile(filepath.Join(modelsPath, v.Name(), entryFileName))
|
||||
if err != nil {
|
||||
logger.Error("read entry file error", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
json += string(data) + ","
|
||||
}
|
||||
json = strings.TrimRight(json, ",")
|
||||
json += "]"
|
||||
if err != nil {
|
||||
logger.Error("write entry file error", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
func (c *systemService) GetMacAddress() (string, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@ -121,7 +237,11 @@ func (c *systemService) CreateFile(path string) (int, error) {
|
||||
}
|
||||
|
||||
func (c *systemService) GetDeviceTree() string {
|
||||
return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree")
|
||||
if output, err := command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree"); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
func (c *systemService) GetSysInfo() host.InfoStat {
|
||||
@ -141,7 +261,11 @@ func (c *systemService) GetDiskInfo() *disk.UsageStat {
|
||||
}
|
||||
|
||||
func (c *systemService) GetNetState(name string) string {
|
||||
return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;CatNetCardState " + name)
|
||||
if output, err := command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;CatNetCardState " + name); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
func (c *systemService) GetDirPathOne(path string) (m model.Path) {
|
||||
@ -238,7 +362,12 @@ func (c *systemService) GetNet(physics bool) []string {
|
||||
if physics {
|
||||
t = "2"
|
||||
}
|
||||
return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetNetCard " + t)
|
||||
|
||||
if output, err := command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;GetNetCard " + t); err != nil {
|
||||
return []string{}
|
||||
} else {
|
||||
return strings.Split(output, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *systemService) UpdateSystemVersion(version string) {
|
||||
@ -250,10 +379,10 @@ func (s *systemService) UpdateSystemVersion(version string) {
|
||||
file.CreateFile(config.AppInfo.LogPath + "/upgrade.log")
|
||||
// go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/update.sh | bash")
|
||||
if len(config.ServerInfo.UpdateUrl) > 0 {
|
||||
go command2.OnlyExec("curl -fsSL " + config.ServerInfo.UpdateUrl + " | bash")
|
||||
go command.OnlyExec("curl -fsSL " + config.ServerInfo.UpdateUrl + " | bash")
|
||||
} else {
|
||||
osRelease, _ := file.ReadOSRelease()
|
||||
go command2.OnlyExec("curl -fsSL https://get.casaos.io/update?t=" + osRelease["MANUFACTURER"] + " | bash")
|
||||
go command.OnlyExec("curl -fsSL https://get.casaos.io/update?t=" + osRelease["MANUFACTURER"] + " | bash")
|
||||
}
|
||||
|
||||
// s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
|
||||
@ -261,15 +390,23 @@ func (s *systemService) UpdateSystemVersion(version string) {
|
||||
}
|
||||
|
||||
func (s *systemService) UpdateAssist() {
|
||||
command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/assist.sh")
|
||||
command.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/assist.sh")
|
||||
}
|
||||
|
||||
func (s *systemService) GetTimeZone() string {
|
||||
return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetTimeZone")
|
||||
if output, err := command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;GetTimeZone"); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
func (s *systemService) GetSystemConfigDebug() []string {
|
||||
return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetSysInfo")
|
||||
if output, err := command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;GetSysInfo"); err != nil {
|
||||
return []string{}
|
||||
} else {
|
||||
return strings.Split(output, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *systemService) UpAppOrderFile(str, id string) {
|
||||
@ -297,7 +434,7 @@ func (s *systemService) GetCasaOSLogs(lineNumber int) string {
|
||||
return err.Error()
|
||||
}
|
||||
defer file.Close()
|
||||
content, err := ioutil.ReadAll(file)
|
||||
content, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
@ -345,7 +482,7 @@ func GetCPUThermalZone() string {
|
||||
name = strings.TrimSuffix(string(file.ReadFullFile(path+"/type")), "\n")
|
||||
for _, s := range cpu_types {
|
||||
if strings.HasPrefix(name, s) {
|
||||
logger.Info(fmt.Sprintf("CPU thermal zone found: %s, path: %s.", name, path))
|
||||
//logger.Info(fmt.Sprintf("CPU thermal zone found: %s, path: %s.", name, path))
|
||||
Cache.SetDefault(keyName, path)
|
||||
return path
|
||||
}
|
||||
@ -359,6 +496,7 @@ func GetCPUThermalZone() string {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Cache.SetDefault(keyName, path)
|
||||
return path
|
||||
}
|
||||
@ -369,7 +507,10 @@ func (s *systemService) GetCPUTemperature() int {
|
||||
if len(path) > 0 {
|
||||
outPut = string(file.ReadFullFile(path + "/temp"))
|
||||
} else {
|
||||
outPut = "0"
|
||||
outPut = string(file.ReadFullFile("/sys/class/hwmon/hwmon0/temp1_input"))
|
||||
if len(outPut) == 0 {
|
||||
outPut = "0"
|
||||
}
|
||||
}
|
||||
|
||||
celsius, _ := strconv.Atoi(strings.TrimSpace(outPut))
|
||||
@ -392,9 +533,8 @@ func (s *systemService) GetCPUPower() map[string]string {
|
||||
}
|
||||
|
||||
func (s *systemService) SystemReboot() error {
|
||||
// cmd := exec.Command("/bin/bash", "-c", "reboot")
|
||||
arg := []string{"6"}
|
||||
cmd := exec.Command("init", arg...)
|
||||
cmd := exec2.Command("init", arg...)
|
||||
_, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -404,7 +544,7 @@ func (s *systemService) SystemReboot() error {
|
||||
|
||||
func (s *systemService) SystemShutdown() error {
|
||||
arg := []string{"0"}
|
||||
cmd := exec.Command("init", arg...)
|
||||
cmd := exec2.Command("init", arg...)
|
||||
_, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
25
tsconfig.json
Normal file
25
tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"lib": [
|
||||
"es2017",
|
||||
"DOM"
|
||||
],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": false,
|
||||
"strict": true,
|
||||
"useUnknownInCatchVariables": false,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist",
|
||||
"types": [
|
||||
"node"
|
||||
],
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"main": "generate/index"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user