Compare commits
69 Commits
v0.3.3-alp
...
v0.3.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
079e431d33 | ||
|
|
cee34ec1c2 | ||
|
|
848ee63386 | ||
|
|
c12c6cc940 | ||
|
|
f31fb22039 | ||
|
|
a5133bdbfa | ||
|
|
1902b2d4f2 | ||
|
|
fc5e351f0b | ||
|
|
7f642a7a4c | ||
|
|
c36a046a15 | ||
|
|
8b2c9486da | ||
|
|
ce5ecfcf84 | ||
|
|
bd1a2f5751 | ||
|
|
d2e0695d73 | ||
|
|
8cd18c3218 | ||
|
|
cc0ba82c92 | ||
|
|
ddca242d23 | ||
|
|
eaa07ba95a | ||
|
|
39a4c29680 | ||
|
|
af6900b1c7 | ||
|
|
9ec43a7691 | ||
|
|
bd85cda9fa | ||
|
|
94eaba6ecb | ||
|
|
e207c9c75f | ||
|
|
81d3293991 | ||
|
|
364fbf01f5 | ||
|
|
87e66aae8a | ||
|
|
3a60db3729 | ||
|
|
d3f78b52fa | ||
|
|
7d67a66d6b | ||
|
|
cb9e1b9dd9 | ||
|
|
dc8282acbb | ||
|
|
cf6103a2b5 | ||
|
|
6f98995e7d | ||
|
|
5cc41fa040 | ||
|
|
cb289f5b8a | ||
|
|
1377d55407 | ||
|
|
06eca38022 | ||
|
|
c47c1e548c | ||
|
|
552ec4849d | ||
|
|
7386a9dce3 | ||
|
|
b2b1daf5ab | ||
|
|
bbc0181e23 | ||
|
|
c23bd3f3a3 | ||
|
|
8a1839c02e | ||
|
|
164bf66190 | ||
|
|
a4c2a4b992 | ||
|
|
e7e82e6ca3 | ||
|
|
574295470e | ||
|
|
b1061f19ad | ||
|
|
bdd9eaca9f | ||
|
|
ec4c672924 | ||
|
|
5d4717de4d | ||
|
|
e2de783152 | ||
|
|
09f68f4034 | ||
|
|
cec83fc048 | ||
|
|
33e1d8a806 | ||
|
|
2a8dafae28 | ||
|
|
a426b56306 | ||
|
|
6202d38bdb | ||
|
|
4626ceb048 | ||
|
|
1e7333118c | ||
|
|
9758436a1e | ||
|
|
ed67e977b7 | ||
|
|
b0b1b5e262 | ||
|
|
2796c37bf6 | ||
|
|
d48e24f652 | ||
|
|
3a8cf593d9 | ||
|
|
0ffa2f901a |
197
.all-contributorsrc
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"imageSize": 100,
|
||||||
|
"badgeTemplate": "<a href=\"#credits\"><img alt=\"All Contributors\" src=\"https://img.shields.io/static/v1?label=All%20Contributors&message=<%= contributors.length %>&color=162453&style=flat-square&logo=Handshake&logoColor=fff\" /></a>",
|
||||||
|
"commit": false,
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"login": "jerrykuku",
|
||||||
|
"name": "老竭力",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/9485680?v=4",
|
||||||
|
"profile": "https://github.com/jerrykuku",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"doc",
|
||||||
|
"ideas",
|
||||||
|
"infra",
|
||||||
|
"maintenance",
|
||||||
|
"platform",
|
||||||
|
"question",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "LinkLeong",
|
||||||
|
"name": "link",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/13556972?v=4",
|
||||||
|
"profile": "https://github.com/LinkLeong",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"doc",
|
||||||
|
"ideas",
|
||||||
|
"infra",
|
||||||
|
"maintenance",
|
||||||
|
"question",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "tigerinus",
|
||||||
|
"name": "Tiger Wang (王豫)",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/7172560?v=4",
|
||||||
|
"profile": "https://github.com/tigerinus",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"doc",
|
||||||
|
"ideas",
|
||||||
|
"infra",
|
||||||
|
"maintenance",
|
||||||
|
"mentoring",
|
||||||
|
"security",
|
||||||
|
"question",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Lauren-ED209",
|
||||||
|
"name": "Lauren",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/8243355?v=4",
|
||||||
|
"profile": "https://github.com/Lauren-ED209",
|
||||||
|
"contributions": [
|
||||||
|
"ideas",
|
||||||
|
"fundingFinding",
|
||||||
|
"projectManagement",
|
||||||
|
"question",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "JohnGuan",
|
||||||
|
"name": "John Guan",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3358477?v=4",
|
||||||
|
"profile": "https://JohnGuan.Cn",
|
||||||
|
"contributions": [
|
||||||
|
"blog",
|
||||||
|
"content",
|
||||||
|
"doc",
|
||||||
|
"ideas",
|
||||||
|
"eventOrganizing",
|
||||||
|
"mentoring",
|
||||||
|
"question",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "dtaivpp",
|
||||||
|
"name": "David Tippett",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/17506770?v=4",
|
||||||
|
"profile": "https://blog.tippybits.com",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"ideas",
|
||||||
|
"question"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "zarevskaya",
|
||||||
|
"name": "Skaya",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/60230221?v=4",
|
||||||
|
"profile": "https://github.com/zarevskaya",
|
||||||
|
"contributions": [
|
||||||
|
"mentoring",
|
||||||
|
"question",
|
||||||
|
"tutorial",
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "AuthorShin",
|
||||||
|
"name": "AuthorShin",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/4959043?v=4",
|
||||||
|
"profile": "https://github.com/AuthorShin",
|
||||||
|
"contributions": [
|
||||||
|
"test",
|
||||||
|
"bug",
|
||||||
|
"question",
|
||||||
|
"ideas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "baptiste313",
|
||||||
|
"name": "baptiste313",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/93325157?v=4",
|
||||||
|
"profile": "https://github.com/baptiste313",
|
||||||
|
"contributions": [
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "DrMxrcy",
|
||||||
|
"name": "DrMxrcy",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/58747968?v=4",
|
||||||
|
"profile": "https://github.com/DrMxrcy",
|
||||||
|
"contributions": [
|
||||||
|
"test",
|
||||||
|
"ideas",
|
||||||
|
"question"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Joooost",
|
||||||
|
"name": "Joooost",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/12090673?v=4",
|
||||||
|
"profile": "https://github.com/Joooost",
|
||||||
|
"contributions": [
|
||||||
|
"ideas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "sio",
|
||||||
|
"name": "Vitaly Potyarkin",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/334908?v=4",
|
||||||
|
"profile": "https://potyarkin.ml",
|
||||||
|
"contributions": [
|
||||||
|
"ideas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "bearfrieze",
|
||||||
|
"name": "Bjørn Friese",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1023813?v=4",
|
||||||
|
"profile": "https://github.com/bearfrieze",
|
||||||
|
"contributions": [
|
||||||
|
"ideas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Protektor-Desura",
|
||||||
|
"name": "Protektor",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1195496?v=4",
|
||||||
|
"profile": "https://github.com/Protektor-Desura",
|
||||||
|
"contributions": [
|
||||||
|
"bug",
|
||||||
|
"ideas",
|
||||||
|
"question"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "llwaini",
|
||||||
|
"name": "llwaini",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/59589857?v=4",
|
||||||
|
"profile": "https://github.com/llwaini",
|
||||||
|
"contributions": [
|
||||||
|
"projectManagement",
|
||||||
|
"test",
|
||||||
|
"tutorial"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contributorsPerLine": 7,
|
||||||
|
"projectName": "CasaOS",
|
||||||
|
"projectOwner": "IceWhaleTech",
|
||||||
|
"repoType": "github",
|
||||||
|
"repoHost": "https://github.com",
|
||||||
|
"skipCi": true
|
||||||
|
}
|
||||||
26
.github/ISSUE_TEMPLATE/alpha_bug_report.yaml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: "[Alpha Only] Bug Report"
|
||||||
|
description: CasaOS Alpha Testing specific bug report form.
|
||||||
|
title: "[Alpha][Bug] "
|
||||||
|
labels: ["alpha", "bug"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
> If you haven't joined CasaOS Alpha Team yet.
|
||||||
|
> Please join first on [Discord](https://discord.gg/knqAbbBbeX) to be updated on the Alpha test plan and test scope.
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: Also tell us, what did you expect to happen?
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: screenshots
|
||||||
|
attributes:
|
||||||
|
label: Screenshots
|
||||||
|
description: If applicable, add screenshots to help explain your problem.
|
||||||
|
placeholder: Screenshots would be very helpful!
|
||||||
|
|
||||||
53
.github/ISSUE_TEMPLATE/app_request.yaml
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
name: "App Request"
|
||||||
|
description: "Request to add an app to the app store."
|
||||||
|
title: "[App Request] AppName"
|
||||||
|
labels: ["App Request"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
### ❤ Thanks for taking the time to fill out this app request!
|
||||||
|
> Before proceeding, please make sure that this app is not in App Store and no one has [requested](https://github.com/IceWhaleTech/CasaOS/labels/App%20Request) the same app before.
|
||||||
|
> If you have already requested the app, please ask your friends to help add a 👍 to this issue. Then be patient and wait for the developers to work on it.
|
||||||
|
> If you have any questions, please ask them on [Discord](https://discord.gg/knqAbbBbeX) or [Github Discussions](https://github.com/IceWhaleTech/CasaOS/discussions).
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: app-info
|
||||||
|
attributes:
|
||||||
|
label: "App Information"
|
||||||
|
description: "The formal information of this app, as detailed as possible."
|
||||||
|
value: |
|
||||||
|
- Name: <!-- eg. Nextcloud -->
|
||||||
|
- Short Description: <!-- eg. Personal cloud and file sharing solution -->
|
||||||
|
- Official Website: <!-- If available. eg. https://nextcloud.com -->
|
||||||
|
- GitHub Repository: <!-- If available. eg. https://github.com/nextcloud/server -->
|
||||||
|
- Docker Image: <!-- If available. eg. nextcloud/server:latest, ghcr.io/nextcloud/server:latest -->
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: why
|
||||||
|
attributes:
|
||||||
|
label: "Why do you want this app?"
|
||||||
|
description: "Detailed notes can help developers and others understand the importance of this app."
|
||||||
|
placeholder: |
|
||||||
|
As a [what role], it helps me solve [what problem], and especially [what function] is great!
|
||||||
|
or
|
||||||
|
It solves [what problem] and especially [what feature] works well, which is hard to do with other app.
|
||||||
|
or
|
||||||
|
This is the app that [some device/service] must use and will not work without it.
|
||||||
|
or
|
||||||
|
others
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional-info
|
||||||
|
attributes:
|
||||||
|
label: "Additional information?"
|
||||||
|
description: "Anything else you want to share with the developers and others?"
|
||||||
|
placeholder: |
|
||||||
|
Example:
|
||||||
|
- Noteworthy matters.
|
||||||
|
- Recommended Docker image.
|
||||||
|
- Validated Docker deployment instructions.
|
||||||
|
- Notable Docker setup details.
|
||||||
|
- Recommended config files, user data, accessible directory settings.
|
||||||
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: '[Bug] '
|
||||||
labels: ''
|
labels: 'bug'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,11 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Questions, Ideas, Discussions
|
- name: Feature/Enhancement Ideas
|
||||||
|
url: https://github.com/IceWhaleTech/CasaOS/discussions/164
|
||||||
|
about: Have an idea for a new feature/enhancement?
|
||||||
|
- name: Questions, Discussions
|
||||||
url: https://github.com/IceWhaleTech/CasaOS/discussions
|
url: https://github.com/IceWhaleTech/CasaOS/discussions
|
||||||
about: Ask questions, propose ideas, or discuss anything related to CasaOS
|
about: Ask questions, propose ideas, or discuss anything related to CasaOS
|
||||||
|
- name: Discord
|
||||||
|
url: https://discord.gg/knqAbbBbeX
|
||||||
|
about: Get help or share great ideas on Discord!
|
||||||
33
.github/workflows/add_issues_to_projects.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: Add Issues To Projects
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add-issues:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Generate token
|
||||||
|
id: generate_token
|
||||||
|
uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.ALPHA_BOT_ID }}
|
||||||
|
private_key: ${{ secrets.ALPHA_BOT_PEM }}
|
||||||
|
|
||||||
|
- name: Add Alpha Bug Issue To project
|
||||||
|
uses: actions/add-to-project@v0.3.0
|
||||||
|
with:
|
||||||
|
github-token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
project-url: https://github.com/orgs/IceWhaleTech/projects/5
|
||||||
|
labeled: alpha, bug
|
||||||
|
label-operator: AND
|
||||||
|
|
||||||
|
- name: Add App Request Issue To project
|
||||||
|
uses: actions/add-to-project@v0.3.0
|
||||||
|
with:
|
||||||
|
github-token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
project-url: https://github.com/orgs/IceWhaleTech/projects/8
|
||||||
|
labeled: "App Request"
|
||||||
|
label-operator: AND
|
||||||
2
.github/workflows/demo.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Get old instance and snapshot name, create new instance name
|
- name: Get old instance and snapshot name, create new instance name
|
||||||
run: |
|
run: |
|
||||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "CasaOS-Demo-Snapshot-1652856810' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
echo "OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "0.3.3-demo-1658402149' | 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 "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 "NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
|||||||
27
.github/workflows/move_alpha_bug_to_project.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# This is a basic workflow to help you get started with Actions
|
||||||
|
|
||||||
|
name: Move alpha bug to project
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
track_issue:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Generate token
|
||||||
|
id: generate_token
|
||||||
|
uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.ALPHA_BOT_ID }}
|
||||||
|
private_key: ${{ secrets.ALPHA_BOT_PEM }}
|
||||||
|
|
||||||
|
- name: Add Issue To GitHub Projects Beta
|
||||||
|
uses: actions/add-to-project@v0.1.0
|
||||||
|
with:
|
||||||
|
project-url: https://github.com/orgs/IceWhaleTech/projects/5
|
||||||
|
github-token: ${{ steps.generate_token.outputs.token }}
|
||||||
|
labeled: alpha, bug
|
||||||
|
label-operator: AND
|
||||||
48
.github/workflows/push_events_to_discord.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
name: Push Events to Discord
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
issue_comment:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
discussion:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
- transferred
|
||||||
|
- answered
|
||||||
|
discussion_comment:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
push-events:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: General Discussions & Comments
|
||||||
|
if: ${{ ( github.event_name == 'discussion' || github.event_name == 'discussion_comment' ) && github.event.discussion.category.name == 'General' }}
|
||||||
|
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||||
|
with:
|
||||||
|
webhook: ${{ secrets.Discord_CasaOS_General_Webhook }}
|
||||||
|
|
||||||
|
- name: App Request Issues & Comments
|
||||||
|
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'App Request') }}
|
||||||
|
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||||
|
with:
|
||||||
|
webhook: ${{ secrets.Discord_CasaOS_App_Request_Webhook }}
|
||||||
|
|
||||||
|
- name: Bug Issues & Comments
|
||||||
|
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'bug') && !contains(!github.event.issue.labels.*.name, 'alpha') }}
|
||||||
|
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 }}
|
||||||
1
.gitignore
vendored
@@ -37,3 +37,4 @@ __debug_bin
|
|||||||
main
|
main
|
||||||
CasaOS
|
CasaOS
|
||||||
github.com
|
github.com
|
||||||
|
.all-contributorsrc
|
||||||
|
|||||||
41
CHANGELOG.md
@@ -18,7 +18,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
## [0.3.3-pre] - 2022-07-01(UTC)
|
## [0.3.5-alpha] - 2022-08-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [File] Mount the shared samba
|
||||||
|
- [File] File sharing via Samba
|
||||||
|
- [System] You can share casaos on Twitter, facebook, reddit
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- [Disk] Support for mounting existing data disks
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [App] fixed uninstalling imported docker container apps results in wiping ALL your config data from them ([#360](https://github.com/IceWhaleTech/CasaOS/issues/360))
|
||||||
|
|
||||||
|
## [0.3.4] - 2022-07-29(UTC)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- SSH adds port-side options and prompts for connection status. ([#286](https://github.com/IceWhaleTech/CasaOS/issues/286))
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Normalize all routes
|
||||||
|
- Application names now support spaces ([#211](https://github.com/IceWhaleTech/CasaOS/issues/211))
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed casaos connect
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Adjustment of authentication method
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed storage format and remove password error issues ([#344](https://github.com/IceWhaleTech/CasaOS/issues/344) [#357](https://github.com/IceWhaleTech/CasaOS/issues/357))
|
||||||
|
|
||||||
|
## [0.3.3] - 2022-07-08(UTC)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
259
README.md
@@ -1,71 +1,149 @@
|
|||||||
# CasaOS - A simple, easy-to-use, elegant open-source Home Cloud system.
|
# CasaOS - Your Home Cloud OS
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[](https://github.com/IceWhaleTech/CasaOS)
|
<!-- Readme i18n links -->
|
||||||
[](https://github.com/IceWhaleTech/CasaOS/pulls)
|
<!-- > English | [中文](#) | [Français](#) -->
|
||||||
[](https://github.com/IceWhaleTech/CasaOS/issues)
|
|
||||||
[](https://github.com/IceWhaleTech/CasaOS/stargazers)
|
|
||||||
[](https://discord.gg/knqAbbBbeX)
|
|
||||||
|
|
||||||
CasaOS is an open-source Home Cloud system based on the Docker ecosystem and designed for home scenarios. It is committed to building the world's most simple, easy-to-use, and elegant Home Cloud system.
|
<p align="center">
|
||||||
|
<!-- CasaOS Banner -->
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_dark_night_800px.png">
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800px.png">
|
||||||
|
<img alt="CasaOS" src="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800px.png">
|
||||||
|
</picture>
|
||||||
|
<br/>
|
||||||
|
<i>Connect with the community developing HOME CLOUD, creating self-sovereign, and defining the future of the distributed cloud.</i>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<!-- CasaOS Badges -->
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS" target="_blank">
|
||||||
|
<img alt="CasaOS Version" src="https://img.shields.io/github/v/release/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=CasaOS" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS/blob/main/LICENSE" target="_blank">
|
||||||
|
<img alt="CasaOS License" src="https://img.shields.io/github/license/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=License" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS/pulls" target="_blank">
|
||||||
|
<img alt="CasaOS Pull Requests" src="https://img.shields.io/github/issues-pr/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=PRs" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS/issues" target="_blank">
|
||||||
|
<img alt="CasaOS Issues" src="https://img.shields.io/github/issues/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Issues" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS/stargazers" target="_blank">
|
||||||
|
<img alt="CasaOS Stargazers" src="https://img.shields.io/github/stars/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Stars" />
|
||||||
|
</a>
|
||||||
|
<!-- <a href="https://github.com/IceWhaleTech/CasaOS/releases" target="_blank">
|
||||||
|
<img alt="CasaOS Downloads" src="https://img.shields.io/github/downloads/IceWhaleTech/CasaOS/total?color=162453&style=flat-square" />
|
||||||
|
</a> -->
|
||||||
|
<br/>
|
||||||
|
<!-- CasaOS Community -->
|
||||||
|
<a href="https://discord.gg/knqAbbBbeX" target="_blank">
|
||||||
|
<img alt="IceWhale Discord" src="https://img.shields.io/discord/884667213326463016?color=162453&style=flat-square&label=Discord&logo=discord&logoColor=fff" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS/discussions" target="_blank">
|
||||||
|
<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 -->
|
||||||
|
<br/>
|
||||||
|
<!-- CasaOS Links -->
|
||||||
|
<a href="https://www.casaos.io" target="_blank">Website</a> |
|
||||||
|
<a href="http://demo.casaos.io" target="_blank">Demo</a> |
|
||||||
|
<a href="https://github.com/IceWhaleTech/CasaOS" target="_blank">GitHub</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<!-- CasaOS Snapshots -->
|
||||||
|
<kbd>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="snapshot-dark.jpg">
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="snapshot-light.jpg">
|
||||||
|
<img alt="CasaOS Snapshot" src="snapshot-light.jpg">
|
||||||
|
</picture>
|
||||||
|
</kbd>
|
||||||
|
</p>
|
||||||
|
|
||||||
IceWhale team believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
## Why do we need Home Cloud?
|
||||||
|
|
||||||

|
Think about it seriously. Is control of our data, smart devices and digital assets now only in the hands of some big company?
|
||||||

|
|
||||||
|
- 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?
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
> If you think what we are doing is valuable. Please **give us a star ⭐** and **fork it 🤞**!
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Friendly UI designed for home scenarios
|
||||||
|
- No code, no forms, intuitive, design for humanity
|
||||||
|
- 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!
|
||||||
|
- Easily install numerous Docker apps
|
||||||
|
- Over 100,000 apps from the Docker ecosystem can be easily installed
|
||||||
|
- Elegant drive and file management
|
||||||
|
- What you see is what you get. No technical background required.
|
||||||
|
- Well-designed system/app widgets
|
||||||
|
- What you care about, at a glance. Resource usage, app status, and more!
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
> ⚠️ Note:
|
CasaOS fully supports ZimaBoard, Intel NUC, and Raspberry Pi. Also, more computers and development boards and fully compatible with Ubuntu, Debian, Raspberry Pi OS, and CentOS with one-liner installation.
|
||||||
>
|
|
||||||
> CasaOS is still in the early development stage and may vary significantly with the final release. Feel free to test run and share your feedback in the [Discord server](https://discord.gg/knqAbbBbeX)!
|
### Hardware Compatibility
|
||||||
|
|
||||||
|
- amd64 / x86-64
|
||||||
|
- arm64
|
||||||
|
- armv7
|
||||||
|
|
||||||
|
### System Compatibility
|
||||||
|
|
||||||
|
Official Support
|
||||||
|
- Debian 11 (✅ Tested, Recommended)
|
||||||
|
- Ubuntu Server 20.04 (✅ Tested)
|
||||||
|
- Raspberry Pi OS (✅ Tested)
|
||||||
|
|
||||||
|
Community Support
|
||||||
|
- Elementary 6.1 (✅ Tested)
|
||||||
|
- Armbian 22.04 (✅ Tested)
|
||||||
|
- Alpine (🚧 Not Fully Tested Yet)
|
||||||
|
- OpenWrt (🚧 Not Fully Tested Yet)
|
||||||
|
|
||||||
### Quick Setup CasaOS
|
### Quick Setup CasaOS
|
||||||
|
|
||||||
Fresh install a system from the list below and run the this command:
|
Freshly install a system from the list above and run this command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
wget -qO- https://get.icewhale.io/casaos.sh | bash
|
wget -qO- https://get.casaos.io | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -fsSL https://get.icewhale.io/casaos.sh | bash
|
curl -fsSL https://get.casaos.io | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
### Uninstall CasaOS
|
### Uninstall CasaOS
|
||||||
|
|
||||||
|
|
||||||
|
v0.3.3 or newer
|
||||||
|
|
||||||
|
```sh
|
||||||
|
casaos-uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
Before v0.3.3
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | bash
|
curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
### System Compatibility
|
|
||||||
|
|
||||||
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
|
||||||
- Armbian 22.02 armhf/arm64/amd64 (✅ Recommend, Tested)
|
|
||||||
- Elementary OS 6.1 Jólnir amd64 (✅ Recommend, Tested)
|
|
||||||
- Deepin 20.4 amd64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- Raspberry Pi Lite OS aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
|
||||||
- OpenWrt 21.02 aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
|
||||||
|
|
||||||
|
|
||||||
## Key Features
|
|
||||||
|
|
||||||
- UI designed for home scenarios - simple, elegant, and easy-to-use
|
|
||||||
- Quick Docker app installation with only three steps, plus automatic management
|
|
||||||
- App Store for Home Cloud 🚧
|
|
||||||
- Home data/digital asset management 🚧
|
|
||||||
- Smart home manager 🚧
|
|
||||||
|
|
||||||
🚧 is under development.
|
|
||||||
|
|
||||||
We are actively moving forward with development, and you are more than welcome to share any idea with us!
|
|
||||||
|
|
||||||
|
|
||||||
## Community
|
## 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 crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||||
@@ -74,16 +152,97 @@ After looking at many systems and software on the market, the team found no serv
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
> A warm welcome for you to share and discuss your great ideas in the [Discord server](https://discord.gg/knqAbbBbeX)!
|
We believes 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)!**
|
||||||
|
|
||||||
[](https://discord.gg/knqAbbBbeX)
|
[](https://discord.gg/knqAbbBbeX)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
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!
|
||||||
|
|
||||||
## Maintainers
|
<details>
|
||||||
- Jerry Liu
|
<summary><b>How can I get involved? 🧐</b></summary>
|
||||||
- Link Liang
|
<p>
|
||||||
- Ober Zhang
|
|
||||||
- Zyaire Ann
|
### Coding 💻 (WIP)
|
||||||
- John Guan
|
|
||||||
- Right here, waiting for YOU!
|
We are refining documentation that can be used for effective community collaboration. Feel free to start a discussion if you have a good idea.
|
||||||
|
|
||||||
|
### Helping Users 💬
|
||||||
|
|
||||||
|
If you have extensive knowledge of CasaOS and related areas. We highly encourage you to help others as much as you can in Discord and Discussions.
|
||||||
|
|
||||||
|
Discord: [https://discord.gg/knqAbbBbeX](https://discord.gg/knqAbbBbeX)
|
||||||
|
|
||||||
|
GitHub Discussions: [https://github.com/IceWhaleTech/CasaOS/discussions](https://github.com/IceWhaleTech/CasaOS/discussions)
|
||||||
|
|
||||||
|
### Helping with Translations 🌍 (WIP)
|
||||||
|
|
||||||
|
CasaOS officially supports English and Chinese. You are welcome to help make CasaOS available in more languages.
|
||||||
|
|
||||||
|
### Performing Alpha Testing ⚠️
|
||||||
|
|
||||||
|
Alpha testing is quality assurance testing that is engaged and driven by the community. It's a great way to get involved in contributing and experiencing the latest features before a new release.
|
||||||
|
|
||||||
|
The documentation is being refined and you can contact @JohnGuan via [Discord](https://discord.gg/knqAbbBbeX). Ask to join the #casaos-alpha channel.
|
||||||
|
|
||||||
|
### Writing Documentation 📖 (WIP)
|
||||||
|
|
||||||
|
Help make our documentation better by writing new content for the CasaOS Wiki, correcting existing material, or translating content into new languages.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Many thanks to everyone who has helped CasaOS so far!
|
||||||
|
|
||||||
|
Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontributors.org/docs/en/emoji-key))
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<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/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>
|
||||||
|
<td align="center"><a href="https://github.com/zarevskaya"><img src="https://avatars.githubusercontent.com/u/60230221?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Skaya</b></sub></a><br /><a href="#mentoring-zarevskaya" title="Mentoring">🧑🏫</a> <a href="#question-zarevskaya" title="Answering Questions">💬</a> <a href="#tutorial-zarevskaya" title="Tutorials">✅</a> <a href="#translation-zarevskaya" title="Translation">🌍</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/AuthorShin"><img src="https://avatars.githubusercontent.com/u/4959043?v=4?s=100" width="100px;" alt=""/><br /><sub><b>AuthorShin</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=AuthorShin" title="Tests">⚠️</a> <a href="https://github.com/IceWhaleTech/CasaOS/issues?q=author%3AAuthorShin" title="Bug reports">🐛</a> <a href="#question-AuthorShin" title="Answering Questions">💬</a> <a href="#ideas-AuthorShin" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/baptiste313"><img src="https://avatars.githubusercontent.com/u/93325157?v=4?s=100" width="100px;" alt=""/><br /><sub><b>baptiste313</b></sub></a><br /><a href="#translation-baptiste313" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/DrMxrcy"><img src="https://avatars.githubusercontent.com/u/58747968?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DrMxrcy</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=DrMxrcy" title="Tests">⚠️</a> <a href="#ideas-DrMxrcy" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-DrMxrcy" title="Answering Questions">💬</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Joooost"><img src="https://avatars.githubusercontent.com/u/12090673?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joooost</b></sub></a><br /><a href="#ideas-Joooost" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||||
|
<td align="center"><a href="https://potyarkin.ml"><img src="https://avatars.githubusercontent.com/u/334908?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vitaly Potyarkin</b></sub></a><br /><a href="#ideas-sio" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/bearfrieze"><img src="https://avatars.githubusercontent.com/u/1023813?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bjørn Friese</b></sub></a><br /><a href="#ideas-bearfrieze" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Protektor-Desura"><img src="https://avatars.githubusercontent.com/u/1195496?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Protektor</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/issues?q=author%3AProtektor-Desura" title="Bug reports">🐛</a> <a href="#ideas-Protektor-Desura" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-Protektor-Desura" title="Answering Questions">💬</a></td>
|
||||||
|
</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>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
Detailed changes for each release are documented in the [release notes](https://github.com/IceWhaleTech/CasaOS/releases).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://dashboard.trackgit.com/token/l5q8egi92tfhlxd70l2l">
|
||||||
|
<img src="https://us-central1-trackgit-analytics.cloudfunctions.net/token/ping/l5q8egi92tfhlxd70l2l" alt="trackgit-views" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|||||||
2
UI
41
alpha.md
@@ -1,41 +0,0 @@
|
|||||||
<!--
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2022-06-27 11:37:26
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-07-01 15:51:29
|
|
||||||
* @FilePath: /CasaOS/alpha.md
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
-->
|
|
||||||
|
|
||||||
# alpha Test Description
|
|
||||||
|
|
||||||
## :warning: Warning
|
|
||||||
|
|
||||||
There is a risk of data loss in non-release versions, so please be careful to back up your data.
|
|
||||||
|
|
||||||
## Install/Update
|
|
||||||
|
|
||||||
``` curl -fsSL https://get.casaos.io | bash -s -- -v v0.3.3-alpha ```
|
|
||||||
|
|
||||||
## Check change log
|
|
||||||
|
|
||||||
[CHANGELOG](https://github.com/IceWhaleTech/CasaOS/blob/main/CHANGELOG.md)
|
|
||||||
|
|
||||||
## Check Design drawings
|
|
||||||
|
|
||||||
[Design drawings](https://www.figma.com/file/pvlGobvuWEvbCb3GLqXfim/CasaOS-V0.3.3)
|
|
||||||
|
|
||||||
## Feedback questions
|
|
||||||
|
|
||||||
Go [here]() to give feedback on your question, note that try to match the picture or video
|
|
||||||
|
|
||||||
|
|
||||||
## Retest after update
|
|
||||||
|
|
||||||
Wait for the fix to appear and update and retest, and follow up on the issue
|
|
||||||
|
|
||||||
## Thanks
|
|
||||||
|
|
||||||
Thank you for your great support, we will return your support from time to time.
|
|
||||||
@@ -15,18 +15,10 @@ TempPath = /var/lib/casaos/temp
|
|||||||
|
|
||||||
[server]
|
[server]
|
||||||
HttpPort = 80
|
HttpPort = 80
|
||||||
UDPPort =
|
|
||||||
RunMode = release
|
RunMode = release
|
||||||
ServerApi = https://api.casaos.io/casaos-api
|
ServerApi = https://api.casaos.io/casaos-api
|
||||||
Handshake = socket.casaos.io
|
Handshake = socket.casaos.io
|
||||||
Token =
|
Token =
|
||||||
USBAutoMount =
|
USBAutoMount =
|
||||||
|
|
||||||
|
|
||||||
[system]
|
[system]
|
||||||
WidgetList =
|
|
||||||
|
|
||||||
|
|
||||||
[file]
|
|
||||||
ShareDir =
|
|
||||||
DownloadDir =
|
|
||||||
19
go.mod
@@ -6,7 +6,6 @@ require (
|
|||||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
||||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||||
github.com/Microsoft/hcsshim v0.8.22 // indirect
|
github.com/Microsoft/hcsshim v0.8.22 // indirect
|
||||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
|
|
||||||
github.com/ambelovsky/go-structs v1.1.0 // indirect
|
github.com/ambelovsky/go-structs v1.1.0 // indirect
|
||||||
github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109
|
github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109
|
||||||
github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 // indirect
|
github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 // indirect
|
||||||
@@ -19,28 +18,27 @@ require (
|
|||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
|
|
||||||
github.com/gin-contrib/gzip v0.0.2
|
github.com/gin-contrib/gzip v0.0.2
|
||||||
github.com/gin-gonic/gin v1.7.2
|
github.com/gin-gonic/gin v1.7.2
|
||||||
github.com/go-ini/ini v1.62.0
|
github.com/go-ini/ini v1.62.0
|
||||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
|
||||||
github.com/go-openapi/spec v0.20.4 // indirect
|
|
||||||
github.com/go-playground/validator/v10 v10.6.1 // indirect
|
github.com/go-playground/validator/v10 v10.6.1 // indirect
|
||||||
github.com/gogo/googleapis v1.4.1 // indirect
|
github.com/gogo/googleapis v1.4.1 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.1
|
github.com/golang-jwt/jwt/v4 v4.4.1
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/mock v1.6.0
|
||||||
github.com/gomodule/redigo v1.8.5
|
github.com/gomodule/redigo v1.8.5
|
||||||
github.com/google/go-github/v36 v36.0.0
|
github.com/google/go-github/v36 v36.0.0
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/googollee/go-socket.io v1.6.2
|
github.com/googollee/go-socket.io v1.6.2
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
|
github.com/hirochachacha/go-smb2 v1.1.0
|
||||||
github.com/jinzhu/copier v0.3.2
|
github.com/jinzhu/copier v0.3.2
|
||||||
github.com/json-iterator/go v1.1.11 // indirect
|
github.com/json-iterator/go v1.1.11 // indirect
|
||||||
github.com/klauspost/compress v1.13.6 // indirect
|
github.com/klauspost/compress v1.13.6 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/lucas-clemente/quic-go v0.25.0
|
github.com/lucas-clemente/quic-go v0.25.0
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.11 // indirect
|
github.com/mattn/go-sqlite3 v1.14.11 // indirect
|
||||||
github.com/mholt/archiver/v3 v3.5.1
|
github.com/mholt/archiver/v3 v3.5.1
|
||||||
@@ -49,19 +47,17 @@ require (
|
|||||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||||
github.com/opencontainers/selinux v1.8.5 // indirect
|
github.com/opencontainers/selinux v1.8.5 // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
|
github.com/pilebones/go-udev v0.9.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109
|
|
||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
github.com/robfig/cron v1.2.0
|
github.com/robfig/cron v1.2.0
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shirou/gopsutil/v3 v3.21.5
|
github.com/shirou/gopsutil/v3 v3.22.7
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/smartystreets/assertions v1.2.0 // indirect
|
github.com/smartystreets/assertions v1.2.0 // indirect
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/swaggo/gin-swagger v1.3.0
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/swaggo/swag v1.7.3
|
|
||||||
github.com/tidwall/gjson v1.10.2
|
github.com/tidwall/gjson v1.10.2
|
||||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
|
||||||
github.com/ugorji/go v1.2.6 // indirect
|
github.com/ugorji/go v1.2.6 // indirect
|
||||||
go.opencensus.io v0.23.0 // indirect
|
go.opencensus.io v0.23.0 // indirect
|
||||||
go.uber.org/zap v1.10.0
|
go.uber.org/zap v1.10.0
|
||||||
@@ -69,8 +65,8 @@ require (
|
|||||||
golang.org/x/mod v0.5.0 // indirect
|
golang.org/x/mod v0.5.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
|
||||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985 // indirect
|
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||||
golang.org/x/tools v0.1.7 // indirect
|
golang.org/x/tools v0.1.7 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
@@ -79,7 +75,6 @@ require (
|
|||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
|
||||||
gorm.io/driver/sqlite v1.2.6
|
gorm.io/driver/sqlite v1.2.6
|
||||||
gorm.io/gorm v1.22.5
|
gorm.io/gorm v1.22.5
|
||||||
)
|
)
|
||||||
|
|||||||
122
go.sum
@@ -59,8 +59,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
|||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
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 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/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
@@ -85,17 +83,10 @@ github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5
|
|||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
|
||||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY=
|
|
||||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
@@ -328,8 +319,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
|||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b h1:r13MvtFTtnvxtuKK7z0ZSQ2EfMmTzWDHwfDvGCoqUQE=
|
|
||||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b/go.mod h1:EfR6AU78zUiZ36oVS5YrmTzc2um3zDXWPx4L4st++jo=
|
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||||
@@ -338,17 +327,14 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
|||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
|
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
||||||
|
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
|
||||||
github.com/gin-contrib/gzip v0.0.2 h1:VMBkd4ZB1Hl7e1lOA5gEZ/qdD3d9vLIq57xKWgPCCV8=
|
github.com/gin-contrib/gzip v0.0.2 h1:VMBkd4ZB1Hl7e1lOA5gEZ/qdD3d9vLIq57xKWgPCCV8=
|
||||||
github.com/gin-contrib/gzip v0.0.2/go.mod h1:YxxswVZIqOvcHEQpsSn+QF5guQtO1dCfy0shBPy4jFc=
|
github.com/gin-contrib/gzip v0.0.2/go.mod h1:YxxswVZIqOvcHEQpsSn+QF5guQtO1dCfy0shBPy4jFc=
|
||||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
|
||||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
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-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
@@ -369,32 +355,15 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
|
||||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
|
||||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
|
||||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
|
||||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
|
||||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
|
||||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
|
||||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
|
||||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
@@ -484,8 +453,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
|
||||||
github.com/google/go-cmp v0.5.6/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.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||||
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs=
|
||||||
@@ -542,6 +512,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
|||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hirochachacha/go-smb2 v1.1.0 h1:b6hs9qKIql9eVXAiN0M2wSFY5xnhbHAQoCwRKbaRTZI=
|
||||||
|
github.com/hirochachacha/go-smb2 v1.1.0/go.mod h1:8F1A4d5EZzrGu5R7PU163UcMRDJQl4FtcxjBfsY8TZE=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@@ -563,9 +535,6 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
|
|||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
|
||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
@@ -609,16 +578,14 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
|||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3mP4CLgibc=
|
github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3mP4CLgibc=
|
||||||
github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg=
|
github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||||
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||||
github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
||||||
@@ -630,8 +597,6 @@ github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaI
|
|||||||
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI=
|
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
@@ -676,7 +641,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
|||||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
|
||||||
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
@@ -741,6 +705,8 @@ github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrap
|
|||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM=
|
github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM=
|
||||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
|
github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q=
|
||||||
|
github.com/pilebones/go-udev v0.9.0/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@@ -748,9 +714,9 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109 h1:h9WYaTCQJ7hap8C5vQniEum2YZbc+iRad/ROafTjy10=
|
|
||||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109/go.mod h1:U7VCLF6LMHzOFD/6Kww2MTQuwaNeEA1U1dOxFyZBoBE=
|
|
||||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
@@ -797,9 +763,8 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shirou/gopsutil/v3 v3.21.5 h1:YUBf0w/KPLk7w1803AYBnH7BmA+1Z/Q5MEZxpREUaB4=
|
github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4=
|
||||||
github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
|
||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||||
@@ -860,20 +825,17 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
|
||||||
github.com/swaggo/swag v1.7.3 h1:ucB7irEdRrhjmW+Z1Ss4GjO68oPKQFjSgOR8BCAvcbU=
|
|
||||||
github.com/swaggo/swag v1.7.3/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI=
|
|
||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
@@ -885,23 +847,18 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
|
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||||
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
|
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||||
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||||
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
|
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||||
github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
|
|
||||||
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
|
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
|
|
||||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
|
||||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
@@ -911,7 +868,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/
|
|||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
|
||||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
@@ -935,6 +891,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||||
@@ -1018,7 +976,6 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
|||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -1033,7 +990,6 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -1062,10 +1018,8 @@ golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
|
golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
|
||||||
@@ -1098,9 +1052,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -1112,7 +1064,6 @@ golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -1162,14 +1113,11 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@@ -1177,8 +1125,9 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985 h1:LOlKVhfDyahgmqa97awczplwkjzNaELFg3zRIJ13RYo=
|
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -1213,9 +1162,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
@@ -1251,7 +1198,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
@@ -1375,15 +1321,12 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
@@ -1407,9 +1350,8 @@ 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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
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-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
||||||
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
||||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||||
|
|||||||
51
main.go
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
||||||
"github.com/IceWhaleTech/CasaOS/route"
|
"github.com/IceWhaleTech/CasaOS/route"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
|
|
||||||
"github.com/robfig/cron"
|
"github.com/robfig/cron"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -24,28 +25,33 @@ var sqliteDB *gorm.DB
|
|||||||
|
|
||||||
var configFlag = flag.String("c", "", "config address")
|
var configFlag = flag.String("c", "", "config address")
|
||||||
var dbFlag = flag.String("db", "", "db path")
|
var dbFlag = flag.String("db", "", "db path")
|
||||||
var showUserInfo = flag.Bool("show-user-info", false, "show user info")
|
|
||||||
var resetUser = flag.Bool("ru", false, "reset user")
|
var resetUser = flag.Bool("ru", false, "reset user")
|
||||||
var user = flag.String("user", "", "user name")
|
var user = flag.String("user", "", "user name")
|
||||||
|
var version = flag.Bool("v", false, "show version")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
if *version {
|
||||||
|
fmt.Println("v" + types.CURRENTVERSION)
|
||||||
|
return
|
||||||
|
}
|
||||||
config.InitSetup(*configFlag)
|
config.InitSetup(*configFlag)
|
||||||
config.UpdateSetup()
|
config.UpdateSetup()
|
||||||
|
|
||||||
loger.LogInit()
|
loger.LogInit()
|
||||||
if len(*dbFlag) == 0 {
|
if len(*dbFlag) == 0 {
|
||||||
*dbFlag = config.AppInfo.DBPath + "/db"
|
*dbFlag = config.AppInfo.DBPath + "/db"
|
||||||
}
|
}
|
||||||
|
|
||||||
sqliteDB = sqlite.GetDb(*dbFlag)
|
sqliteDB = sqlite.GetDb(*dbFlag)
|
||||||
//gredis.GetRedisConn(config.RedisInfo),
|
//gredis.GetRedisConn(config.RedisInfo),
|
||||||
|
|
||||||
service.MyService = service.NewService(sqliteDB)
|
service.MyService = service.NewService(sqliteDB)
|
||||||
|
|
||||||
service.Cache = cache.Init()
|
service.Cache = cache.Init()
|
||||||
|
|
||||||
service.GetToken()
|
service.GetToken()
|
||||||
service.UDPAddressMap = make(map[string]string)
|
|
||||||
//go service.SocketConnect()
|
|
||||||
service.CancelList = make(map[string]string)
|
|
||||||
service.InternalInspection = make(map[string][]string)
|
|
||||||
service.NewVersionApp = make(map[string]string)
|
service.NewVersionApp = make(map[string]string)
|
||||||
route.InitFunction()
|
route.InitFunction()
|
||||||
|
|
||||||
@@ -67,15 +73,10 @@ func init() {
|
|||||||
// @BasePath /v1
|
// @BasePath /v1
|
||||||
func main() {
|
func main() {
|
||||||
service.NotifyMsg = make(chan notify.Message, 10)
|
service.NotifyMsg = make(chan notify.Message, 10)
|
||||||
if *showUserInfo {
|
if *version {
|
||||||
fmt.Println("CasaOS User Info")
|
|
||||||
fmt.Println("UserName:" + config.UserInfo.UserName)
|
|
||||||
fmt.Println("Password:" + config.UserInfo.PWD)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println("Reset User", *resetUser)
|
|
||||||
if *resetUser {
|
if *resetUser {
|
||||||
|
|
||||||
if user == nil || len(*user) == 0 {
|
if user == nil || len(*user) == 0 {
|
||||||
fmt.Println("user is empty")
|
fmt.Println("user is empty")
|
||||||
return
|
return
|
||||||
@@ -89,42 +90,20 @@ func main() {
|
|||||||
userData.Password = encryption.GetMD5ByStr(password)
|
userData.Password = encryption.GetMD5ByStr(password)
|
||||||
service.MyService.User().UpdateUserPassword(userData)
|
service.MyService.User().UpdateUserPassword(userData)
|
||||||
fmt.Println("User reset successful")
|
fmt.Println("User reset successful")
|
||||||
fmt.Println("UserName:" + userData.UserName)
|
fmt.Println("UserName:" + userData.Username)
|
||||||
fmt.Println("Password:" + password)
|
fmt.Println("Password:" + password)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go func() {
|
|
||||||
service.UDPService()
|
|
||||||
service.SendIPToServer()
|
|
||||||
}()
|
|
||||||
go route.SocketInit(service.NotifyMsg)
|
go route.SocketInit(service.NotifyMsg)
|
||||||
go func() {
|
go route.MonitoryUSB()
|
||||||
for i := 0; i < 1000; i++ {
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
//service.NotifyMsg <- strconv.Itoa(i)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
//model.Setup()
|
//model.Setup()
|
||||||
//gredis.Setup()
|
//gredis.Setup()
|
||||||
r := route.InitRouter()
|
r := route.InitRouter()
|
||||||
//service.SyncTask(sqliteDB)
|
//service.SyncTask(sqliteDB)
|
||||||
cron2 := cron.New()
|
cron2 := cron.New()
|
||||||
//every day execution
|
//every day execution
|
||||||
err := cron2.AddFunc("0 0/5 * * * *", func() {
|
|
||||||
//service.PushIpInfo(*&config.ServerInfo.Token)
|
|
||||||
//service.UpdataDDNSList(mysqldb)
|
|
||||||
//service.SyncTask(sqliteDB)
|
|
||||||
|
|
||||||
service.SendIPToServer()
|
err := cron2.AddFunc("0/5 * * * * *", func() {
|
||||||
|
|
||||||
service.LoopFriend()
|
|
||||||
//service.MyService.App().CheckNewImage()
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
err = cron2.AddFunc("0/5 * * * * *", func() {
|
|
||||||
if service.ClientCount > 0 {
|
if service.ClientCount > 0 {
|
||||||
//route.SendNetINfoBySocket()
|
//route.SendNetINfoBySocket()
|
||||||
//route.SendCPUBySocket()
|
//route.SendCPUBySocket()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2021-10-08 10:29:08
|
* @Date: 2021-10-08 10:29:08
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-21 15:10:03
|
* @LastEditTime: 2022-07-22 11:06:07
|
||||||
* @FilePath: /CasaOS/middleware/gin.go
|
* @FilePath: /CasaOS/middleware/gin.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -13,6 +13,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -26,14 +27,14 @@ func Cors() gin.HandlerFunc {
|
|||||||
c.Header("Access-Control-Allow-Origin", "*")
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
|
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
|
||||||
//允许跨域设置可以返回其他子段,可以自定义字段
|
//允许跨域设置可以返回其他子段,可以自定义字段
|
||||||
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language")
|
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language,Content-Type,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Connection,Host,Origin,Referer,User-Agent,X-Requested-With")
|
||||||
// 允许浏览器(客户端)可以解析的头部 (重要)
|
// 允许浏览器(客户端)可以解析的头部 (重要)
|
||||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
|
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
|
||||||
//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
|
//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
|
||||||
//设置缓存时间
|
//设置缓存时间
|
||||||
c.Header("Access-Control-Max-Age", "172800")
|
c.Header("Access-Control-Max-Age", "172800")
|
||||||
c.Header("Access-Control-Allow-Credentials", "true")
|
c.Header("Access-Control-Allow-Credentials", "true")
|
||||||
c.Set("content-type", "application/json")
|
c.Set("Content-Type", "application/json")
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//允许类型校验
|
//允许类型校验
|
||||||
@@ -52,7 +53,10 @@ func Cors() gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
func WriteLog() gin.HandlerFunc {
|
func WriteLog() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("body", c.Request.Body), zap.Any("method", c.Request.Method))
|
if !strings.Contains(c.Request.URL.String(), "password") {
|
||||||
|
loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("method", c.Request.Method))
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2022-03-18 11:40:55
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-05-13 14:48:01
|
|
||||||
* @FilePath: /CasaOS/model/app-analyse.go
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package model
|
|
||||||
|
|
||||||
type AppAnalyse struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
UUId string `json:"uuid"`
|
|
||||||
Language string `json:"language"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ConnectionStatus struct {
|
|
||||||
From string `json:"from"`
|
|
||||||
To string `json:"to"`
|
|
||||||
Error string `json:"error"`
|
|
||||||
UUId string `json:"uuid"`
|
|
||||||
Event string `json:"event"`
|
|
||||||
}
|
|
||||||
11
model/app.go
@@ -13,6 +13,15 @@ type ServerAppListCollection struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @tiger - 对于用于出参的数据结构,静态信息(例如 title)和
|
||||||
|
// 动态信息(例如 state、query_count)应该划分到不同的数据结构中
|
||||||
|
//
|
||||||
|
// 这样的好处是
|
||||||
|
// 1 - 多次获取动态信息时可以减少出参复杂度,因为静态信息只获取一次就好
|
||||||
|
// 2 - 在未来的迭代中,可以降低维护成本(所有字段都展开放在一个层级维护成本略高)
|
||||||
|
//
|
||||||
|
// 另外,一些针对性字段,例如 Docker 相关的,可以用 map 来保存。
|
||||||
|
// 这样在未来增加多态 App,例如 Snap,不需要维护多个结构,或者一个结构保存不必要的字段
|
||||||
type ServerAppList struct {
|
type ServerAppList struct {
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
@@ -36,7 +45,7 @@ type ServerAppList struct {
|
|||||||
Index string `json:"index"`
|
Index string `json:"index"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
State string `json:"state"`
|
State int `json:"state"`
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
MinMemory int `json:"min_memory"`
|
MinMemory int `json:"min_memory"`
|
||||||
MinDisk int `json:"min_disk"`
|
MinDisk int `json:"min_disk"`
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
* @Author: link a624669980@163.com
|
* @Author: link a624669980@163.com
|
||||||
* @Date: 2022-05-16 17:37:08
|
* @Date: 2022-05-16 17:37:08
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-22 17:45:53
|
* @LastEditTime: 2022-07-13 10:46:38
|
||||||
* @FilePath: /CasaOS/model/category.go
|
* @FilePath: /CasaOS/model/category.go
|
||||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
* @Description:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ type CategoryList struct {
|
|||||||
//CreatedAt time.Time `json:"created_at"`
|
//CreatedAt time.Time `json:"created_at"`
|
||||||
//
|
//
|
||||||
//UpdatedAt time.Time `json:"updated_at"`
|
//UpdatedAt time.Time `json:"updated_at"`
|
||||||
Font string `json:"font"`
|
Font string `json:"font"` // @tiger - 如果这个和前端有关,应该不属于后端的出参范围,而是前端去界定
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Count uint `json:"count"`
|
Count uint `json:"count"` // @tiger - count 属于动态信息,应该单独放在一个出参结构中(原因见另外一个关于 静态/动态 出参的注释)
|
||||||
}
|
}
|
||||||
|
|||||||
20
model/connections.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-27 10:30:43
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-04 20:06:04
|
||||||
|
* @FilePath: /CasaOS/model/connections.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Connections struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
MountPoint string `json:"mount_point"`
|
||||||
|
}
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-13 10:43:45
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-03 14:45:35
|
||||||
|
* @FilePath: /CasaOS/model/disk.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
type LSBLKModel struct {
|
type LSBLKModel struct {
|
||||||
@@ -29,6 +39,7 @@ type LSBLKModel struct {
|
|||||||
Serial string `json:"serial"`
|
Serial string `json:"serial"`
|
||||||
Children []LSBLKModel `json:"children"`
|
Children []LSBLKModel `json:"children"`
|
||||||
SubSystems string `json:"subsystems"`
|
SubSystems string `json:"subsystems"`
|
||||||
|
Label string `json:"label"`
|
||||||
//详情特有
|
//详情特有
|
||||||
StartSector uint64 `json:"start_sector,omitempty"`
|
StartSector uint64 `json:"start_sector,omitempty"`
|
||||||
Rota bool `json:"rota"` //true(hhd) false(ssd)
|
Rota bool `json:"rota"` //true(hhd) false(ssd)
|
||||||
@@ -46,26 +57,37 @@ type Drive struct {
|
|||||||
NeedFormat bool `json:"need_format"`
|
NeedFormat bool `json:"need_format"`
|
||||||
Serial string `json:"serial"`
|
Serial string `json:"serial"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
ChildrenNumber int `json:"children_number"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DriveUSB struct {
|
type DriveUSB struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Size uint64 `json:"size"`
|
Size uint64 `json:"size"`
|
||||||
Used uint64 `json:"use"`
|
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
Mount bool `json:"mount"` //是否完全挂载
|
Avail uint64 `json:"avail"`
|
||||||
Avail uint64 `json:"avail"` //可用空间
|
Children []USBChildren `json:"children"`
|
||||||
|
}
|
||||||
|
type USBChildren struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Avail uint64 `json:"avail"`
|
||||||
|
MountPoint string `json:"mount_point"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
Name string `json:"name"`
|
MountPoint string `json:"mount_point"`
|
||||||
MountPoint string `json:"mountpoint"`
|
|
||||||
Size string `json:"size"`
|
Size string `json:"size"`
|
||||||
Avail string `json:"avail"` //可用空间
|
Avail string `json:"avail"` //可用空间
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
CreatedAt int64 `json:"create_at"`
|
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
DriveName string `json:"drive_name"`
|
DriveName string `json:"drive_name"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
}
|
||||||
|
type Storages struct {
|
||||||
|
DiskName string `json:"disk_name"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Children []Storage `json:"children"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Summary struct {
|
type Summary struct {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2021-12-08 18:10:25
|
* @Date: 2021-12-08 18:10:25
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-14 17:20:36
|
* @LastEditTime: 2022-07-13 10:49:16
|
||||||
* @FilePath: /CasaOS/model/docker.go
|
* @FilePath: /CasaOS/model/docker.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -14,5 +14,5 @@ type DockerStatsModel struct {
|
|||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Data interface{} `json:"data"`
|
Data interface{} `json:"data"`
|
||||||
Pre interface{} `json:"pre"`
|
Previous interface{} `json:"previous"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ func (p *PathArray) Scan(input interface{}) error {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
type CustomizationPostData struct {
|
type CustomizationPostData struct {
|
||||||
|
ContainerName string `json:"container_name"`
|
||||||
CustomId string `json:"custom_id"`
|
CustomId string `json:"custom_id"`
|
||||||
Origin string `json:"origin"`
|
Origin string `json:"origin"`
|
||||||
NetworkModel string `json:"network_model"`
|
NetworkModel string `json:"network_model"`
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2022-05-27 18:42:42
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-05-27 18:43:08
|
|
||||||
* @FilePath: /CasaOS/model/notify/person.go
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package notify
|
|
||||||
|
|
||||||
type Person struct {
|
|
||||||
ShareId string `json:"share_id"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
}
|
|
||||||
19
model/notify/storage.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-15 10:43:00
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-07-15 10:56:17
|
||||||
|
* @FilePath: /CasaOS/model/notify/storage.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package notify
|
||||||
|
|
||||||
|
type StorageMessage struct {
|
||||||
|
Type string `json:"type"` //sata,usb
|
||||||
|
Action string `json:"action"` //remove add
|
||||||
|
Path string `json:"path"`
|
||||||
|
Volume string `json:"volume"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type PersionModel struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
Ips []string `json:"ips"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//记录链接状态
|
|
||||||
type ConnectState struct {
|
|
||||||
From string `json:"from"`
|
|
||||||
To string `json:"to"`
|
|
||||||
Type string `json:"type"` //current state 1:ready 2:ok
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UUId string `json:"uuid"` //对接标识
|
|
||||||
}
|
|
||||||
type MessageModel struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
UUId string `json:"uuid"`
|
|
||||||
From string `json:"from"`
|
|
||||||
To string `json:"to"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TranFileModel struct {
|
|
||||||
Hash string `json:"hash"` //Verify current fragment integrity
|
|
||||||
Length int `json:"length"`
|
|
||||||
Index int `json:"index"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//需要获取文件详情
|
|
||||||
type FileDetailModel struct {
|
|
||||||
Path string `json:"path"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回文件详情
|
|
||||||
type FileSummaryModel struct {
|
|
||||||
Hash string `json:"hash"` //Verify file
|
|
||||||
Name string `json:"name"`
|
|
||||||
BlockSize int `json:"block_size"`
|
|
||||||
Length int `json:"length"`
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FriendsModel struct {
|
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
|
||||||
NickName string `json:"nick_name"`
|
|
||||||
Desc string `json:"desc"`
|
|
||||||
ShareId string `json:"share_id"`
|
|
||||||
}
|
|
||||||
17
model/share.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-26 11:12:12
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-07-27 14:58:55
|
||||||
|
* @FilePath: /CasaOS/model/share.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Shares struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Anonymous bool `json:"anonymous"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-16 17:50:56
|
* @LastEditTime: 2022-07-14 11:02:06
|
||||||
* @FilePath: /CasaOS/model/sys_common.go
|
* @FilePath: /CasaOS/model/sys_common.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -37,9 +37,7 @@ type ServerModel struct {
|
|||||||
RunMode string
|
RunMode string
|
||||||
ServerApi string
|
ServerApi string
|
||||||
LockAccount bool
|
LockAccount bool
|
||||||
Handshake string
|
|
||||||
Token string
|
Token string
|
||||||
UDPPort string
|
|
||||||
USBAutoMount string
|
USBAutoMount string
|
||||||
SocketPort string
|
SocketPort string
|
||||||
}
|
}
|
||||||
@@ -76,12 +74,7 @@ type RedisModel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SystemConfig struct {
|
type SystemConfig struct {
|
||||||
ConfigStr string `json:"config_str"`
|
|
||||||
WidgetList string `json:"widget_list"`
|
|
||||||
ConfigPath string `json:"config_path"`
|
ConfigPath string `json:"config_path"`
|
||||||
SyncPort string `json:"sync_port"`
|
|
||||||
SyncKey string `json:"sync_key"`
|
|
||||||
Analyse string `json:"analyse"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CasaOSGlobalVariables struct {
|
type CasaOSGlobalVariables struct {
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-05-13 18:15:46
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-01 18:32:57
|
||||||
|
* @FilePath: /CasaOS/model/zima.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
@@ -11,4 +21,5 @@ type Path struct {
|
|||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Label string `json:"label,omitempty"`
|
Label string `json:"label,omitempty"`
|
||||||
Write bool `json:"write"`
|
Write bool `json:"write"`
|
||||||
|
Extensions map[string]interface{} `json:"extensions"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-21 16:01:26
|
* @LastEditTime: 2022-07-14 10:58:45
|
||||||
* @FilePath: /CasaOS/pkg/config/init.go
|
* @FilePath: /CasaOS/pkg/config/init.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -15,7 +14,7 @@ import (
|
|||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSshClient(user, password string) (*ssh.Client, error) {
|
func NewSshClient(user, password string, port string) (*ssh.Client, error) {
|
||||||
|
|
||||||
// connet to ssh
|
// connet to ssh
|
||||||
// addr = fmt.Sprintf("%s:%d", host, port)
|
// addr = fmt.Sprintf("%s:%d", host, port)
|
||||||
@@ -32,7 +31,7 @@ func NewSshClient(user, password string) (*ssh.Client, error) {
|
|||||||
//} else {
|
//} else {
|
||||||
// config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)}
|
// config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)}
|
||||||
//}
|
//}
|
||||||
addr := fmt.Sprintf("%s:%d", "127.0.0.1", 22)
|
addr := fmt.Sprintf("%s:%s", "127.0.0.1", port)
|
||||||
c, err := ssh.Dial("tcp", addr, config)
|
c, err := ssh.Dial("tcp", addr, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -396,7 +395,7 @@ func WsReaderCopy(reader *websocket.Conn, writer io.Writer) {
|
|||||||
if err = json2.Unmarshal(p, &msgObj); err != nil {
|
if err = json2.Unmarshal(p, &msgObj); err != nil {
|
||||||
writer.Write(p)
|
writer.Write(p)
|
||||||
} else if msgObj.Type == wsMsgResize {
|
} else if msgObj.Type == wsMsgResize {
|
||||||
writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r"))
|
//writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
pkg/samba/smaba.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-27 10:35:29
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-01 13:56:44
|
||||||
|
* @FilePath: /CasaOS/pkg/samba/smaba.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package samba
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/hirochachacha/go-smb2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConnectSambaService(host, port, username, password, directory string) error {
|
||||||
|
conn, err := net.Dial("tcp", host+":"+port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
d := &smb2.Dialer{
|
||||||
|
Initiator: &smb2.NTLMInitiator{
|
||||||
|
User: username,
|
||||||
|
Password: password,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := d.Dial(conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Logoff()
|
||||||
|
names, err := s.ListSharenames()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
|
if name == directory {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.New("directory not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
//get share name list
|
||||||
|
func GetSambaSharesList(host, port, username, password string) ([]string, error) {
|
||||||
|
conn, err := net.Dial("tcp", host+":"+port)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
d := &smb2.Dialer{
|
||||||
|
Initiator: &smb2.NTLMInitiator{
|
||||||
|
User: username,
|
||||||
|
Password: password,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := d.Dial(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer s.Logoff()
|
||||||
|
names, err := s.ListSharenames()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return names, err
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-22 18:50:44
|
* @LastEditTime: 2022-07-27 11:25:26
|
||||||
* @FilePath: /CasaOS/pkg/sqlite/db.go
|
* @FilePath: /CasaOS/pkg/sqlite/db.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -42,8 +42,22 @@ func GetDb(dbPath string) *gorm.DB {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
gdb = db
|
gdb = db
|
||||||
err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{}, model2.PersonDownRecordDBModel{}, model2.UserDBModel{})
|
|
||||||
|
db.Exec(`alter table o_user rename to old_user;
|
||||||
|
|
||||||
|
create table o_users ( id integer primary key,username text,password text,role text,email text,nickname text,avatar text,description text,created_at datetime,updated_at datetime);
|
||||||
|
|
||||||
|
insert into o_users select id,user_name,password,role,email,nick_name,avatar,description,created_at,updated_at from old_user;
|
||||||
|
|
||||||
|
drop table old_user;
|
||||||
|
drop table o_user;
|
||||||
|
`)
|
||||||
|
|
||||||
|
err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.UserDBModel{}, model2.SharesDBModel{}, model2.ConnectionsDBModel{})
|
||||||
db.Exec("DROP TABLE IF EXISTS o_application")
|
db.Exec("DROP TABLE IF EXISTS o_application")
|
||||||
|
db.Exec("DROP TABLE IF EXISTS o_friend")
|
||||||
|
db.Exec("DROP TABLE IF EXISTS o_person_download")
|
||||||
|
db.Exec("DROP TABLE IF EXISTS o_person_down_record")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("check or create db error", zap.Any("error", err))
|
loger.Error("check or create db error", zap.Any("error", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package common_err
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
SUCCESS = 200
|
SUCCESS = 200
|
||||||
ERROR = 500
|
SERVICE_ERROR = 500
|
||||||
INVALID_PARAMS = 400
|
CLIENT_ERROR = 400
|
||||||
ERROR_AUTH_TOKEN = 401
|
ERROR_AUTH_TOKEN = 401
|
||||||
|
|
||||||
|
INVALID_PARAMS = 4000
|
||||||
//user
|
//user
|
||||||
PWD_INVALID = 10001
|
PWD_INVALID = 10001
|
||||||
PWD_IS_EMPTY = 10002
|
PWD_IS_EMPTY = 10002
|
||||||
@@ -26,6 +27,9 @@ const (
|
|||||||
PORT_IS_OCCUPIED = 20004
|
PORT_IS_OCCUPIED = 20004
|
||||||
COMMAND_ERROR_INVALID_OPERATION = 20005
|
COMMAND_ERROR_INVALID_OPERATION = 20005
|
||||||
VERIFICATION_FAILURE = 20006
|
VERIFICATION_FAILURE = 20006
|
||||||
|
Record_NOT_EXIST = 20007
|
||||||
|
Record_ALREADY_EXIST = 20008
|
||||||
|
SERVICE_NOT_RUNNING = 20009
|
||||||
|
|
||||||
//disk
|
//disk
|
||||||
NAME_NOT_AVAILABLE = 40001
|
NAME_NOT_AVAILABLE = 40001
|
||||||
@@ -47,21 +51,15 @@ const (
|
|||||||
DIR_NOT_EXISTS = 60004
|
DIR_NOT_EXISTS = 60004
|
||||||
SOURCE_DES_SAME = 60005
|
SOURCE_DES_SAME = 60005
|
||||||
|
|
||||||
//shortcuts
|
//share
|
||||||
SHORTCUTS_URL_ERROR = 70001
|
SHARE_ALREADY_EXISTS = 70001
|
||||||
|
SHARE_NAME_ALREADY_EXISTS = 70002
|
||||||
//person
|
|
||||||
PERSON_REMOTE_ERROR = 80001
|
|
||||||
PERSON_DOWN_NOT_EXIST = 80002
|
|
||||||
PERSON_EXIST_DOWNLOAD = 80003
|
|
||||||
PERSON_NOT_EXIST_USER = 80004
|
|
||||||
PERSON_EXIST_FRIEND = 80005
|
|
||||||
PERSON_MYSELF = 80006
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var MsgFlags = map[int]string{
|
var MsgFlags = map[int]string{
|
||||||
SUCCESS: "ok",
|
SUCCESS: "ok",
|
||||||
ERROR: "fail",
|
SERVICE_ERROR: "Fail",
|
||||||
|
CLIENT_ERROR: "Fail",
|
||||||
INVALID_PARAMS: "Parameters Error",
|
INVALID_PARAMS: "Parameters Error",
|
||||||
ERROR_AUTH_TOKEN: "Error auth token",
|
ERROR_AUTH_TOKEN: "Error auth token",
|
||||||
|
|
||||||
@@ -84,6 +82,9 @@ var MsgFlags = map[int]string{
|
|||||||
FILE_OR_DIR_EXISTS: "File or folder already exists",
|
FILE_OR_DIR_EXISTS: "File or folder already exists",
|
||||||
PORT_IS_OCCUPIED: "Port is occupied",
|
PORT_IS_OCCUPIED: "Port is occupied",
|
||||||
VERIFICATION_FAILURE: "Verification failure",
|
VERIFICATION_FAILURE: "Verification failure",
|
||||||
|
Record_ALREADY_EXIST: "Record already exists",
|
||||||
|
Record_NOT_EXIST: "Record does not exist",
|
||||||
|
SERVICE_NOT_RUNNING: "Service is not running",
|
||||||
|
|
||||||
//app
|
//app
|
||||||
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
UNINSTALL_APP_ERROR: "Error uninstalling app",
|
||||||
@@ -97,7 +98,9 @@ var MsgFlags = map[int]string{
|
|||||||
REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point",
|
REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point",
|
||||||
DISK_BUSYING: "Drive is busy",
|
DISK_BUSYING: "Drive is busy",
|
||||||
FORMAT_ERROR: "Formatting failed, please check if the directory is occupied",
|
FORMAT_ERROR: "Formatting failed, please check if the directory is occupied",
|
||||||
|
//share
|
||||||
|
SHARE_ALREADY_EXISTS: "Share already exists",
|
||||||
|
SHARE_NAME_ALREADY_EXISTS: "Share name already exists",
|
||||||
//
|
//
|
||||||
SOURCE_DES_SAME: "Source and destination cannot be the same.",
|
SOURCE_DES_SAME: "Source and destination cannot be the same.",
|
||||||
FILE_DOES_NOT_EXIST: "File does not exist",
|
FILE_DOES_NOT_EXIST: "File does not exist",
|
||||||
@@ -106,14 +109,7 @@ var MsgFlags = map[int]string{
|
|||||||
|
|
||||||
FILE_READ_ERROR: "File read error",
|
FILE_READ_ERROR: "File read error",
|
||||||
FILE_DELETE_ERROR: "Delete error",
|
FILE_DELETE_ERROR: "Delete error",
|
||||||
SHORTCUTS_URL_ERROR: "URL error",
|
|
||||||
|
|
||||||
PERSON_REMOTE_ERROR: "Remote connection error",
|
|
||||||
PERSON_DOWN_NOT_EXIST: "Download record does not exist",
|
|
||||||
PERSON_EXIST_DOWNLOAD: "The same download task exists",
|
|
||||||
PERSON_EXIST_FRIEND: "Friend already exist",
|
|
||||||
PERSON_NOT_EXIST_USER: "User does not exist",
|
|
||||||
PERSON_MYSELF: "You can not add yourself",
|
|
||||||
COMMAND_ERROR_INVALID_OPERATION: "invalid operation",
|
COMMAND_ERROR_INVALID_OPERATION: "invalid operation",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,5 +119,5 @@ func GetMsg(code int) string {
|
|||||||
if ok {
|
if ok {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
return MsgFlags[ERROR]
|
return MsgFlags[SERVICE_ERROR]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -547,3 +547,20 @@ func MoveFile(sourcePath, destPath string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadLine(lineNumber int, path string) string {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
fileScanner := bufio.NewScanner(file)
|
||||||
|
lineCount := 1
|
||||||
|
for fileScanner.Scan() {
|
||||||
|
if lineCount == lineNumber {
|
||||||
|
return fileScanner.Text()
|
||||||
|
}
|
||||||
|
lineCount++
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2021-09-30 18:18:14
|
* @Date: 2021-09-30 18:18:14
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-24 10:02:46
|
* @LastEditTime: 2022-07-18 17:30:38
|
||||||
* @FilePath: /CasaOS/pkg/utils/jwt/jwt.go
|
* @FilePath: /CasaOS/pkg/utils/jwt/jwt.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -16,67 +16,26 @@ import (
|
|||||||
jwt "github.com/golang-jwt/jwt/v4"
|
jwt "github.com/golang-jwt/jwt/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// type Claims struct {
|
|
||||||
// UserName string `json:"username"`
|
|
||||||
// PassWord string `json:"password"`
|
|
||||||
// Id int `json:"id"`
|
|
||||||
// jwt.RegisteredClaims
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var jwtSecret []byte
|
|
||||||
|
|
||||||
// //创建token
|
|
||||||
// func GenerateToken(username, password string, id int, issuer string, t time.Duration) (string, error) {
|
|
||||||
// clims := Claims{
|
|
||||||
// username,
|
|
||||||
// password,
|
|
||||||
// id,
|
|
||||||
// jwt.RegisteredClaims{
|
|
||||||
// ExpiresAt: jwt.NewNumericDate(time.Now().Add(t)),
|
|
||||||
// IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
||||||
// NotBefore: jwt.NewNumericDate(time.Now()),
|
|
||||||
// Issuer: issuer,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
|
|
||||||
// tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, clims)
|
|
||||||
// token, err := tokenClaims.SignedString(jwtSecret)
|
|
||||||
// return token, err
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //解析token
|
|
||||||
// func ParseToken(token string) (*Claims, error) {
|
|
||||||
// tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
|
||||||
// return jwtSecret, nil
|
|
||||||
// })
|
|
||||||
// if tokenClaims != nil {
|
|
||||||
// if clims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
|
|
||||||
// return clims, nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
//****************** soon to be removed ******************
|
|
||||||
|
|
||||||
type Claims struct {
|
type Claims struct {
|
||||||
UserName string `json:"username"`
|
Username string `json:"username"`
|
||||||
PassWord string `json:"password"`
|
PassWord string `json:"password"`
|
||||||
jwt.StandardClaims
|
Id int `json:"id"`
|
||||||
|
jwt.RegisteredClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
var jwtSecret []byte
|
var jwtSecret []byte
|
||||||
|
|
||||||
//创建token
|
//创建token
|
||||||
func GenerateToken(username, password string) (string, error) {
|
func GenerateToken(username, password string, id int, issuer string, t time.Duration) (string, error) {
|
||||||
expireTime := time.Now().AddDate(999, 0, 0)
|
|
||||||
clims := Claims{
|
clims := Claims{
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
jwt.StandardClaims{
|
id,
|
||||||
ExpiresAt: expireTime.Unix(),
|
jwt.RegisteredClaims{
|
||||||
Issuer: "gin-blog",
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(t)),
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||||
|
Issuer: issuer,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,13 +46,17 @@ func GenerateToken(username, password string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//解析token
|
//解析token
|
||||||
func ParseToken(token string) (*Claims, error) {
|
func ParseToken(token string, valid bool) (*Claims, error) {
|
||||||
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
return jwtSecret, nil
|
return jwtSecret, nil
|
||||||
})
|
})
|
||||||
if tokenClaims != nil {
|
if tokenClaims != nil {
|
||||||
if clims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
|
if clims, ok := tokenClaims.Claims.(*Claims); ok {
|
||||||
|
if valid && tokenClaims.Valid {
|
||||||
return clims, nil
|
return clims, nil
|
||||||
|
} else if !valid {
|
||||||
|
return clims, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-06-17 14:01:25
|
* @Date: 2022-06-17 14:01:25
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-07-04 16:26:22
|
* @LastEditTime: 2022-07-29 16:22:25
|
||||||
* @FilePath: /CasaOS/pkg/utils/jwt/jwt_helper.go
|
* @FilePath: /CasaOS/pkg/utils/jwt/jwt_helper.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -11,65 +11,16 @@
|
|||||||
package jwt
|
package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
|
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func JWT() gin.HandlerFunc {
|
|
||||||
// return func(c *gin.Context) {
|
|
||||||
// var code int
|
|
||||||
// code = common_err.SUCCESS
|
|
||||||
// token := c.GetHeader("Authorization")
|
|
||||||
// if len(token) == 0 {
|
|
||||||
// token = c.Query("token")
|
|
||||||
// }
|
|
||||||
// if token == "" {
|
|
||||||
// code = common_err.INVALID_PARAMS
|
|
||||||
// }
|
|
||||||
|
|
||||||
// claims, err := ParseToken(token)
|
|
||||||
// //_, err := ParseToken(token)
|
|
||||||
// if err != nil {
|
|
||||||
// code = common_err.ERROR_AUTH_TOKEN
|
|
||||||
// } else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) {
|
|
||||||
// code = common_err.ERROR_AUTH_TOKEN
|
|
||||||
// }
|
|
||||||
// if code != common_err.SUCCESS {
|
|
||||||
// c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
|
||||||
// c.Abort()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// c.Request.Header.Add("user_id", strconv.Itoa(claims.Id))
|
|
||||||
// c.Next()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //get AccessToken
|
|
||||||
// func GetAccessToken(username, pwd string, id int) string {
|
|
||||||
// token, err := GenerateToken(username, pwd, id, "casaos", 3*time.Hour*time.Duration(1))
|
|
||||||
// if err == nil {
|
|
||||||
// return token
|
|
||||||
// } else {
|
|
||||||
// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetRefreshToken(username, pwd string, id int) string {
|
|
||||||
// token, err := GenerateToken(username, pwd, id, "fresh", 7*24*time.Hour*time.Duration(1))
|
|
||||||
// if err == nil {
|
|
||||||
// return token
|
|
||||||
// } else {
|
|
||||||
// loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//*************** soon to be removed *****************
|
|
||||||
|
|
||||||
func JWT() gin.HandlerFunc {
|
func JWT() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
var code int
|
var code int
|
||||||
@@ -82,32 +33,43 @@ func JWT() gin.HandlerFunc {
|
|||||||
code = common_err.INVALID_PARAMS
|
code = common_err.INVALID_PARAMS
|
||||||
}
|
}
|
||||||
|
|
||||||
//claims, err := ParseToken(token)
|
claims, err := ParseToken(token, false)
|
||||||
_, err := ParseToken(token)
|
|
||||||
|
//_, err := ParseToken(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
code = common_err.ERROR_AUTH_TOKEN
|
code = common_err.ERROR_AUTH_TOKEN
|
||||||
|
} else if (c.Request.URL.Path == "/v1/file" || c.Request.URL.Path == "/v1/image" || c.Request.URL.Path == "/v1/file/upload" || c.Request.URL.Path == "/v1/batch") && claims.VerifyIssuer("casaos", true) {
|
||||||
|
//Special treatment
|
||||||
|
} else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) {
|
||||||
|
code = common_err.ERROR_AUTH_TOKEN
|
||||||
}
|
}
|
||||||
//else if time.Now().Unix() > claims.ExpiresAt {
|
|
||||||
// code = oasis_err2.ERROR_AUTH_TOKEN
|
|
||||||
//}
|
|
||||||
|
|
||||||
if code != common_err.SUCCESS {
|
if code != common_err.SUCCESS {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.Request.Header.Add("user_id", strconv.Itoa(claims.Id))
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取token
|
//get AccessToken
|
||||||
func GetToken(username, pwd string) string {
|
func GetAccessToken(username, pwd string, id int) string {
|
||||||
token, err := GenerateToken(username, pwd)
|
token, err := GenerateToken(username, pwd, id, "casaos", 3*time.Hour*time.Duration(1))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return token
|
return token
|
||||||
} else {
|
} else {
|
||||||
//loger2.NewOLoger().Fatal(fmt.Sprintf("Get Token Fail: %V", err))
|
loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRefreshToken(username, pwd string, id int) string {
|
||||||
|
token, err := GenerateToken(username, pwd, id, "refresh", 7*24*time.Hour*time.Duration(1))
|
||||||
|
if err == nil {
|
||||||
|
return token
|
||||||
|
} else {
|
||||||
|
loger2.Error(fmt.Sprintf("Get Token Fail: %V", err))
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
pkg/utils/udev_helper.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-08-10 16:06:12
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-10 16:11:37
|
||||||
|
* @FilePath: /CasaOS/pkg/utils/udev_helper.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package utils
|
||||||
|
|
||||||
|
// func getOptionnalMatcher() (matcher netlink.Matcher, err error) {
|
||||||
|
// if filePath == nil || *filePath == "" {
|
||||||
|
// return nil, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// stream, err := ioutil.ReadFile(*filePath)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if stream == nil {
|
||||||
|
// return nil, fmt.Errorf("Empty, no rules provided in \"%s\", err: %w", *filePath, err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var rules netlink.RuleDefinitions
|
||||||
|
// if err := json.Unmarshal(stream, &rules); err != nil {
|
||||||
|
// return nil, fmt.Errorf("Wrong rule syntax, err: %w", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return &rules, nil
|
||||||
|
// }
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-29 14:29:34
|
* @LastEditTime: 2022-07-21 15:27:53
|
||||||
* @FilePath: /CasaOS/pkg/utils/version/version.go
|
* @FilePath: /CasaOS/pkg/utils/version/version.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -33,9 +33,6 @@ func IsNeedUpdate(version model.Version) (bool, model.Version) {
|
|||||||
for i := 0; i < len(v1); i++ {
|
for i := 0; i < len(v1); i++ {
|
||||||
a, _ := strconv.Atoi(v1[i])
|
a, _ := strconv.Atoi(v1[i])
|
||||||
b, _ := strconv.Atoi(v2[i])
|
b, _ := strconv.Atoi(v2[i])
|
||||||
if i == 0 && a > b {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if a > b {
|
if a > b {
|
||||||
return true, version
|
return true, version
|
||||||
}
|
}
|
||||||
|
|||||||
25
route/darwin.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//go:build darwin
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-08-12 14:22:28
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-12 18:41:14
|
||||||
|
* @FilePath: /CasaOS/route/darwin.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package route
|
||||||
|
|
||||||
|
func MonitoryUSB() {
|
||||||
|
|
||||||
|
}
|
||||||
|
func SendAllHardwareStatusBySocket() {
|
||||||
|
|
||||||
|
}
|
||||||
|
func SendUSBBySocket() {
|
||||||
|
|
||||||
|
}
|
||||||
197
route/init.go
@@ -1,166 +1,32 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model/system_app"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/samba"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitFunction() {
|
func InitFunction() {
|
||||||
go checkSystemApp()
|
|
||||||
ShellInit()
|
ShellInit()
|
||||||
CheckSerialDiskMount()
|
CheckSerialDiskMount()
|
||||||
|
|
||||||
CheckToken2_11()
|
CheckToken2_11()
|
||||||
ImportApplications()
|
ImportApplications()
|
||||||
|
// Soon to be removed
|
||||||
ChangeAPIUrl()
|
ChangeAPIUrl()
|
||||||
|
|
||||||
MoveUserToDB()
|
MoveUserToDB()
|
||||||
|
InitNetworkMount()
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncIsExistence = false
|
|
||||||
|
|
||||||
func installSyncthing(appId string) {
|
|
||||||
|
|
||||||
var appInfo model.ServerAppList
|
|
||||||
m := model.CustomizationPostData{}
|
|
||||||
var dockerImage string
|
|
||||||
var dockerImageVersion string
|
|
||||||
appInfo = service.MyService.Casa().GetServerAppInfo(appId, "system", "us_en")
|
|
||||||
dockerImage = appInfo.Image
|
|
||||||
dockerImageVersion = appInfo.ImageVersion
|
|
||||||
|
|
||||||
if len(appInfo.ImageVersion) == 0 {
|
|
||||||
dockerImageVersion = "latest"
|
|
||||||
}
|
|
||||||
|
|
||||||
if appInfo.NetworkModel != "host" {
|
|
||||||
for i := 0; i < len(appInfo.Ports); i++ {
|
|
||||||
if p, _ := strconv.Atoi(appInfo.Ports[i].ContainerPort); port.IsPortAvailable(p, appInfo.Ports[i].Protocol) {
|
|
||||||
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
|
||||||
} else {
|
|
||||||
if appInfo.Ports[i].Protocol == "tcp" {
|
|
||||||
if p, err := port.GetAvailablePort("tcp"); err == nil {
|
|
||||||
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
|
||||||
}
|
|
||||||
} else if appInfo.Ports[i].Protocol == "upd" {
|
|
||||||
if p, err := port.GetAvailablePort("udp"); err == nil {
|
|
||||||
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if appInfo.Ports[i].Type == 0 {
|
|
||||||
appInfo.PortMap = appInfo.Ports[i].CommendPort
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(appInfo.Devices); i++ {
|
|
||||||
if !file.CheckNotExist(appInfo.Devices[i].ContainerPath) {
|
|
||||||
appInfo.Devices[i].Path = appInfo.Devices[i].ContainerPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(appInfo.Tip) > 0 {
|
|
||||||
appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
|
|
||||||
}
|
|
||||||
|
|
||||||
appInfo.MaxMemory = service.MyService.System().GetMemInfo()["total"].(uint64) >> 20
|
|
||||||
|
|
||||||
id := uuid.NewV4().String()
|
|
||||||
|
|
||||||
// step:下载镜像
|
|
||||||
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, "", "")
|
|
||||||
if err != nil {
|
|
||||||
//pull image error
|
|
||||||
fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.CpuShares = 50
|
|
||||||
m.Envs = appInfo.Envs
|
|
||||||
m.Memory = int64(appInfo.MaxMemory)
|
|
||||||
m.Origin = "system"
|
|
||||||
m.PortMap = appInfo.PortMap
|
|
||||||
m.Ports = appInfo.Ports
|
|
||||||
m.Restart = "always"
|
|
||||||
m.Volumes = appInfo.Volumes
|
|
||||||
m.NetworkModel = appInfo.NetworkModel
|
|
||||||
m.Label = id
|
|
||||||
m.CustomId = id
|
|
||||||
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("container create error", err)
|
|
||||||
// create container error
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//step:start container
|
|
||||||
err = service.MyService.Docker().DockerContainerStart(containerId)
|
|
||||||
if err != nil {
|
|
||||||
//start container error
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
checkSystemApp()
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the system application is installed
|
|
||||||
func checkSystemApp() {
|
|
||||||
list := service.MyService.App().GetSystemAppList()
|
|
||||||
for _, v := range list {
|
|
||||||
info, err := service.MyService.Docker().DockerContainerInfo(v.ID)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Contains(info.Config.Image, "linuxserver/syncthing") {
|
|
||||||
if v.State != "running" {
|
|
||||||
//step:start container
|
|
||||||
service.MyService.Docker().DockerContainerStart(v.ID)
|
|
||||||
}
|
|
||||||
syncIsExistence = true
|
|
||||||
if config.SystemConfigInfo.SyncPort != v.Labels["web"] {
|
|
||||||
config.SystemConfigInfo.SyncPort = v.Labels["web"]
|
|
||||||
}
|
|
||||||
|
|
||||||
path := ""
|
|
||||||
for _, i := range info.Mounts {
|
|
||||||
if i.Destination == "/config" {
|
|
||||||
path = i.Source
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content := file.ReadFullFile(filepath.Join(path, "config.xml"))
|
|
||||||
syncConfig := &system_app.SyncConfig{}
|
|
||||||
xml.Unmarshal(content, &syncConfig)
|
|
||||||
config.SystemConfigInfo.SyncKey = syncConfig.Key
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !syncIsExistence {
|
|
||||||
installSyncthing("74")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func CheckSerialDiskMount() {
|
func CheckSerialDiskMount() {
|
||||||
// check mount point
|
// check mount point
|
||||||
dbList := service.MyService.Disk().GetSerialAll()
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
@@ -175,7 +41,7 @@ func CheckSerialDiskMount() {
|
|||||||
command.ExecEnabledSMART(v.Path)
|
command.ExecEnabledSMART(v.Path)
|
||||||
if v.Children != nil {
|
if v.Children != nil {
|
||||||
for _, h := range v.Children {
|
for _, h := range v.Children {
|
||||||
if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
|
//if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
|
||||||
if m, ok := mountPoint[h.UUID]; ok {
|
if m, ok := mountPoint[h.UUID]; ok {
|
||||||
//mount point check
|
//mount point check
|
||||||
volume := m
|
volume := m
|
||||||
@@ -193,7 +59,7 @@ func CheckSerialDiskMount() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,31 +82,11 @@ func CheckToken2_11() {
|
|||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
sysType := runtime.GOOS
|
|
||||||
if len(config.FileSettingInfo.DownloadDir) == 0 {
|
|
||||||
downloadPath := "/DATA/Downloads"
|
|
||||||
if sysType == "windows" {
|
|
||||||
downloadPath = "C:\\CasaOS\\DATA\\Downloads"
|
|
||||||
}
|
|
||||||
if sysType == "darwin" {
|
|
||||||
downloadPath = "./CasaOS/DATA/Downloads"
|
|
||||||
}
|
|
||||||
config.Cfg.Section("file").Key("DownloadDir").SetValue(downloadPath)
|
|
||||||
config.FileSettingInfo.DownloadDir = downloadPath
|
|
||||||
file.IsNotExistMkDir(config.FileSettingInfo.DownloadDir)
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(config.UserInfo.Description) == 0 {
|
if len(config.UserInfo.Description) == 0 {
|
||||||
config.Cfg.Section("user").Key("Description").SetValue("nothing")
|
config.Cfg.Section("user").Key("Description").SetValue("nothing")
|
||||||
config.UserInfo.Description = "nothing"
|
config.UserInfo.Description = "nothing"
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
}
|
}
|
||||||
if len(config.ServerInfo.Handshake) == 0 {
|
|
||||||
config.Cfg.Section("server").Key("Handshake").SetValue("socket.casaos.io")
|
|
||||||
config.ServerInfo.Handshake = "socket.casaos.io"
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") {
|
if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") {
|
||||||
service.MyService.System().UpdateUSBAutoMount("False")
|
service.MyService.System().UpdateUSBAutoMount("False")
|
||||||
@@ -279,9 +125,9 @@ func MoveUserToDB() {
|
|||||||
|
|
||||||
if len(config.UserInfo.UserName) > 0 && service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 {
|
if len(config.UserInfo.UserName) > 0 && service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 {
|
||||||
user := model2.UserDBModel{}
|
user := model2.UserDBModel{}
|
||||||
user.UserName = config.UserInfo.UserName
|
user.Username = config.UserInfo.UserName
|
||||||
user.Email = config.UserInfo.Email
|
user.Email = config.UserInfo.Email
|
||||||
user.NickName = config.UserInfo.NickName
|
user.Nickname = config.UserInfo.NickName
|
||||||
user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD)
|
user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD)
|
||||||
user.Role = "admin"
|
user.Role = "admin"
|
||||||
user = service.MyService.User().CreateUser(user)
|
user = service.MyService.User().CreateUser(user)
|
||||||
@@ -293,3 +139,32 @@ func MoveUserToDB() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitNetworkMount() {
|
||||||
|
connections := service.MyService.Connections().GetConnectionsList()
|
||||||
|
for _, v := range connections {
|
||||||
|
connection := service.MyService.Connections().GetConnectionByID(fmt.Sprint(v.ID))
|
||||||
|
directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
|
||||||
|
if err != nil {
|
||||||
|
service.MyService.Connections().DeleteConnection(fmt.Sprint(connection.ID))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
baseHostPath := "/mnt/" + connection.Host
|
||||||
|
|
||||||
|
mountPointList := service.MyService.System().GetDirPath(baseHostPath)
|
||||||
|
for _, v := range mountPointList {
|
||||||
|
service.MyService.Connections().UnmountSmaba(v.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.RemoveAll(baseHostPath)
|
||||||
|
|
||||||
|
file.IsNotExistMkDir(baseHostPath)
|
||||||
|
for _, v := range directories {
|
||||||
|
mountPoint := baseHostPath + "/" + v
|
||||||
|
file.IsNotExistMkDir(mountPoint)
|
||||||
|
service.MyService.Connections().MountSmaba(connection.Username, connection.Host, v, connection.Port, mountPoint, connection.Password)
|
||||||
|
}
|
||||||
|
connection.Directories = strings.Join(directories, ",")
|
||||||
|
service.MyService.Connections().UpdateConnection(&connection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
|
//go:build !darwin
|
||||||
|
// +build !darwin
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-07-01 15:11:36
|
* @Date: 2022-07-01 15:11:36
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-07-01 15:16:00
|
* @LastEditTime: 2022-08-15 11:50:04
|
||||||
* @FilePath: /CasaOS/route/periodical.go
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2022-05-27 15:55:36
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-06-29 16:47:19
|
|
||||||
* @FilePath: /CasaOS/route/periodical.go
|
* @FilePath: /CasaOS/route/periodical.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -21,14 +14,20 @@
|
|||||||
package route
|
package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
"github.com/pilebones/go-udev/netlink"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SendNetINfoBySocket() {
|
func SendNetINfoBySocket() {
|
||||||
@@ -139,28 +138,24 @@ func SendUSBBySocket() {
|
|||||||
usb := []model.DriveUSB{}
|
usb := []model.DriveUSB{}
|
||||||
for _, v := range usbList {
|
for _, v := range usbList {
|
||||||
if v.Tran == "usb" {
|
if v.Tran == "usb" {
|
||||||
|
isMount := false
|
||||||
temp := model.DriveUSB{}
|
temp := model.DriveUSB{}
|
||||||
temp.Model = v.Model
|
temp.Model = v.Model
|
||||||
temp.Name = v.Name
|
temp.Name = v.Name
|
||||||
temp.Size = v.Size
|
temp.Size = v.Size
|
||||||
mountTemp := true
|
|
||||||
if len(v.Children) == 0 {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
|
||||||
for _, child := range v.Children {
|
for _, child := range v.Children {
|
||||||
if len(child.MountPoint) > 0 {
|
if len(child.MountPoint) > 0 {
|
||||||
|
isMount = true
|
||||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
temp.Avail += avail
|
temp.Avail += avail
|
||||||
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
|
||||||
temp.Used += used
|
|
||||||
} else {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
temp.Mount = mountTemp
|
if isMount {
|
||||||
usb = append(usb, temp)
|
usb = append(usb, temp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
service.MyService.Notify().SendUSBInfoBySocket(usb)
|
service.MyService.Notify().SendUSBInfoBySocket(usb)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,30 +251,61 @@ func SendAllHardwareStatusBySocket() {
|
|||||||
usb := []model.DriveUSB{}
|
usb := []model.DriveUSB{}
|
||||||
for _, v := range usbList {
|
for _, v := range usbList {
|
||||||
if v.Tran == "usb" {
|
if v.Tran == "usb" {
|
||||||
|
isMount := false
|
||||||
temp := model.DriveUSB{}
|
temp := model.DriveUSB{}
|
||||||
temp.Model = v.Model
|
temp.Model = v.Model
|
||||||
temp.Name = v.Name
|
temp.Name = v.Name
|
||||||
temp.Size = v.Size
|
temp.Size = v.Size
|
||||||
mountTemp := true
|
|
||||||
if len(v.Children) == 0 {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
|
||||||
for _, child := range v.Children {
|
for _, child := range v.Children {
|
||||||
if len(child.MountPoint) > 0 {
|
if len(child.MountPoint) > 0 {
|
||||||
|
isMount = true
|
||||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
temp.Avail += avail
|
temp.Avail += avail
|
||||||
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
|
||||||
temp.Used += used
|
|
||||||
} else {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
temp.Mount = mountTemp
|
if isMount {
|
||||||
usb = append(usb, temp)
|
usb = append(usb, temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memInfo := service.MyService.System().GetMemInfo()
|
memInfo := service.MyService.System().GetMemInfo()
|
||||||
|
|
||||||
service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memInfo, cpuData, newNet)
|
service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memInfo, cpuData, newNet)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func MonitoryUSB() {
|
||||||
|
var matcher netlink.Matcher
|
||||||
|
|
||||||
|
conn := new(netlink.UEventConn)
|
||||||
|
if err := conn.Connect(netlink.UdevEvent); err != nil {
|
||||||
|
loger.Error("udev err", zap.Any("Unable to connect to Netlink Kobject UEvent socket", err))
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
queue := make(chan netlink.UEvent)
|
||||||
|
errors := make(chan error)
|
||||||
|
quit := conn.Monitor(queue, errors, matcher)
|
||||||
|
|
||||||
|
signals := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
go func() {
|
||||||
|
<-signals
|
||||||
|
close(quit)
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case uevent := <-queue:
|
||||||
|
if uevent.Env["DEVTYPE"] == "disk" {
|
||||||
|
time.Sleep(time.Microsecond * 500)
|
||||||
|
SendUSBBySocket()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case err := <-errors:
|
||||||
|
loger.Error("udev err", zap.Any("err", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
330
route/route.go
@@ -23,6 +23,7 @@ func InitRouter() *gin.Engine {
|
|||||||
r.Use(middleware.WriteLog())
|
r.Use(middleware.WriteLog())
|
||||||
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||||
gin.SetMode(config.ServerInfo.RunMode)
|
gin.SetMode(config.ServerInfo.RunMode)
|
||||||
|
|
||||||
r.StaticFS("/ui", http.FS(web.Static))
|
r.StaticFS("/ui", http.FS(web.Static))
|
||||||
r.GET("/", WebUIHome)
|
r.GET("/", WebUIHome)
|
||||||
// r.StaticFS("/assets", http.Dir("./static/assets"))
|
// r.StaticFS("/assets", http.Dir("./static/assets"))
|
||||||
@@ -31,199 +32,216 @@ func InitRouter() *gin.Engine {
|
|||||||
// c.Redirect(http.StatusMovedPermanently, "ui/")
|
// c.Redirect(http.StatusMovedPermanently, "ui/")
|
||||||
//})
|
//})
|
||||||
|
|
||||||
r.POST("/v1/user/register/:key", v1.PostUserRegister)
|
r.POST("/v1/users/register", v1.PostUserRegister)
|
||||||
r.POST("/v1/user/login", v1.PostUserLogin) //
|
r.POST("/v1/users/login", v1.PostUserLogin)
|
||||||
r.GET("/v1/user/all/name", v1.GetUserAllUserName)
|
r.GET("/v1/users/name", v1.GetUserAllUsername) //all/name
|
||||||
|
r.POST("/v1/users/refresh", v1.PostUserRefreshToken)
|
||||||
|
// No short-term modifications
|
||||||
|
r.GET("/v1/users/image", v1.GetUserImage)
|
||||||
|
|
||||||
r.GET("/v1/sys/init/check", v1.GetSystemInitCheck)
|
r.GET("/v1/users/status", v1.GetUserStatus) //init/check
|
||||||
r.GET("/v1/guide/check", v1.GetGuideCheck)
|
//r.GET("/v1/guide/check", v1.GetGuideCheck) // /v1/sys/guide_check
|
||||||
r.GET("/v1/debug", v1.GetSystemConfigDebug)
|
r.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug
|
||||||
r.POST("/v1/user/setusernamepwd", v1.Set_Name_Pwd)
|
|
||||||
r.GET("/v1/user/info/:id", v1.GetUserInfo)
|
r.GET("/v1/sys/socket-port", v1.GetSystemSocketPort) //sys/socket_port
|
||||||
r.GET("/v1/user/avatar/:id", v1.GetUserAvatar)
|
r.GET("/v1/sys/version/check", v1.GetSystemCheckVersion)
|
||||||
r.GET("/v1/user/image", v1.GetUserImage)
|
|
||||||
|
|
||||||
//get user info
|
|
||||||
r.GET("/v1/person/shareid", v1.GetPersonShareId)
|
|
||||||
r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort)
|
|
||||||
//r.POST("/v1/user/refresh/token", v1.PostUserRefreshToken)
|
|
||||||
v1Group := r.Group("/v1")
|
v1Group := r.Group("/v1")
|
||||||
|
|
||||||
v1Group.Use(jwt2.JWT())
|
v1Group.Use(jwt2.JWT())
|
||||||
{
|
{
|
||||||
v1UserGroup := v1Group.Group("/user")
|
v1UsersGroup := v1Group.Group("/users")
|
||||||
v1UserGroup.Use()
|
v1UsersGroup.Use()
|
||||||
{
|
{
|
||||||
|
v1UsersGroup.GET("/current", v1.GetUserInfo)
|
||||||
|
v1UsersGroup.PUT("/current", v1.PutUserInfo)
|
||||||
|
v1UsersGroup.PUT("/current/password", v1.PutUserPassword)
|
||||||
|
|
||||||
//****************** New version needs to be modified start ******************
|
v1UsersGroup.GET("/current/custom/:key", v1.GetUserCustomConf)
|
||||||
//chang user name
|
v1UsersGroup.POST("/current/custom/:key", v1.PostUserCustomConf)
|
||||||
v1UserGroup.PUT("/username", v1.PutUserName)
|
v1UsersGroup.DELETE("/current/custom/:key", v1.DeleteUserCustomConf)
|
||||||
v1UserGroup.PUT("/password", v1.PutUserPwd)
|
|
||||||
v1UserGroup.PUT("/nick", v1.PutUserNick)
|
|
||||||
v1UserGroup.PUT("/desc", v1.PutUserDesc)
|
|
||||||
v1UserGroup.GET("/info", v1.GetUserInfoByUserName)
|
|
||||||
v1UserGroup.GET("/custom/:id/:key", v1.GetUserCustomConf)
|
|
||||||
v1UserGroup.POST("/custom/:id/:key", v1.PostUserCustomConf)
|
|
||||||
v1UserGroup.DELETE("/custom/:id/:key", v1.DeleteUserCustomConf)
|
|
||||||
v1UserGroup.POST("/upload/image/:id/:key", v1.PostUserUploadImage)
|
|
||||||
v1UserGroup.POST("/file/image/:id/:key", v1.PostUserFileImage)
|
|
||||||
v1UserGroup.DELETE("/image/:id", v1.DeleteUserImage)
|
|
||||||
//****************** New version needs to be modified end ******************
|
|
||||||
|
|
||||||
//****************** soon to be removed start ******************
|
v1UsersGroup.POST("/current/image/:key", v1.PostUserUploadImage)
|
||||||
v1UserGroup.POST("/person/info", v1.PostUserPersonInfo)
|
v1UsersGroup.PUT("/current/image/:key", v1.PutUserImage)
|
||||||
v1UserGroup.GET("/shareid", v1.GetUserShareID)
|
//v1UserGroup.POST("/file/image/:key", v1.PostUserFileImage)
|
||||||
//****************** soon to be removed end ******************
|
v1UsersGroup.DELETE("/current/image", v1.DeleteUserImage)
|
||||||
|
|
||||||
//v1UserGroup.GET("/info", v1.GetUserInfo)
|
//v1UserGroup.PUT("/avatar", v1.PutUserAvatar)
|
||||||
|
//v1UserGroup.GET("/avatar", v1.GetUserAvatar)
|
||||||
|
v1UsersGroup.DELETE("/:id", v1.DeleteUser)
|
||||||
|
v1UsersGroup.GET("/:username", v1.GetUserInfoByUsername)
|
||||||
|
v1UsersGroup.DELETE("", v1.DeleteUserAll)
|
||||||
|
}
|
||||||
|
|
||||||
v1UserGroup.PUT("/avatar", v1.PutUserAvatar)
|
v1AppsGroup := v1Group.Group("/apps")
|
||||||
v1UserGroup.GET("/avatar", v1.GetUserAvatar)
|
v1AppsGroup.Use()
|
||||||
v1UserGroup.DELETE("/delete/:id", v1.DeleteUser)
|
{
|
||||||
|
v1AppsGroup.GET("", v1.AppList) //list
|
||||||
|
v1AppsGroup.GET("/:id", v1.AppInfo)
|
||||||
|
}
|
||||||
|
v1ContainerGroup := v1Group.Group("/container")
|
||||||
|
v1ContainerGroup.Use()
|
||||||
|
{
|
||||||
|
v1ContainerGroup.GET("", v1.MyAppList) ///my/list
|
||||||
|
v1ContainerGroup.GET("/usage", v1.AppUsageList)
|
||||||
|
v1ContainerGroup.GET("/:id", v1.ContainerUpdateInfo) ///update/:id/info
|
||||||
|
v1ContainerGroup.GET("/:id/logs", v1.ContainerLog) // /app/logs/:id
|
||||||
|
v1ContainerGroup.GET("/networks", v1.GetDockerNetworks) //app/install/config
|
||||||
|
|
||||||
|
v1ContainerGroup.GET("/:id/state", v1.GetContainerState) //app/state/:id ?state=install_progress
|
||||||
|
// there are problems, temporarily do not deal with
|
||||||
|
v1ContainerGroup.GET("/:id/terminal", v1.DockerTerminal) //app/terminal/:id
|
||||||
|
v1ContainerGroup.POST("", v1.InstallApp) //app/install
|
||||||
|
//v1ContainerGroup.GET("/:id", v1.ContainerInfo) // /app/info/:id
|
||||||
|
|
||||||
|
v1ContainerGroup.PUT("/:id", v1.UpdateSetting) ///update/:id/setting
|
||||||
|
|
||||||
|
v1ContainerGroup.PUT("/:id/state", v1.ChangAppState) // /app/state/:id
|
||||||
|
v1ContainerGroup.DELETE("/:id", v1.UnInstallApp) //app/uninstall/:id
|
||||||
|
//Not used
|
||||||
|
v1ContainerGroup.PUT("/:id/latest", v1.PutAppUpdate)
|
||||||
|
//Not used
|
||||||
|
v1ContainerGroup.POST("/share", v1.ShareAppFile)
|
||||||
|
|
||||||
}
|
}
|
||||||
v1AppGroup := v1Group.Group("/app")
|
v1AppCategoriesGroup := v1Group.Group("/app-categories")
|
||||||
v1AppGroup.Use()
|
v1AppCategoriesGroup.Use()
|
||||||
{
|
{
|
||||||
//获取我的已安装的列表
|
v1AppCategoriesGroup.GET("", v1.CategoryList)
|
||||||
v1AppGroup.GET("/my/list", v1.MyAppList)
|
|
||||||
//
|
|
||||||
v1AppGroup.GET("/usage", v1.AppUsageList)
|
|
||||||
//app详情
|
|
||||||
v1AppGroup.GET("/appinfo/:id", v1.AppInfo)
|
|
||||||
//获取未安装的列表
|
|
||||||
v1AppGroup.GET("/list", v1.AppList)
|
|
||||||
//获取端口
|
|
||||||
v1AppGroup.GET("/port", v1.GetPort)
|
|
||||||
//检查端口
|
|
||||||
v1AppGroup.GET("/check/:port", v1.PortCheck)
|
|
||||||
|
|
||||||
v1AppGroup.GET("/category", v1.CategoryList)
|
|
||||||
|
|
||||||
v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
|
|
||||||
//app容器详情
|
|
||||||
v1AppGroup.GET("/info/:id", v1.ContainerInfo)
|
|
||||||
//app容器日志
|
|
||||||
v1AppGroup.GET("/logs/:id", v1.ContainerLog)
|
|
||||||
//暂停或启动容器
|
|
||||||
v1AppGroup.PUT("/state/:id", v1.ChangAppState)
|
|
||||||
//安装app
|
|
||||||
v1AppGroup.POST("/install", v1.InstallApp)
|
|
||||||
//卸载app
|
|
||||||
v1AppGroup.DELETE("/uninstall/:id", v1.UnInstallApp)
|
|
||||||
//获取进度
|
|
||||||
v1AppGroup.GET("/state/:id", v1.GetContainerState)
|
|
||||||
//更新容器配置
|
|
||||||
v1AppGroup.PUT("/update/:id/setting", v1.UpdateSetting)
|
|
||||||
//获取可能新数据
|
|
||||||
v1AppGroup.GET("/update/:id/info", v1.ContainerUpdateInfo)
|
|
||||||
v1AppGroup.GET("/rely/:id/info", v1.ContainerRelyInfo)
|
|
||||||
v1AppGroup.GET("/install/config", v1.GetDockerInstallConfig)
|
|
||||||
v1AppGroup.PUT("/update/:id", v1.PutAppUpdate)
|
|
||||||
v1AppGroup.POST("/share", v1.ShareAppFile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v1SysGroup := v1Group.Group("/sys")
|
v1SysGroup := v1Group.Group("/sys")
|
||||||
v1SysGroup.Use()
|
v1SysGroup.Use()
|
||||||
{
|
{
|
||||||
v1SysGroup.GET("/version/check", v1.GetSystemCheckVersion)
|
v1SysGroup.GET("/version", v1.GetSystemCheckVersion) //version/check
|
||||||
v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo)
|
|
||||||
v1SysGroup.POST("/update", v1.SystemUpdate)
|
v1SysGroup.POST("/update", v1.SystemUpdate)
|
||||||
|
|
||||||
|
v1SysGroup.GET("/hardware", v1.GetSystemHardwareInfo) //hardware/info
|
||||||
|
|
||||||
v1SysGroup.GET("/wsssh", v1.WsSsh)
|
v1SysGroup.GET("/wsssh", v1.WsSsh)
|
||||||
v1SysGroup.GET("/config", v1.GetSystemConfig)
|
v1SysGroup.POST("/ssh-login", v1.PostSshLogin)
|
||||||
|
//v1SysGroup.GET("/config", v1.GetSystemConfig) //delete
|
||||||
//v1SysGroup.POST("/config", v1.PostSetSystemConfig)
|
//v1SysGroup.POST("/config", v1.PostSetSystemConfig)
|
||||||
v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
|
v1SysGroup.GET("/logs", v1.GetCasaOSErrorLogs) //error/logs
|
||||||
v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)
|
//v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)//delete
|
||||||
v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)
|
//v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)//delete
|
||||||
|
|
||||||
|
v1SysGroup.POST("/stop", v1.PostKillCasaOS)
|
||||||
|
|
||||||
|
v1SysGroup.GET("/utilization", v1.GetSystemUtilization)
|
||||||
|
// v1SysGroup.GET("/cpu", v1.GetSystemCupInfo)
|
||||||
|
// v1SysGroup.GET("/mem", v1.GetSystemMemInfo)
|
||||||
|
// v1SysGroup.GET("/disk", v1.GetSystemDiskInfo)
|
||||||
|
// v1SysGroup.GET("/network", v1.GetSystemNetInfo)
|
||||||
|
|
||||||
|
v1SysGroup.PUT("/usb-auto-mount", v1.PutSystemUSBAutoMount) ///sys/usb/:status
|
||||||
|
v1SysGroup.GET("/usb-auto-mount", v1.GetSystemUSBAutoMount) ///sys/usb/status
|
||||||
|
|
||||||
|
v1SysGroup.GET("/server-info", nil)
|
||||||
|
v1SysGroup.PUT("/server-info", nil)
|
||||||
|
v1SysGroup.GET("/apps-state", v1.GetSystemAppsStatus)
|
||||||
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
||||||
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||||
v1SysGroup.POST("/stop", v1.PostKillCasaOS)
|
|
||||||
v1SysGroup.GET("/utilization", v1.GetSystemUtilization)
|
|
||||||
v1SysGroup.PUT("/usb/:status", v1.PutSystemUSBAutoMount)
|
|
||||||
v1SysGroup.GET("/usb/status", v1.GetSystemUSBAutoMount)
|
|
||||||
v1SysGroup.GET("/cpu", v1.GetSystemCupInfo)
|
|
||||||
v1SysGroup.GET("/mem", v1.GetSystemMemInfo)
|
|
||||||
v1SysGroup.GET("/disk", v1.GetSystemDiskInfo)
|
|
||||||
v1SysGroup.GET("/network", v1.GetSystemNetInfo)
|
|
||||||
}
|
}
|
||||||
|
v1PortGroup := v1Group.Group("/port")
|
||||||
|
v1PortGroup.Use()
|
||||||
|
{
|
||||||
|
v1PortGroup.GET("/", v1.GetPort) //app/port
|
||||||
|
v1PortGroup.GET("/state/:port", v1.PortCheck) //app/check/:port
|
||||||
|
}
|
||||||
|
|
||||||
v1FileGroup := v1Group.Group("/file")
|
v1FileGroup := v1Group.Group("/file")
|
||||||
v1FileGroup.Use()
|
v1FileGroup.Use()
|
||||||
{
|
{
|
||||||
v1FileGroup.PUT("/rename", v1.RenamePath)
|
v1FileGroup.GET("", v1.GetDownloadSingleFile) //download/:path
|
||||||
v1FileGroup.GET("/read", v1.GetFilerContent)
|
v1FileGroup.POST("", v1.PostCreateFile)
|
||||||
|
v1FileGroup.PUT("", v1.PutFileContent)
|
||||||
|
v1FileGroup.PUT("/name", v1.RenamePath)
|
||||||
|
//file/rename
|
||||||
|
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.GET("/upload", v1.GetFileUpload)
|
v1FileGroup.GET("/upload", v1.GetFileUpload)
|
||||||
v1FileGroup.GET("/dirpath", v1.DirPath)
|
|
||||||
//create folder
|
|
||||||
v1FileGroup.POST("/mkdir", v1.MkdirAll)
|
|
||||||
v1FileGroup.POST("/create", v1.PostCreateFile)
|
|
||||||
|
|
||||||
v1FileGroup.GET("/download", v1.GetDownloadFile)
|
|
||||||
v1FileGroup.GET("/download/*path", v1.GetDownloadSingleFile)
|
|
||||||
v1FileGroup.POST("/operate", v1.PostOperateFileOrDir)
|
|
||||||
v1FileGroup.DELETE("/delete", v1.DeleteFile)
|
|
||||||
v1FileGroup.PUT("/update", v1.PutFileContent)
|
|
||||||
v1FileGroup.GET("/image", v1.GetFileImage)
|
|
||||||
v1FileGroup.DELETE("/operate/:id", v1.DeleteOperateFileOrDir)
|
|
||||||
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
||||||
}
|
}
|
||||||
v1DiskGroup := v1Group.Group("/disk")
|
v1FolderGroup := v1Group.Group("/folder")
|
||||||
v1DiskGroup.Use()
|
v1FolderGroup.Use()
|
||||||
{
|
{
|
||||||
v1DiskGroup.GET("/check", v1.GetDiskCheck)
|
v1FolderGroup.PUT("/name", v1.RenamePath)
|
||||||
|
v1FolderGroup.GET("", v1.DirPath) ///file/dirpath
|
||||||
v1DiskGroup.GET("/list", v1.GetDiskList)
|
v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir
|
||||||
|
|
||||||
//获取磁盘详情
|
|
||||||
v1DiskGroup.GET("/info", v1.GetDiskInfo)
|
|
||||||
|
|
||||||
//format storage
|
|
||||||
v1DiskGroup.POST("/format", v1.PostDiskFormat)
|
|
||||||
|
|
||||||
// add storage
|
|
||||||
v1DiskGroup.POST("/storage", v1.PostDiskAddPartition)
|
|
||||||
|
|
||||||
//mount SATA disk
|
|
||||||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
|
||||||
|
|
||||||
//umount sata disk
|
|
||||||
v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
|
||||||
|
|
||||||
//获取可以格式化的内容
|
|
||||||
v1DiskGroup.GET("/type", v1.FormatDiskType)
|
|
||||||
|
|
||||||
//删除分区
|
|
||||||
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
|
|
||||||
v1DiskGroup.GET("/usb", v1.GetUSBList)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
v1PersonGroup := v1Group.Group("/person")
|
v1BatchGroup := v1Group.Group("/batch")
|
||||||
v1PersonGroup.Use()
|
v1BatchGroup.Use()
|
||||||
{
|
{
|
||||||
v1PersonGroup.GET("/detection", v1.GetPersonDetection)
|
|
||||||
v1PersonGroup.GET("/users", v1.GetPersonFriend)
|
|
||||||
v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend)
|
|
||||||
v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend)
|
|
||||||
v1PersonGroup.GET("/directory", v1.GetPersonDirectory)
|
|
||||||
v1PersonGroup.GET("/file", v1.GetPersonFile)
|
|
||||||
v1PersonGroup.GET("/refile/:uuid", v1.GetPersonReFile)
|
|
||||||
v1PersonGroup.PUT("/remarks/:shareid", v1.PutPersonRemarks)
|
|
||||||
v1PersonGroup.GET("/list", v1.GetPersonDownloadList)
|
|
||||||
v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersonDownloadFile)
|
|
||||||
|
|
||||||
v1PersonGroup.POST("/share", v1.PostPersonShare)
|
|
||||||
v1PersonGroup.POST("/file/:shareid", v1.PostPersonFile)
|
|
||||||
v1PersonGroup.GET("/share", v1.GetPersonShare)
|
|
||||||
v1PersonGroup.POST("/down/dir", v1.PostPersonDownDir)
|
|
||||||
v1PersonGroup.GET("/down/dir", v1.GetPersonDownDir)
|
|
||||||
v1PersonGroup.PUT("/block/:shareid", v1.PutPersonBlock)
|
|
||||||
v1PersonGroup.GET("/public", v1.GetPersonPublic)
|
|
||||||
v1PersonGroup.PUT("/friend/:shareid", v1.PutPersonAgreeFriend)
|
|
||||||
v1PersonGroup.PUT("/write/:shareid", v1.PutPersonWrite)
|
|
||||||
v1PersonGroup.GET("/image/thumbnail/:shareid", v1.GetPersonImageThumbnail)
|
|
||||||
|
|
||||||
|
v1BatchGroup.DELETE("", v1.DeleteFile) //file/delete
|
||||||
|
v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir)
|
||||||
|
v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) //file/operate
|
||||||
|
v1BatchGroup.GET("", v1.GetDownloadFile)
|
||||||
|
}
|
||||||
|
v1ImageGroup := v1Group.Group("/image")
|
||||||
|
v1ImageGroup.Use()
|
||||||
|
{
|
||||||
|
v1ImageGroup.GET("", v1.GetFileImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
v1DisksGroup := v1Group.Group("/disks")
|
||||||
|
v1DisksGroup.Use()
|
||||||
|
{
|
||||||
|
//v1DiskGroup.GET("/check", v1.GetDiskCheck) //delete
|
||||||
|
//v1DisksGroup.GET("", v1.GetDiskInfo)
|
||||||
|
|
||||||
|
//v1DisksGroup.POST("", v1.PostMountDisk)
|
||||||
|
v1DisksGroup.GET("", v1.GetDiskList)
|
||||||
|
v1DisksGroup.GET("/usb", v1.GetDisksUSBList)
|
||||||
|
v1DisksGroup.DELETE("/usb", v1.DeleteDiskUSB)
|
||||||
|
v1DisksGroup.DELETE("", v1.DeleteDisksUmount)
|
||||||
|
// //format storage
|
||||||
|
// v1DiskGroup.POST("/format", v1.PostDiskFormat)
|
||||||
|
|
||||||
|
// //mount SATA disk
|
||||||
|
// v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||||
|
|
||||||
|
// //umount sata disk
|
||||||
|
// v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
||||||
|
|
||||||
|
//v1DiskGroup.GET("/type", v1.FormatDiskType)//delete
|
||||||
|
|
||||||
|
v1DisksGroup.DELETE("/part", v1.RemovePartition) //disk/delpart
|
||||||
|
}
|
||||||
|
|
||||||
|
v1StorageGroup := v1Group.Group("/storage")
|
||||||
|
v1StorageGroup.Use()
|
||||||
|
{
|
||||||
|
v1StorageGroup.POST("", v1.PostDiskAddPartition)
|
||||||
|
|
||||||
|
v1StorageGroup.PUT("", v1.PostDiskFormat)
|
||||||
|
|
||||||
|
v1StorageGroup.DELETE("", v1.PostDiskUmount)
|
||||||
|
v1StorageGroup.GET("", v1.GetStorageList)
|
||||||
|
}
|
||||||
|
v1SambaGroup := v1Group.Group("/samba")
|
||||||
|
v1SambaGroup.Use()
|
||||||
|
{
|
||||||
|
v1ConnectionsGroup := v1SambaGroup.Group("/connections")
|
||||||
|
v1ConnectionsGroup.Use()
|
||||||
|
{
|
||||||
|
v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList)
|
||||||
|
v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate)
|
||||||
|
v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections)
|
||||||
|
}
|
||||||
|
v1SharesGroup := v1SambaGroup.Group("/shares")
|
||||||
|
v1SharesGroup.Use()
|
||||||
|
{
|
||||||
|
v1SharesGroup.GET("", v1.GetSambaSharesList)
|
||||||
|
v1SharesGroup.POST("", v1.PostSambaSharesCreate)
|
||||||
|
v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares)
|
||||||
|
v1SharesGroup.GET("/status", v1.GetSambaStatus)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v1Group.GET("/sync/config", v1.GetSyncConfig)
|
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
@@ -37,10 +36,14 @@ func AppList(c *gin.Context) {
|
|||||||
categoryId := c.DefaultQuery("category_id", "0")
|
categoryId := c.DefaultQuery("category_id", "0")
|
||||||
key := c.DefaultQuery("key", "")
|
key := c.DefaultQuery("key", "")
|
||||||
if len(index) == 0 || len(size) == 0 || len(t) == 0 || len(categoryId) == 0 {
|
if len(index) == 0 || len(size) == 0 || len(t) == 0 || len(categoryId) == 0 {
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
collection, err := service.MyService.Casa().GetServerList(index, size, t, categoryId, key)
|
||||||
|
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
|
||||||
}
|
}
|
||||||
collection := service.MyService.Casa().GetServerList(index, size, t, categoryId, key)
|
|
||||||
// for i := 0; i < len(recommend); i++ {
|
// for i := 0; i < len(recommend); i++ {
|
||||||
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||||
// if ct != nil {
|
// if ct != nil {
|
||||||
@@ -64,7 +67,7 @@ func AppList(c *gin.Context) {
|
|||||||
data["list"] = collection.List
|
data["list"] = collection.List
|
||||||
data["community"] = collection.Community
|
data["community"] = collection.Community
|
||||||
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取一个可用端口
|
// @Summary 获取一个可用端口
|
||||||
@@ -83,7 +86,8 @@ func GetPort(c *gin.Context) {
|
|||||||
p, _ = port2.GetAvailablePort(t)
|
p, _ = port2.GetAvailablePort(t)
|
||||||
ok = !port2.IsPortAvailable(p, t)
|
ok = !port2.IsPortAvailable(p, t)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
|
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
|
||||||
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 检查端口是否可用
|
// @Summary 检查端口是否可用
|
||||||
@@ -98,7 +102,7 @@ func GetPort(c *gin.Context) {
|
|||||||
func PortCheck(c *gin.Context) {
|
func PortCheck(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Param("port"))
|
p, _ := strconv.Atoi(c.Param("port"))
|
||||||
t := c.DefaultQuery("type", "tcp")
|
t := c.DefaultQuery("type", "tcp")
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port2.IsPortAvailable(p, t)})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port2.IsPortAvailable(p, t)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 我的应用列表
|
// @Summary 我的应用列表
|
||||||
@@ -117,10 +121,10 @@ func MyAppList(c *gin.Context) {
|
|||||||
position, _ := strconv.ParseBool(c.DefaultQuery("position", "true"))
|
position, _ := strconv.ParseBool(c.DefaultQuery("position", "true"))
|
||||||
list, unTranslation := service.MyService.App().GetMyList(index, size, position)
|
list, unTranslation := service.MyService.App().GetMyList(index, size, position)
|
||||||
data := make(map[string]interface{}, 2)
|
data := make(map[string]interface{}, 2)
|
||||||
data["list"] = list
|
data["casaos_apps"] = list
|
||||||
data["local"] = unTranslation
|
data["local_apps"] = unTranslation
|
||||||
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary my app hardware usage list
|
// @Summary my app hardware usage list
|
||||||
@@ -132,7 +136,8 @@ func MyAppList(c *gin.Context) {
|
|||||||
// @Router /app/usage [get]
|
// @Router /app/usage [get]
|
||||||
func AppUsageList(c *gin.Context) {
|
func AppUsageList(c *gin.Context) {
|
||||||
list := service.MyService.App().GetHardwareUsage()
|
list := service.MyService.App().GetHardwareUsage()
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
|
//c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: nil})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 应用详情
|
// @Summary 应用详情
|
||||||
@@ -147,7 +152,11 @@ func AppInfo(c *gin.Context) {
|
|||||||
|
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
language := c.GetHeader("Language")
|
language := c.GetHeader("Language")
|
||||||
info := service.MyService.Casa().GetServerAppInfo(id, "", language)
|
info, err := service.MyService.Casa().GetServerAppInfo(id, "", language)
|
||||||
|
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
|
||||||
|
}
|
||||||
if info.NetworkModel != "host" {
|
if info.NetworkModel != "host" {
|
||||||
for i := 0; i < len(info.Ports); i++ {
|
for i := 0; i < len(info.Ports); i++ {
|
||||||
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
|
||||||
@@ -214,7 +223,7 @@ func AppInfo(c *gin.Context) {
|
|||||||
|
|
||||||
info.MaxMemory = (service.MyService.System().GetMemInfo()["total"]).(uint64) >> 20
|
info.MaxMemory = (service.MyService.System().GetMemInfo()["total"]).(uint64) >> 20
|
||||||
|
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取远程分类列表
|
// @Summary 获取远程分类列表
|
||||||
@@ -225,7 +234,11 @@ func AppInfo(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /app/category [get]
|
// @Router /app/category [get]
|
||||||
func CategoryList(c *gin.Context) {
|
func CategoryList(c *gin.Context) {
|
||||||
list := service.MyService.Casa().GetServerCategoryList()
|
list, err := service.MyService.Casa().GetServerCategoryList()
|
||||||
|
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
|
||||||
|
}
|
||||||
var count uint = 0
|
var count uint = 0
|
||||||
for _, category := range list {
|
for _, category := range list {
|
||||||
count += category.Count
|
count += category.Count
|
||||||
@@ -234,7 +247,7 @@ func CategoryList(c *gin.Context) {
|
|||||||
rear := append([]model.CategoryList{}, list[0:]...)
|
rear := append([]model.CategoryList{}, list[0:]...)
|
||||||
list = append(list[:0], model.CategoryList{Count: count, Name: "All", Font: "apps"})
|
list = append(list[:0], model.CategoryList{Count: count, Name: "All", Font: "apps"})
|
||||||
list = append(list, rear...)
|
list = append(list, rear...)
|
||||||
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 分享该应用配置
|
// @Summary 分享该应用配置
|
||||||
@@ -247,5 +260,5 @@ func CategoryList(c *gin.Context) {
|
|||||||
func ShareAppFile(c *gin.Context) {
|
func ShareAppFile(c *gin.Context) {
|
||||||
str, _ := ioutil.ReadAll(c.Request.Body)
|
str, _ := ioutil.ReadAll(c.Request.Body)
|
||||||
content := service.MyService.Casa().ShareAppFile(str)
|
content := service.MyService.Casa().ShareAppFile(str)
|
||||||
c.JSON(http.StatusOK, json.RawMessage(content))
|
c.JSON(common_err.SUCCESS, json.RawMessage(content))
|
||||||
}
|
}
|
||||||
|
|||||||
466
route/v1/disk.go
@@ -1,7 +1,6 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -9,8 +8,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/model/notify"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
@@ -28,7 +28,35 @@ var diskMap = make(map[string]string)
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/list [get]
|
// @Router /disk/list [get]
|
||||||
func GetDiskList(c *gin.Context) {
|
func GetDiskList(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
if len(path) > 0 {
|
||||||
|
m := service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := c.DefaultQuery("type", "")
|
||||||
list := service.MyService.Disk().LSBLK(false)
|
list := service.MyService.Disk().LSBLK(false)
|
||||||
|
if t == "usb" {
|
||||||
|
data := []model.DriveUSB{}
|
||||||
|
for _, v := range list {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = append(data, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
dbList := service.MyService.Disk().GetSerialAll()
|
dbList := service.MyService.Disk().GetSerialAll()
|
||||||
part := make(map[string]int64, len(dbList))
|
part := make(map[string]int64, len(dbList))
|
||||||
for _, v := range dbList {
|
for _, v := range dbList {
|
||||||
@@ -51,14 +79,13 @@ func GetDiskList(c *gin.Context) {
|
|||||||
disk.Size = list[i].Size
|
disk.Size = list[i].Size
|
||||||
disk.Path = list[i].Path
|
disk.Path = list[i].Path
|
||||||
disk.Model = list[i].Model
|
disk.Model = list[i].Model
|
||||||
|
disk.ChildrenNumber = len(list[i].Children)
|
||||||
if len(list[i].Children) > 0 && findSystem == 0 {
|
if len(list[i].Children) > 0 && findSystem == 0 {
|
||||||
for j := 0; j < len(list[i].Children); j++ {
|
for j := 0; j < len(list[i].Children); j++ {
|
||||||
if len(list[i].Children[j].Children) > 0 {
|
if len(list[i].Children[j].Children) > 0 {
|
||||||
for _, v := range list[i].Children[j].Children {
|
for _, v := range list[i].Children[j].Children {
|
||||||
if v.MountPoint == "/" {
|
if v.MountPoint == "/" {
|
||||||
stor := model.Storage{}
|
stor := model.Storage{}
|
||||||
stor.Name = "System"
|
|
||||||
stor.MountPoint = v.MountPoint
|
stor.MountPoint = v.MountPoint
|
||||||
stor.Size = v.FSSize
|
stor.Size = v.FSSize
|
||||||
stor.Avail = v.FSAvail
|
stor.Avail = v.FSAvail
|
||||||
@@ -82,7 +109,6 @@ func GetDiskList(c *gin.Context) {
|
|||||||
} else {
|
} else {
|
||||||
if list[i].Children[j].MountPoint == "/" {
|
if list[i].Children[j].MountPoint == "/" {
|
||||||
stor := model.Storage{}
|
stor := model.Storage{}
|
||||||
stor.Name = "System"
|
|
||||||
stor.MountPoint = list[i].Children[j].MountPoint
|
stor.MountPoint = list[i].Children[j].MountPoint
|
||||||
stor.Size = list[i].Children[j].FSSize
|
stor.Size = list[i].Children[j].FSSize
|
||||||
stor.Avail = list[i].Children[j].FSAvail
|
stor.Avail = list[i].Children[j].FSAvail
|
||||||
@@ -116,31 +142,29 @@ func GetDiskList(c *gin.Context) {
|
|||||||
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
temp.SmartStatus.Passed = true
|
temp.SmartStatus.Passed = true
|
||||||
}
|
}
|
||||||
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
|
isAvail := true
|
||||||
|
for _, v := range list[i].Children {
|
||||||
|
if v.MountPoint != "" {
|
||||||
stor := model.Storage{}
|
stor := model.Storage{}
|
||||||
stor.MountPoint = list[i].Children[0].MountPoint
|
stor.MountPoint = v.MountPoint
|
||||||
stor.Size = list[i].Children[0].FSSize
|
stor.Size = v.FSSize
|
||||||
stor.Avail = list[i].Children[0].FSAvail
|
stor.Avail = v.FSAvail
|
||||||
stor.Path = list[i].Children[0].Path
|
stor.Path = v.Path
|
||||||
stor.Type = list[i].Children[0].FsType
|
stor.Type = v.FsType
|
||||||
stor.DriveName = list[i].Name
|
stor.DriveName = list[i].Name
|
||||||
pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
|
|
||||||
if len(pathArr) == 3 {
|
|
||||||
stor.Name = pathArr[2]
|
|
||||||
}
|
|
||||||
if t, ok := part[list[i].Children[0].MountPoint]; ok {
|
|
||||||
stor.CreatedAt = t
|
|
||||||
}
|
|
||||||
storage = append(storage, stor)
|
storage = append(storage, stor)
|
||||||
} else {
|
isAvail = false
|
||||||
//todo 长度有问题
|
}
|
||||||
if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" {
|
}
|
||||||
|
|
||||||
|
if isAvail {
|
||||||
|
//if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" {
|
||||||
disk.NeedFormat = false
|
disk.NeedFormat = false
|
||||||
avail = append(avail, disk)
|
avail = append(avail, disk)
|
||||||
} else {
|
// } else {
|
||||||
disk.NeedFormat = true
|
// disk.NeedFormat = true
|
||||||
avail = append(avail, disk)
|
// avail = append(avail, disk)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
disk.Temperature = temp.Temperature.Current
|
disk.Temperature = temp.Temperature.Current
|
||||||
@@ -154,7 +178,108 @@ func GetDiskList(c *gin.Context) {
|
|||||||
data["storage"] = storage
|
data["storage"] = storage
|
||||||
data["avail"] = avail
|
data["avail"] = avail
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary disk list
|
||||||
|
// @Produce application/json
|
||||||
|
// @Accept application/json
|
||||||
|
// @Tags disk
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Success 200 {string} string "ok"
|
||||||
|
// @Router /disk/list [get]
|
||||||
|
func GetDisksUSBList(c *gin.Context) {
|
||||||
|
list := service.MyService.Disk().LSBLK(false)
|
||||||
|
data := []model.DriveUSB{}
|
||||||
|
for _, v := range list {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Label
|
||||||
|
if temp.Name == "" {
|
||||||
|
temp.Name = v.Name
|
||||||
|
}
|
||||||
|
temp.Size = v.Size
|
||||||
|
children := []model.USBChildren{}
|
||||||
|
for _, child := range v.Children {
|
||||||
|
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
tempChildren := model.USBChildren{}
|
||||||
|
tempChildren.MountPoint = child.MountPoint
|
||||||
|
tempChildren.Size, _ = strconv.ParseUint(child.FSSize, 10, 64)
|
||||||
|
tempChildren.Avail, _ = strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
tempChildren.Name = child.Label
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
children = append(children, tempChildren)
|
||||||
|
temp.Avail += avail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.Children = children
|
||||||
|
data = append(data, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDisksUmount(c *gin.Context) {
|
||||||
|
id := c.GetHeader("user_id")
|
||||||
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
|
||||||
|
path := js["path"]
|
||||||
|
pwd := js["password"]
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserAllInfoById(id)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := diskMap[path]; ok {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diskInfo := service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
for _, v := range diskInfo.Children {
|
||||||
|
service.MyService.Disk().UmountPointAndRemoveDir(v.Path)
|
||||||
|
//delete data
|
||||||
|
service.MyService.Disk().DeleteMountPoint(v.Path, v.MountPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
|
|
||||||
|
//send notify to client
|
||||||
|
msg := notify.StorageMessage{}
|
||||||
|
msg.Action = "REMOVED"
|
||||||
|
msg.Path = path
|
||||||
|
msg.Volume = ""
|
||||||
|
msg.Size = 0
|
||||||
|
msg.Type = ""
|
||||||
|
service.MyService.Notify().SendStorageBySocket(msg)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: path})
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDiskUSB(c *gin.Context) {
|
||||||
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
mountPoint := js["mount_point"]
|
||||||
|
if file.CheckNotExist(mountPoint) {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.MyService.Disk().UmountUSB(mountPoint)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mountPoint})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get disk list
|
// @Summary get disk list
|
||||||
@@ -191,49 +316,6 @@ func GetDiskInfo(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary format storage
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags disk
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param path formData string true "e.g. /dev/sda1"
|
|
||||||
// @Param pwd formData string true "user password"
|
|
||||||
// @Param volume formData string true "mount point"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /disk/format [post]
|
|
||||||
func PostDiskFormat(c *gin.Context) {
|
|
||||||
path := c.PostForm("path")
|
|
||||||
t := "ext4"
|
|
||||||
pwd := c.PostForm("pwd")
|
|
||||||
volume := c.PostForm("volume")
|
|
||||||
|
|
||||||
if pwd != config.UserInfo.PWD {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(path) == 0 || len(t) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := diskMap[path]; ok {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
diskMap[path] = "busying"
|
|
||||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
|
||||||
format := service.MyService.Disk().FormatDisk(path, t)
|
|
||||||
if len(format) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
|
||||||
delete(diskMap, path)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
service.MyService.Disk().MountDisk(path, volume)
|
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
|
||||||
delete(diskMap, path)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 获取支持的格式
|
// @Summary 获取支持的格式
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -256,15 +338,17 @@ func FormatDiskType(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/delpart [delete]
|
// @Router /disk/delpart [delete]
|
||||||
func RemovePartition(c *gin.Context) {
|
func RemovePartition(c *gin.Context) {
|
||||||
path := c.PostForm("path")
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
path := js["path"]
|
||||||
|
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
}
|
}
|
||||||
var p = path[:len(path)-1]
|
var p = path[:len(path)-1]
|
||||||
var n = path[len(path)-1:]
|
var n = path[len(path)-1:]
|
||||||
service.MyService.Disk().DelPartition(p, n)
|
service.MyService.Disk().DelPartition(p, n)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary add storage
|
// @Summary add storage
|
||||||
@@ -280,107 +364,137 @@ func RemovePartition(c *gin.Context) {
|
|||||||
// @Router /disk/storage [post]
|
// @Router /disk/storage [post]
|
||||||
func PostDiskAddPartition(c *gin.Context) {
|
func PostDiskAddPartition(c *gin.Context) {
|
||||||
|
|
||||||
name := c.PostForm("name")
|
js := make(map[string]interface{})
|
||||||
path := c.PostForm("path")
|
c.ShouldBind(&js)
|
||||||
format, _ := strconv.ParseBool(c.PostForm("format"))
|
path := js["path"].(string)
|
||||||
|
//name := js["name"].(string)
|
||||||
|
format := js["format"].(bool)
|
||||||
|
|
||||||
if len(name) == 0 || len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := diskMap[path]; ok {
|
if _, ok := diskMap[path]; ok {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
return
|
|
||||||
}
|
|
||||||
if !file.CheckNotExist("/DATA/" + name) {
|
|
||||||
// /mnt/name exist
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//diskInfo := service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
|
||||||
|
// if !file.CheckNotExist("/DATA/" + name) {
|
||||||
|
// // /mnt/name exist
|
||||||
|
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
diskMap[path] = "busying"
|
diskMap[path] = "busying"
|
||||||
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
currentDisk := service.MyService.Disk().GetDiskInfo(path)
|
||||||
if !format {
|
if format {
|
||||||
if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") {
|
// format := service.MyService.Disk().FormatDisk(path+"1", "ext4")
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
// if len(format) == 0 {
|
||||||
delete(diskMap, path)
|
// delete(diskMap, path)
|
||||||
return
|
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
||||||
}
|
// return
|
||||||
} else {
|
// }
|
||||||
service.MyService.Disk().AddPartition(path)
|
service.MyService.Disk().AddPartition(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
formatBool := true
|
// formatBool := true
|
||||||
for formatBool {
|
// for formatBool {
|
||||||
|
// currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||||
|
// if len(currentDisk.Children) > 0 {
|
||||||
|
// formatBool = false
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// time.Sleep(time.Second)
|
||||||
|
// }
|
||||||
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
||||||
fmt.Println(currentDisk.Children)
|
// if len(currentDisk.Children) != 1 {
|
||||||
if len(currentDisk.Children) > 0 {
|
// c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
||||||
formatBool = false
|
// return
|
||||||
break
|
// }
|
||||||
|
for i := 0; i < len(currentDisk.Children); i++ {
|
||||||
|
childrenName := currentDisk.Children[i].Label
|
||||||
|
if len(childrenName) == 0 {
|
||||||
|
childrenName = "Storage_" + currentDisk.Children[i].Name
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second)
|
mountPath := "/DATA/" + childrenName
|
||||||
}
|
if !file.CheckNotExist(mountPath) {
|
||||||
currentDisk = service.MyService.Disk().GetDiskInfo(path)
|
ls := service.MyService.System().GetDirPath(mountPath)
|
||||||
if len(currentDisk.Children) != 1 {
|
if len(ls) > 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
|
// exist
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
mountPath := "/DATA/" + name
|
|
||||||
m := model2.SerialDisk{}
|
m := model2.SerialDisk{}
|
||||||
m.MountPoint = mountPath
|
m.MountPoint = mountPath
|
||||||
m.Path = currentDisk.Children[0].Path
|
m.Path = currentDisk.Children[i].Path
|
||||||
m.UUID = currentDisk.Children[0].UUID
|
m.UUID = currentDisk.Children[i].UUID
|
||||||
m.State = 0
|
m.State = 0
|
||||||
m.CreatedAt = time.Now().Unix()
|
m.CreatedAt = time.Now().Unix()
|
||||||
service.MyService.Disk().SaveMountPoint(m)
|
service.MyService.Disk().SaveMountPoint(m)
|
||||||
|
|
||||||
//mount dir
|
//mount dir
|
||||||
service.MyService.Disk().MountDisk(currentDisk.Children[0].Path, mountPath)
|
service.MyService.Disk().MountDisk(currentDisk.Children[i].Path, mountPath)
|
||||||
|
}
|
||||||
|
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
|
|
||||||
delete(diskMap, path)
|
delete(diskMap, path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
|
//send notify to client
|
||||||
|
msg := notify.StorageMessage{}
|
||||||
|
msg.Action = "ADDED"
|
||||||
|
msg.Path = currentDisk.Children[0].Path
|
||||||
|
msg.Volume = "/DATA/"
|
||||||
|
msg.Size = currentDisk.Children[0].Size
|
||||||
|
msg.Type = currentDisk.Children[0].Tran
|
||||||
|
service.MyService.Notify().SendStorageBySocket(msg)
|
||||||
|
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary add mount point
|
// @Param pwd formData string true "user password"
|
||||||
// @Produce application/json
|
// @Param volume formData string true "mount point"
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags disk
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param path formData string true "for example: /dev/sda1"
|
|
||||||
// @Param serial formData string true "disk id"
|
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/mount [post]
|
// @Router /disk/format [post]
|
||||||
func PostMountDisk(c *gin.Context) {
|
func PostDiskFormat(c *gin.Context) {
|
||||||
// for example: path=/dev/sda1
|
id := c.GetHeader("user_id")
|
||||||
path := c.PostForm("path")
|
js := make(map[string]string)
|
||||||
serial := c.PostForm("serial")
|
c.ShouldBind(&js)
|
||||||
|
path := js["path"]
|
||||||
mountPath := "/DATA/volume"
|
t := "ext4"
|
||||||
var list = service.MyService.Disk().GetSerialAll()
|
pwd := js["password"]
|
||||||
var pathMapList = make(map[string]string, len(list))
|
volume := js["volume"]
|
||||||
for _, v := range list {
|
user := service.MyService.User().GetUserAllInfoById(id)
|
||||||
pathMapList[v.MountPoint] = "1"
|
if user.Id == 0 {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(list)+1; i++ {
|
if len(path) == 0 || len(t) == 0 {
|
||||||
if _, ok := pathMapList[mountPath+strconv.Itoa(i)]; !ok {
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
mountPath = mountPath + strconv.Itoa(i)
|
return
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
if _, ok := diskMap[path]; ok {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
diskMap[path] = "busying"
|
||||||
//mount dir
|
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||||
service.MyService.Disk().MountDisk(path, mountPath)
|
format := service.MyService.Disk().FormatDisk(path, t)
|
||||||
|
if len(format) == 0 {
|
||||||
m := model2.SerialDisk{}
|
delete(diskMap, path)
|
||||||
m.MountPoint = mountPath
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)})
|
||||||
m.Path = path
|
return
|
||||||
m.UUID = serial
|
}
|
||||||
m.State = 0
|
service.MyService.Disk().MountDisk(path, volume)
|
||||||
//service.MyService.Disk().SaveMountPoint(m)
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
delete(diskMap, path)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary remove mount point
|
// @Summary remove mount point
|
||||||
@@ -394,22 +508,30 @@ func PostMountDisk(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /disk/umount [post]
|
// @Router /disk/umount [post]
|
||||||
func PostDiskUmount(c *gin.Context) {
|
func PostDiskUmount(c *gin.Context) {
|
||||||
|
id := c.GetHeader("user_id")
|
||||||
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
|
||||||
path := c.PostForm("path")
|
path := js["path"]
|
||||||
mountPoint := c.PostForm("volume")
|
mountPoint := js["volume"]
|
||||||
pwd := c.PostForm("pwd")
|
pwd := js["password"]
|
||||||
|
|
||||||
if len(path) == 0 || len(mountPoint) == 0 {
|
if len(path) == 0 || len(mountPoint) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if pwd != config.UserInfo.PWD {
|
user := service.MyService.User().GetUserAllInfoById(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
if user.Id == 0 {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if encryption.GetMD5ByStr(pwd) != user.Password {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := diskMap[path]; ok {
|
if _, ok := diskMap[path]; ok {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +539,16 @@ func PostDiskUmount(c *gin.Context) {
|
|||||||
//delete data
|
//delete data
|
||||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
||||||
service.MyService.Disk().RemoveLSBLKCache()
|
service.MyService.Disk().RemoveLSBLKCache()
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
|
//send notify to client
|
||||||
|
msg := notify.StorageMessage{}
|
||||||
|
msg.Action = "REMOVED"
|
||||||
|
msg.Path = path
|
||||||
|
msg.Volume = mountPoint
|
||||||
|
msg.Size = 0
|
||||||
|
msg.Type = ""
|
||||||
|
service.MyService.Notify().SendStorageBySocket(msg)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary confirm delete disk
|
// @Summary confirm delete disk
|
||||||
@@ -455,45 +586,10 @@ func GetDiskCheck(c *gin.Context) {
|
|||||||
for _, v := range dbList {
|
for _, v := range dbList {
|
||||||
if _, ok := mapList[v.UUID]; !ok {
|
if _, ok := mapList[v.UUID]; !ok {
|
||||||
//disk undefind
|
//disk undefind
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: "disk undefind"})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "disk undefind"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary check mount point
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags disk
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /disk/usb [get]
|
|
||||||
func GetUSBList(c *gin.Context) {
|
|
||||||
list := service.MyService.Disk().LSBLK(false)
|
|
||||||
data := []model.DriveUSB{}
|
|
||||||
for _, v := range list {
|
|
||||||
if v.Tran == "usb" {
|
|
||||||
temp := model.DriveUSB{}
|
|
||||||
temp.Model = v.Model
|
|
||||||
temp.Name = v.Name
|
|
||||||
temp.Size = v.Size
|
|
||||||
mountTemp := true
|
|
||||||
if len(v.Children) == 0 {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
|
||||||
for _, child := range v.Children {
|
|
||||||
if len(child.MountPoint) > 0 {
|
|
||||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
|
||||||
temp.Avail += avail
|
|
||||||
} else {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
temp.Mount = mountTemp
|
|
||||||
data = append(data, temp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
json2 "encoding/json"
|
json2 "encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
@@ -25,6 +27,7 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
|
"go.uber.org/zap"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,14 +44,14 @@ func DockerTerminal(c *gin.Context) {
|
|||||||
row := c.DefaultQuery("rows", "30")
|
row := c.DefaultQuery("rows", "30")
|
||||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
container := c.Param("id")
|
container := c.Param("id")
|
||||||
hr, err := service.Exec(container, row, col)
|
hr, err := service.Exec(container, row, col)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
// 关闭I/O流
|
// 关闭I/O流
|
||||||
@@ -63,14 +66,41 @@ func DockerTerminal(c *gin.Context) {
|
|||||||
docker.WsReaderCopy(conn, hr.Conn)
|
docker.WsReaderCopy(conn, hr.Conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
//打开本机的ssh接口
|
func PostSshLogin(c *gin.Context) {
|
||||||
func WsSsh(c *gin.Context) {
|
j := make(map[string]string)
|
||||||
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
|
c.ShouldBind(&j)
|
||||||
|
userName := j["username"]
|
||||||
|
password := j["password"]
|
||||||
|
port := j["port"]
|
||||||
|
if userName == "" || password == "" || port == "" {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "Username or password or port is empty"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err := docker.NewSshClient(userName, password, port)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.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."})
|
||||||
|
loger.Error("connect ssh error", zap.Any("error", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
|
func WsSsh(c *gin.Context) {
|
||||||
|
_, e := exec.LookPath("ssh")
|
||||||
|
if e != nil {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "ssh server not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userName := c.Query("username")
|
||||||
|
password := c.Query("password")
|
||||||
|
port := c.Query("port")
|
||||||
|
wsConn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
var logBuff = new(bytes.Buffer)
|
var logBuff = new(bytes.Buffer)
|
||||||
|
|
||||||
quitChan := make(chan bool, 3)
|
quitChan := make(chan bool, 3)
|
||||||
user := ""
|
// user := ""
|
||||||
password := ""
|
// password := ""
|
||||||
var login int = 1
|
var login int = 1
|
||||||
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
|
cols, _ := strconv.Atoi(c.DefaultQuery("cols", "200"))
|
||||||
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
|
rows, _ := strconv.Atoi(c.DefaultQuery("rows", "32"))
|
||||||
@@ -78,14 +108,16 @@ func WsSsh(c *gin.Context) {
|
|||||||
for login != 0 {
|
for login != 0 {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
if userName == "" || password == "" || port == "" {
|
||||||
wsConn.WriteMessage(websocket.TextMessage, []byte("login:"))
|
wsConn.WriteMessage(websocket.TextMessage, []byte("username or password or port is empty"))
|
||||||
user = docker.ReceiveWsMsgUser(wsConn, logBuff)
|
}
|
||||||
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
// wsConn.WriteMessage(websocket.TextMessage, []byte("login:"))
|
||||||
wsConn.WriteMessage(websocket.TextMessage, []byte("password:"))
|
// user = docker.ReceiveWsMsgUser(wsConn, logBuff)
|
||||||
password = docker.ReceiveWsMsgPassword(wsConn, logBuff)
|
// wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
||||||
wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
// wsConn.WriteMessage(websocket.TextMessage, []byte("password:"))
|
||||||
client, err = docker.NewSshClient(user, password)
|
// password = docker.ReceiveWsMsgPassword(wsConn, logBuff)
|
||||||
|
// wsConn.WriteMessage(websocket.TextMessage, []byte("\r\n\x1b[0m"))
|
||||||
|
client, err = docker.NewSshClient(userName, password, port)
|
||||||
|
|
||||||
if err != nil && client == nil {
|
if err != nil && client == nil {
|
||||||
wsConn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
wsConn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
||||||
@@ -110,25 +142,6 @@ func WsSsh(c *gin.Context) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//安装进度推送
|
|
||||||
func SpeedPush(c *gin.Context) {
|
|
||||||
//token := c.Query("token")
|
|
||||||
//if len(token) == 0 || token != config.UserInfo.Token {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
|
|
||||||
//ws, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
|
|
||||||
//defer ws.Close()
|
|
||||||
//
|
|
||||||
//for {
|
|
||||||
// select {
|
|
||||||
// case msg := <-WSMSG:
|
|
||||||
// ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintln(msg)))
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 安装app(该接口需要post json数据)
|
// @Summary 安装app(该接口需要post json数据)
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -144,7 +157,7 @@ func SpeedPush(c *gin.Context) {
|
|||||||
func InstallApp(c *gin.Context) {
|
func InstallApp(c *gin.Context) {
|
||||||
var appInfo model.ServerAppList
|
var appInfo model.ServerAppList
|
||||||
m := model.CustomizationPostData{}
|
m := model.CustomizationPostData{}
|
||||||
c.BindJSON(&m)
|
c.ShouldBind(&m)
|
||||||
|
|
||||||
const CUSTOM = "custom"
|
const CUSTOM = "custom"
|
||||||
var dockerImage string
|
var dockerImage string
|
||||||
@@ -154,19 +167,22 @@ func InstallApp(c *gin.Context) {
|
|||||||
if len(m.Protocol) == 0 {
|
if len(m.Protocol) == 0 {
|
||||||
m.Protocol = "http"
|
m.Protocol = "http"
|
||||||
}
|
}
|
||||||
if m.Origin != "custom" {
|
m.ContainerName = strings.Replace(m.Label, " ", "_", -1)
|
||||||
oldName := m.Label
|
if m.Origin != CUSTOM {
|
||||||
|
oldName := m.ContainerName
|
||||||
|
oldLabel := m.Label
|
||||||
for i := 0; true; i++ {
|
for i := 0; true; i++ {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
m.Label = oldName + "-" + strconv.Itoa(i)
|
m.ContainerName = oldName + "-" + strconv.Itoa(i)
|
||||||
|
m.Label = oldLabel + "-" + strconv.Itoa(i)
|
||||||
}
|
}
|
||||||
if _, err := service.MyService.Docker().DockerListByName(m.Label); err != nil {
|
if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
|
if _, err := service.MyService.Docker().DockerListByName(m.ContainerName); err == nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +193,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
//c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
//c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
portMap, _ := strconv.Atoi(m.PortMap)
|
portMap, _ := strconv.Atoi(m.PortMap)
|
||||||
if !port2.IsPortAvailable(portMap, "tcp") {
|
if !port2.IsPortAvailable(portMap, "tcp") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,39 +209,39 @@ func InstallApp(c *gin.Context) {
|
|||||||
dockerImage = m.Image
|
dockerImage = m.Image
|
||||||
dockerImageVersion = "latest"
|
dockerImageVersion = "latest"
|
||||||
}
|
}
|
||||||
|
m.Image = dockerImage + ":" + dockerImageVersion
|
||||||
for _, u := range m.Ports {
|
for _, u := range m.Ports {
|
||||||
|
|
||||||
if u.Protocol == "udp" {
|
if u.Protocol == "udp" {
|
||||||
t, _ := strconv.Atoi(u.CommendPort)
|
t, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(t, "udp") {
|
if !port2.IsPortAvailable(t, "udp") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if u.Protocol == "tcp" {
|
} else if u.Protocol == "tcp" {
|
||||||
|
|
||||||
te, _ := strconv.Atoi(u.CommendPort)
|
te, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(te, "tcp") {
|
if !port2.IsPortAvailable(te, "tcp") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if u.Protocol == "both" {
|
} else if u.Protocol == "both" {
|
||||||
t, _ := strconv.Atoi(u.CommendPort)
|
t, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(t, "udp") {
|
if !port2.IsPortAvailable(t, "udp") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
te, _ := strconv.Atoi(u.CommendPort)
|
te, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(te, "tcp") {
|
if !port2.IsPortAvailable(te, "tcp") {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.Origin == "custom" {
|
if m.Origin == CUSTOM {
|
||||||
for _, device := range m.Devices {
|
for _, device := range m.Devices {
|
||||||
if file.CheckNotExist(device.Path) {
|
if file.CheckNotExist(device.Path) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DEVICE_NOT_EXIST, Message: device.Path + "," + common_err.GetMsg(common_err.DEVICE_NOT_EXIST)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DEVICE_NOT_EXIST, Message: device.Path + "," + common_err.GetMsg(common_err.DEVICE_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +279,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
// installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
|
// installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
// installLog.Id = uuid.NewV4().String()
|
// installLog.Id = uuid.NewV4().String()
|
||||||
// service.MyService.Notify().AddLog(installLog)
|
// service.MyService.Notify().AddLog(installLog)
|
||||||
if m.Origin != "custom" {
|
if m.Origin != CUSTOM {
|
||||||
for _, plugin := range appInfo.Plugins {
|
for _, plugin := range appInfo.Plugins {
|
||||||
if plugin == "mysql" {
|
if plugin == "mysql" {
|
||||||
mid := uuid.NewV4().String()
|
mid := uuid.NewV4().String()
|
||||||
@@ -318,11 +334,11 @@ func InstallApp(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
|
for !service.MyService.Docker().IsExistImage(m.Image) {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m)
|
_, err = service.MyService.Docker().DockerContainerCreate(m, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
|
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
|
||||||
notify := notify.Application{}
|
notify := notify.Application{}
|
||||||
@@ -349,7 +365,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
// echo -e "hellow\nworld" >>
|
// echo -e "hellow\nworld" >>
|
||||||
|
|
||||||
//step:启动容器
|
//step:启动容器
|
||||||
err = service.MyService.Docker().DockerContainerStart(m.Label)
|
err = service.MyService.Docker().DockerContainerStart(m.ContainerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
|
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
|
||||||
notify := notify.Application{}
|
notify := notify.Application{}
|
||||||
@@ -372,7 +388,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//step: 启动成功 检查容器状态确认启动成功
|
//step: 启动成功 检查容器状态确认启动成功
|
||||||
container, err := service.MyService.Docker().DockerContainerInfo(m.Label)
|
container, err := service.MyService.Docker().DockerContainerInfo(m.ContainerName)
|
||||||
if err != nil && container.ContainerJSONBase.State.Running {
|
if err != nil && container.ContainerJSONBase.State.Running {
|
||||||
notify := notify.Application{}
|
notify := notify.Application{}
|
||||||
notify.Icon = m.Icon
|
notify.Icon = m.Icon
|
||||||
@@ -405,7 +421,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m.Label})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m.Label})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +442,7 @@ func InstallApp(c *gin.Context) {
|
|||||||
// // appInfo := service.MyService.App().GetServerAppInfo(appId)
|
// // appInfo := service.MyService.App().GetServerAppInfo(appId)
|
||||||
//
|
//
|
||||||
// m := model.CustomizationPostData{}
|
// m := model.CustomizationPostData{}
|
||||||
// c.BindJSON(&m)
|
// c.ShouldBind(&m)
|
||||||
// //检查端口
|
// //检查端口
|
||||||
// if len(m.PortMap) == 0 || m.PortMap == "0" {
|
// if len(m.PortMap) == 0 || m.PortMap == "0" {
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
@@ -603,27 +619,27 @@ func UnInstallApp(c *gin.Context) {
|
|||||||
appId := c.Param("id")
|
appId := c.Param("id")
|
||||||
|
|
||||||
if len(appId) == 0 {
|
if len(appId) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//info := service.MyService.App().GetUninstallInfo(appId)
|
//info := service.MyService.App().GetUninstallInfo(appId)
|
||||||
|
|
||||||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
//step:停止容器
|
//step:停止容器
|
||||||
err = service.MyService.Docker().DockerContainerStop(appId)
|
err = service.MyService.Docker().DockerContainerStop(appId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = service.MyService.Docker().DockerContainerRemove(appId, false)
|
err = service.MyService.Docker().DockerContainerRemove(appId, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.UNINSTALL_APP_ERROR, Message: common_err.GetMsg(common_err.UNINSTALL_APP_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +704,7 @@ func UnInstallApp(c *gin.Context) {
|
|||||||
notify.Success = true
|
notify.Success = true
|
||||||
notify.Finished = true
|
notify.Finished = true
|
||||||
service.MyService.Notify().SendUninstallAppBySocket(notify)
|
service.MyService.Notify().SendUninstallAppBySocket(notify)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,26 +719,35 @@ func UnInstallApp(c *gin.Context) {
|
|||||||
// @Router /app/state/{id} [put]
|
// @Router /app/state/{id} [put]
|
||||||
func ChangAppState(c *gin.Context) {
|
func ChangAppState(c *gin.Context) {
|
||||||
appId := c.Param("id")
|
appId := c.Param("id")
|
||||||
state := c.DefaultPostForm("state", "stop")
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
state := js["state"]
|
||||||
|
if len(appId) == 0 || len(state) == 0 {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
if state == "stop" {
|
if state == "start" {
|
||||||
err = service.MyService.Docker().DockerContainerStop(appId)
|
|
||||||
} else if state == "start" {
|
|
||||||
err = service.MyService.Docker().DockerContainerStart(appId)
|
err = service.MyService.Docker().DockerContainerStart(appId)
|
||||||
} else if state == "restart" {
|
} else if state == "restart" {
|
||||||
service.MyService.Docker().DockerContainerStop(appId)
|
service.MyService.Docker().DockerContainerStop(appId)
|
||||||
err = service.MyService.Docker().DockerContainerStart(appId)
|
err = service.MyService.Docker().DockerContainerStart(appId)
|
||||||
|
} else {
|
||||||
|
err = service.MyService.Docker().DockerContainerStop(appId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
info, err := service.MyService.App().GetContainerInfo(appId)
|
info, err := service.MyService.App().GetContainerInfo(appId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info.State})
|
|
||||||
|
// @tiger - 用 {'state': ...} 来体现出参上下文
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info.State})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 查看容器日志
|
// @Summary 查看容器日志
|
||||||
@@ -736,7 +761,7 @@ func ChangAppState(c *gin.Context) {
|
|||||||
func ContainerLog(c *gin.Context) {
|
func ContainerLog(c *gin.Context) {
|
||||||
appId := c.Param("id")
|
appId := c.Param("id")
|
||||||
log, _ := service.MyService.Docker().DockerContainerLog(appId)
|
log, _ := service.MyService.Docker().DockerContainerLog(appId)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取容器状态
|
// @Summary 获取容器状态
|
||||||
@@ -750,10 +775,10 @@ func ContainerLog(c *gin.Context) {
|
|||||||
// @Router /app/state/{id} [get]
|
// @Router /app/state/{id} [get]
|
||||||
func GetContainerState(c *gin.Context) {
|
func GetContainerState(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
t := c.DefaultQuery("type", "0")
|
//t := c.DefaultQuery("type", "0")
|
||||||
containerInfo, e := service.MyService.App().GetSimpleContainerInfo(id)
|
containerInfo, e := service.MyService.App().GetSimpleContainerInfo(id)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: e.Error()})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: e.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,12 +786,12 @@ func GetContainerState(c *gin.Context) {
|
|||||||
|
|
||||||
data["state"] = containerInfo.State
|
data["state"] = containerInfo.State
|
||||||
|
|
||||||
if t == "1" {
|
// if t == "1" {
|
||||||
appInfo := service.MyService.App().GetAppDBInfo(id)
|
// appInfo := service.MyService.App().GetAppDBInfo(id)
|
||||||
data["app"] = appInfo
|
// data["app"] = appInfo
|
||||||
}
|
// }
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 更新设置
|
// @Summary 更新设置
|
||||||
@@ -786,10 +811,10 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
const CUSTOM = "custom"
|
const CUSTOM = "custom"
|
||||||
m := model.CustomizationPostData{}
|
m := model.CustomizationPostData{}
|
||||||
c.BindJSON(&m)
|
c.ShouldBind(&m)
|
||||||
|
|
||||||
if len(id) == 0 {
|
if len(id) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//var cpd model.CustomizationPostData
|
//var cpd model.CustomizationPostData
|
||||||
@@ -804,12 +829,11 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
service.MyService.Docker().DockerContainerStop(id)
|
service.MyService.Docker().DockerContainerStop(id)
|
||||||
portMap, _ := strconv.Atoi(m.PortMap)
|
portMap, _ := strconv.Atoi(m.PortMap)
|
||||||
if !port2.IsPortAvailable(portMap, "tcp") {
|
if !port2.IsPortAvailable(portMap, "tcp") {
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + m.PortMap})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + m.PortMap})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,28 +843,28 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
t, _ := strconv.Atoi(u.CommendPort)
|
t, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(t, "udp") {
|
if !port2.IsPortAvailable(t, "udp") {
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if u.Protocol == "tcp" {
|
} else if u.Protocol == "tcp" {
|
||||||
te, _ := strconv.Atoi(u.CommendPort)
|
te, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(te, "tcp") {
|
if !port2.IsPortAvailable(te, "tcp") {
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if u.Protocol == "both" {
|
} else if u.Protocol == "both" {
|
||||||
t, _ := strconv.Atoi(u.CommendPort)
|
t, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(t, "udp") {
|
if !port2.IsPortAvailable(t, "udp") {
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
te, _ := strconv.Atoi(u.CommendPort)
|
te, _ := strconv.Atoi(u.CommendPort)
|
||||||
if !port2.IsPortAvailable(te, "tcp") {
|
if !port2.IsPortAvailable(te, "tcp") {
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: "Duplicate port:" + u.CommendPort})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: "Duplicate port:" + u.CommendPort})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -849,11 +873,11 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
service.MyService.Docker().DockerContainerUpdateName(id, id)
|
service.MyService.Docker().DockerContainerUpdateName(id, id)
|
||||||
//service.MyService.Docker().DockerContainerRemove(id, true)
|
//service.MyService.Docker().DockerContainerRemove(id, true)
|
||||||
|
|
||||||
containerId, err := service.MyService.Docker().DockerContainerCreate(m.Image, m)
|
containerId, err := service.MyService.Docker().DockerContainerCreate(m, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
service.MyService.Docker().DockerContainerUpdateName(m.Label, id)
|
service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id)
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// echo -e "hellow\nworld" >>
|
// echo -e "hellow\nworld" >>
|
||||||
@@ -862,7 +886,7 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
err = service.MyService.Docker().DockerContainerStart(containerId)
|
err = service.MyService.Docker().DockerContainerStart(containerId)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.Docker().DockerContainerRemove(id, true)
|
service.MyService.Docker().DockerContainerRemove(id, true)
|
||||||
@@ -933,7 +957,7 @@ func UpdateSetting(c *gin.Context) {
|
|||||||
|
|
||||||
//service.MyService.App().UpdateApp(appInfo)
|
//service.MyService.App().UpdateApp(appInfo)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary update app version
|
// @Summary update app version
|
||||||
@@ -948,20 +972,20 @@ func PutAppUpdate(c *gin.Context) {
|
|||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
|
|
||||||
if len(id) == 0 {
|
if len(id) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
inspect, err := service.MyService.Docker().DockerContainerInfo(id)
|
inspect, err := service.MyService.Docker().DockerContainerInfo(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
|
|
||||||
}
|
}
|
||||||
imageLatest := strings.Split(inspect.Config.Image, ":")[0] + ":latest"
|
imageLatest := strings.Split(inspect.Config.Image, ":")[0] + ":latest"
|
||||||
err = service.MyService.Docker().DockerPullImage(imageLatest, "", "")
|
err = service.MyService.Docker().DockerPullImage(imageLatest, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -974,7 +998,7 @@ func PutAppUpdate(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id)
|
service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id)
|
||||||
service.MyService.Docker().DockerContainerStart(id)
|
service.MyService.Docker().DockerContainerStart(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,13 +1006,13 @@ func PutAppUpdate(c *gin.Context) {
|
|||||||
err = service.MyService.Docker().DockerContainerStart(containerId)
|
err = service.MyService.Docker().DockerContainerStart(containerId)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.Docker().DockerContainerRemove(id, true)
|
service.MyService.Docker().DockerContainerRemove(id, true)
|
||||||
delete(service.NewVersionApp, id)
|
delete(service.NewVersionApp, id)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取容器详情
|
// @Summary 获取容器详情
|
||||||
@@ -1001,6 +1025,8 @@ func PutAppUpdate(c *gin.Context) {
|
|||||||
// @Router /app/info/{id} [get]
|
// @Router /app/info/{id} [get]
|
||||||
func ContainerInfo(c *gin.Context) {
|
func ContainerInfo(c *gin.Context) {
|
||||||
appId := c.Param("id")
|
appId := c.Param("id")
|
||||||
|
|
||||||
|
// @tiger - 作为最佳实践,不应该直接把数据库的信息返回,来避免未来数据库结构上的迭代带来的新字段
|
||||||
appInfo := service.MyService.App().GetAppDBInfo(appId)
|
appInfo := service.MyService.App().GetAppDBInfo(appId)
|
||||||
containerInfo, _ := service.MyService.Docker().DockerContainerStats(appId)
|
containerInfo, _ := service.MyService.Docker().DockerContainerStats(appId)
|
||||||
var cpuModel = "arm"
|
var cpuModel = "arm"
|
||||||
@@ -1015,44 +1041,34 @@ func ContainerInfo(c *gin.Context) {
|
|||||||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//todo 需要自定义错误
|
//todo 需要自定义错误
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
con := struct {
|
con := struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
StartedAt string `json:"started_at"`
|
StartedAt string `json:"started_at"`
|
||||||
CPUShares int64 `json:"cpu_shares"`
|
CPUShares int64 `json:"cpu_shares"`
|
||||||
Memory int64 `json:"memory"`
|
Memory int64 `json:"total_memory"` // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段
|
||||||
Restart string `json:"restart"`
|
Restart string `json:"restart_policy"` // @tiger - 改成 restart_policy?
|
||||||
}{Status: info.State.Status, StartedAt: info.State.StartedAt, CPUShares: info.HostConfig.CPUShares, Memory: info.HostConfig.Memory >> 20, Restart: info.HostConfig.RestartPolicy.Name}
|
}{Status: info.State.Status, StartedAt: info.State.StartedAt, CPUShares: info.HostConfig.CPUShares, Memory: info.HostConfig.Memory >> 20, Restart: info.HostConfig.RestartPolicy.Name}
|
||||||
data := make(map[string]interface{}, 5)
|
data := make(map[string]interface{}, 5)
|
||||||
data["app"] = appInfo
|
data["app"] = appInfo // @tiget - 最佳实践是,返回 appid,然后具体的 app 信息由前端另行获取
|
||||||
data["cpu"] = cpuModel
|
data["cpu"] = cpuModel // @tiger - 改成 arch
|
||||||
data["memory"] = service.MyService.System().GetMemInfo()["total"]
|
data["memory"] = service.MyService.System().GetMemInfo()["total"] // @tiger - 改成 total_memory,方便以后增加 free_memory 之类的字段
|
||||||
data["container"] = json2.RawMessage(containerInfo)
|
data["container"] = json2.RawMessage(containerInfo)
|
||||||
data["info"] = con
|
data["info"] = con
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取安装所需要的数据
|
func GetDockerNetworks(c *gin.Context) {
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags app
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /app/install/config [get]
|
|
||||||
func GetDockerInstallConfig(c *gin.Context) {
|
|
||||||
networks := service.MyService.Docker().DockerNetworkModelList()
|
networks := service.MyService.Docker().DockerNetworkModelList()
|
||||||
data := make(map[string]interface{}, 2)
|
|
||||||
list := []map[string]string{}
|
list := []map[string]string{}
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
if network.Driver != "null" {
|
if network.Driver != "null" {
|
||||||
list = append(list, map[string]string{"name": network.Name, "driver": network.Driver, "id": network.ID})
|
list = append(list, map[string]string{"name": network.Name, "driver": network.Driver, "id": network.ID})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data["networks"] = list
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
||||||
data["memory"] = service.MyService.System().GetMemInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取依赖数据
|
// @Summary 获取依赖数据
|
||||||
@@ -1069,7 +1085,6 @@ func ContainerRelyInfo(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: appInfo})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: appInfo})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取可更新数据
|
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags app
|
// @Tags app
|
||||||
@@ -1083,7 +1098,7 @@ func ContainerUpdateInfo(c *gin.Context) {
|
|||||||
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
info, err := service.MyService.Docker().DockerContainerInfo(appId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var port model.PortArray
|
var port model.PortArray
|
||||||
@@ -1105,13 +1120,13 @@ func ContainerUpdateInfo(c *gin.Context) {
|
|||||||
showENV := info.Config.Labels["show_env"]
|
showENV := info.Config.Labels["show_env"]
|
||||||
showENVList := strings.Split(showENV, ",")
|
showENVList := strings.Split(showENV, ",")
|
||||||
showENVMap := make(map[string]string)
|
showENVMap := make(map[string]string)
|
||||||
if len(showENVList) > 1 {
|
if len(showENVList) > 0 {
|
||||||
for _, name := range showENVList {
|
for _, name := range showENVList {
|
||||||
showENVMap[name] = "1"
|
showENVMap[name] = "1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, v := range info.Config.Env {
|
for _, v := range info.Config.Env {
|
||||||
if len(showENVList) > 1 {
|
if len(showENVList) > 0 {
|
||||||
if _, ok := showENVMap[strings.Split(v, "=")[0]]; ok {
|
if _, ok := showENVMap[strings.Split(v, "=")[0]]; ok {
|
||||||
temp := model.Env{
|
temp := model.Env{
|
||||||
Name: strings.Split(v, "=")[0],
|
Name: strings.Split(v, "=")[0],
|
||||||
@@ -1161,7 +1176,7 @@ func ContainerUpdateInfo(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
m.NetworkModel = string(info.HostConfig.NetworkMode)
|
m.NetworkModel = string(info.HostConfig.NetworkMode)
|
||||||
m.Description = info.Config.Labels["desc"]
|
m.Description = info.Config.Labels["desc"]
|
||||||
m.Label = strings.ReplaceAll(info.Name, "/", "")
|
m.ContainerName = strings.ReplaceAll(info.Name, "/", "")
|
||||||
m.PortMap = info.Config.Labels["web"]
|
m.PortMap = info.Config.Labels["web"]
|
||||||
m.Devices = driver
|
m.Devices = driver
|
||||||
m.Envs = envs
|
m.Envs = envs
|
||||||
@@ -1181,6 +1196,11 @@ func ContainerUpdateInfo(c *gin.Context) {
|
|||||||
m.Cmd = info.Config.Cmd
|
m.Cmd = info.Config.Cmd
|
||||||
m.HostName = info.Config.Hostname
|
m.HostName = info.Config.Hostname
|
||||||
m.Privileged = info.HostConfig.Privileged
|
m.Privileged = info.HostConfig.Privileged
|
||||||
|
name := info.Config.Labels["name"]
|
||||||
|
if len(name) == 0 {
|
||||||
|
name = strings.ReplaceAll(info.Name, "/", "")
|
||||||
|
}
|
||||||
|
m.Label = name
|
||||||
|
|
||||||
m.Protocol = info.Config.Labels["protocol"]
|
m.Protocol = info.Config.Labels["protocol"]
|
||||||
if m.Protocol == "" {
|
if m.Protocol == "" {
|
||||||
|
|||||||
154
route/v1/file.go
@@ -1,8 +1,6 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"encoding/csv"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -26,32 +24,6 @@ import (
|
|||||||
uuid "github.com/satori/go.uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func downloadReadFile(c *gin.Context) {
|
|
||||||
//http下载地址 csv
|
|
||||||
csvFileUrl := c.PostForm("file_name")
|
|
||||||
res, err := http.Get(csvFileUrl)
|
|
||||||
if err != nil {
|
|
||||||
c.String(400, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
//读取csv
|
|
||||||
reader := csv.NewReader(bufio.NewReader(res.Body))
|
|
||||||
for {
|
|
||||||
line, err := reader.Read()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
c.String(400, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//line 就是每一行的内容
|
|
||||||
fmt.Println(line)
|
|
||||||
//line[0] 就是第几列
|
|
||||||
fmt.Println(line[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 读取文件
|
// @Summary 读取文件
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -63,14 +35,14 @@ func downloadReadFile(c *gin.Context) {
|
|||||||
func GetFilerContent(c *gin.Context) {
|
func GetFilerContent(c *gin.Context) {
|
||||||
filePath := c.Query("path")
|
filePath := c.Query("path")
|
||||||
if len(filePath) == 0 {
|
if len(filePath) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||||
Success: common_err.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.Exists(filePath) {
|
if !file.Exists(filePath) {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
})
|
})
|
||||||
@@ -79,7 +51,7 @@ func GetFilerContent(c *gin.Context) {
|
|||||||
//文件读取任务是将文件内容读取到内存中。
|
//文件读取任务是将文件内容读取到内存中。
|
||||||
info, err := ioutil.ReadFile(filePath)
|
info, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
Success: common_err.FILE_READ_ERROR,
|
Success: common_err.FILE_READ_ERROR,
|
||||||
Message: common_err.GetMsg(common_err.FILE_READ_ERROR),
|
Message: common_err.GetMsg(common_err.FILE_READ_ERROR),
|
||||||
Data: err.Error(),
|
Data: err.Error(),
|
||||||
@@ -88,8 +60,7 @@ func GetFilerContent(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
result := string(info)
|
result := string(info)
|
||||||
|
|
||||||
//返回结果
|
c.JSON(common_err.SUCCESS, model.Result{
|
||||||
c.JSON(http.StatusOK, model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: result,
|
Data: result,
|
||||||
@@ -121,18 +92,18 @@ func GetLocalFile(c *gin.Context) {
|
|||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
// @Tags file
|
// @Tags file
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param t query string false "Compression format" Enums(zip,tar,targz)
|
// @Param format query string false "Compression format" Enums(zip,tar,targz)
|
||||||
// @Param files query string true "file list eg: filename1,filename2,filename3 "
|
// @Param files query string true "file list eg: filename1,filename2,filename3 "
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /file/download [get]
|
// @Router /file/download [get]
|
||||||
func GetDownloadFile(c *gin.Context) {
|
func GetDownloadFile(c *gin.Context) {
|
||||||
|
|
||||||
t := c.Query("t")
|
t := c.Query("format")
|
||||||
|
|
||||||
files := c.Query("files")
|
files := c.Query("files")
|
||||||
|
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||||
Success: common_err.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
@@ -141,7 +112,7 @@ func GetDownloadFile(c *gin.Context) {
|
|||||||
list := strings.Split(files, ",")
|
list := strings.Split(files, ",")
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
if !file.Exists(v) {
|
if !file.Exists(v) {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
Success: common_err.FILE_DOES_NOT_EXIST,
|
Success: common_err.FILE_DOES_NOT_EXIST,
|
||||||
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
|
||||||
})
|
})
|
||||||
@@ -179,7 +150,7 @@ func GetDownloadFile(c *gin.Context) {
|
|||||||
|
|
||||||
extension, ar, err := file.GetCompressionAlgorithm(t)
|
extension, ar, err := file.GetCompressionAlgorithm(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.CLIENT_ERROR, model.Result{
|
||||||
Success: common_err.INVALID_PARAMS,
|
Success: common_err.INVALID_PARAMS,
|
||||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
@@ -188,9 +159,9 @@ func GetDownloadFile(c *gin.Context) {
|
|||||||
|
|
||||||
err = ar.Create(c.Writer)
|
err = ar.Create(c.Writer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{
|
c.JSON(common_err.SERVICE_ERROR, model.Result{
|
||||||
Success: common_err.ERROR,
|
Success: common_err.SERVICE_ERROR,
|
||||||
Message: common_err.GetMsg(common_err.ERROR),
|
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
|
||||||
Data: err.Error(),
|
Data: err.Error(),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -213,8 +184,22 @@ func GetDownloadFile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetDownloadSingleFile(c *gin.Context) {
|
func GetDownloadSingleFile(c *gin.Context) {
|
||||||
filePath := c.Param("path")
|
filePath := c.Query("path")
|
||||||
fileTmp, _ := os.Open(filePath)
|
if len(filePath) == 0 {
|
||||||
|
c.JSON(service.ClientCount, model.Result{
|
||||||
|
Success: common_err.INVALID_PARAMS,
|
||||||
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileTmp, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
c.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()
|
defer fileTmp.Close()
|
||||||
|
|
||||||
fileName := path.Base(filePath)
|
fileName := path.Base(filePath)
|
||||||
@@ -234,6 +219,11 @@ func GetDownloadSingleFile(c *gin.Context) {
|
|||||||
func DirPath(c *gin.Context) {
|
func DirPath(c *gin.Context) {
|
||||||
path := c.DefaultQuery("path", "")
|
path := c.DefaultQuery("path", "")
|
||||||
info := service.MyService.System().GetDirPath(path)
|
info := service.MyService.System().GetDirPath(path)
|
||||||
|
shares := service.MyService.Shares().GetSharesList()
|
||||||
|
sharesMap := make(map[string]string)
|
||||||
|
for _, v := range shares {
|
||||||
|
sharesMap[v.Path] = fmt.Sprint(v.ID)
|
||||||
|
}
|
||||||
if path == "/DATA/AppData" {
|
if path == "/DATA/AppData" {
|
||||||
list := service.MyService.Docker().DockerContainerList()
|
list := service.MyService.Docker().DockerContainerList()
|
||||||
apps := make(map[string]string, len(list))
|
apps := make(map[string]string, len(list))
|
||||||
@@ -273,7 +263,17 @@ func DirPath(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(info); i++ {
|
||||||
|
if v, ok := sharesMap[info[i].Path]; ok {
|
||||||
|
ex := make(map[string]interface{})
|
||||||
|
|
||||||
|
shareEx := make(map[string]string)
|
||||||
|
shareEx["shared"] = "true"
|
||||||
|
shareEx["id"] = v
|
||||||
|
ex["share"] = shareEx
|
||||||
|
info[i].Extensions = ex
|
||||||
|
}
|
||||||
|
}
|
||||||
//Hide the files or folders in operation
|
//Hide the files or folders in operation
|
||||||
fileQueue := make(map[string]string)
|
fileQueue := make(map[string]string)
|
||||||
if len(service.OpStrArr) > 0 {
|
if len(service.OpStrArr) > 0 {
|
||||||
@@ -297,7 +297,7 @@ func DirPath(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: pathList})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: pathList})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary rename file or dir
|
// @Summary rename file or dir
|
||||||
@@ -311,15 +311,15 @@ func DirPath(c *gin.Context) {
|
|||||||
// @Router /file/rename [put]
|
// @Router /file/rename [put]
|
||||||
func RenamePath(c *gin.Context) {
|
func RenamePath(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
op := json["oldpath"]
|
op := json["old_path"]
|
||||||
np := json["newpath"]
|
np := json["new_path"]
|
||||||
if len(op) == 0 || len(np) == 0 {
|
if len(op) == 0 || len(np) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
success, err := service.MyService.System().RenameFile(op, np)
|
success, err := service.MyService.System().RenameFile(op, np)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
|
c.JSON(common_err.SUCCESS, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary create folder
|
// @Summary create folder
|
||||||
@@ -332,11 +332,11 @@ func RenamePath(c *gin.Context) {
|
|||||||
// @Router /file/mkdir [post]
|
// @Router /file/mkdir [post]
|
||||||
func MkdirAll(c *gin.Context) {
|
func MkdirAll(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
path := json["path"]
|
path := json["path"]
|
||||||
var code int
|
var code int
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// decodedPath, err := url.QueryUnescape(path)
|
// decodedPath, err := url.QueryUnescape(path)
|
||||||
@@ -345,7 +345,7 @@ func MkdirAll(c *gin.Context) {
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
code, _ = service.MyService.System().MkdirAll(path)
|
code, _ = service.MyService.System().MkdirAll(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary create file
|
// @Summary create file
|
||||||
@@ -358,11 +358,11 @@ func MkdirAll(c *gin.Context) {
|
|||||||
// @Router /file/create [post]
|
// @Router /file/create [post]
|
||||||
func PostCreateFile(c *gin.Context) {
|
func PostCreateFile(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
path := json["path"]
|
path := json["path"]
|
||||||
var code int
|
var code int
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// decodedPath, err := url.QueryUnescape(path)
|
// decodedPath, err := url.QueryUnescape(path)
|
||||||
@@ -371,7 +371,7 @@ func PostCreateFile(c *gin.Context) {
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
code, _ = service.MyService.System().CreateFile(path)
|
code, _ = service.MyService.System().CreateFile(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: code, Message: common_err.GetMsg(code)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary upload file
|
// @Summary upload file
|
||||||
@@ -452,7 +452,7 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
defer out.Close()
|
defer out.Close()
|
||||||
_, err := io.Copy(out, f)
|
_, err := io.Copy(out, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -460,7 +460,7 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
defer out.Close()
|
defer out.Close()
|
||||||
_, err := io.Copy(out, f)
|
_, err := io.Copy(out, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
@@ -468,7 +468,7 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
fileNum, err := ioutil.ReadDir(tempDir)
|
fileNum, err := ioutil.ReadDir(tempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
if totalChunks == len(fileNum) {
|
if totalChunks == len(fileNum) {
|
||||||
@@ -476,7 +476,7 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
file.RMDir(tempDir)
|
file.RMDir(tempDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary copy or move file
|
// @Summary copy or move file
|
||||||
@@ -490,14 +490,14 @@ func PostFileUpload(c *gin.Context) {
|
|||||||
func PostOperateFileOrDir(c *gin.Context) {
|
func PostOperateFileOrDir(c *gin.Context) {
|
||||||
|
|
||||||
list := model.FileOperate{}
|
list := model.FileOperate{}
|
||||||
c.BindJSON(&list)
|
c.ShouldBind(&list)
|
||||||
|
|
||||||
if len(list.Item) == 0 {
|
if len(list.Item) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] {
|
if list.To == list.Item[0].From[:strings.LastIndex(list.Item[0].From, "/")] {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SOURCE_DES_SAME, Message: common_err.GetMsg(common_err.SOURCE_DES_SAME)})
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +526,7 @@ func PostOperateFileOrDir(c *gin.Context) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary delete file
|
// @Summary delete file
|
||||||
@@ -540,9 +540,9 @@ func PostOperateFileOrDir(c *gin.Context) {
|
|||||||
func DeleteFile(c *gin.Context) {
|
func DeleteFile(c *gin.Context) {
|
||||||
|
|
||||||
paths := []string{}
|
paths := []string{}
|
||||||
c.BindJSON(&paths)
|
c.ShouldBind(&paths)
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// path := c.Query("path")
|
// path := c.Query("path")
|
||||||
@@ -552,12 +552,12 @@ func DeleteFile(c *gin.Context) {
|
|||||||
for _, v := range paths {
|
for _, v := range paths {
|
||||||
err := os.RemoveAll(v)
|
err := os.RemoveAll(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary update file
|
// @Summary update file
|
||||||
@@ -572,26 +572,26 @@ func DeleteFile(c *gin.Context) {
|
|||||||
func PutFileContent(c *gin.Context) {
|
func PutFileContent(c *gin.Context) {
|
||||||
|
|
||||||
fi := model.FileUpdate{}
|
fi := model.FileUpdate{}
|
||||||
c.BindJSON(&fi)
|
c.ShouldBind(&fi)
|
||||||
|
|
||||||
// path := c.PostForm("path")
|
// path := c.PostForm("path")
|
||||||
// content := c.PostForm("content")
|
// content := c.PostForm("content")
|
||||||
if !file.Exists(fi.FilePath) {
|
if !file.Exists(fi.FilePath) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
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
|
||||||
}
|
}
|
||||||
//err := os.Remove(path)
|
//err := os.Remove(path)
|
||||||
err := os.RemoveAll(fi.FilePath)
|
err := os.RemoveAll(fi.FilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err})
|
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
|
||||||
}
|
}
|
||||||
err = file.CreateFileAndWriteContent(fi.FilePath, fi.FileContent)
|
err = file.CreateFileAndWriteContent(fi.FilePath, fi.FileContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: 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
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary image thumbnail/original image
|
// @Summary image thumbnail/original image
|
||||||
@@ -607,13 +607,13 @@ func GetFileImage(c *gin.Context) {
|
|||||||
t := c.Query("type")
|
t := c.Query("type")
|
||||||
path := c.Query("path")
|
path := c.Query("path")
|
||||||
if !file.Exists(path) {
|
if !file.Exists(path) {
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
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
|
||||||
}
|
}
|
||||||
if t == "thumbnail" {
|
if t == "thumbnail" {
|
||||||
f, err := file.GetImage(path, 100, 0)
|
f, err := file.GetImage(path, 100, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
c.Writer.WriteString(string(f))
|
c.Writer.WriteString(string(f))
|
||||||
@@ -621,13 +621,13 @@ func GetFileImage(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
data, err := ioutil.ReadAll(f)
|
data, err := ioutil.ReadAll(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
||||||
}
|
}
|
||||||
c.Writer.WriteString(string(data))
|
c.Writer.WriteString(string(data))
|
||||||
@@ -652,5 +652,5 @@ func DeleteOperateFileOrDir(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
go service.MyService.Notify().SendFileOperateNotify(true)
|
go service.MyService.Notify().SendFileOperateNotify(true)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,804 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/gob"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
natType "github.com/Curtis-Milo/nat-type-identifier-go"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"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/IceWhaleTech/CasaOS/types"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
uuid "github.com/satori/go.uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary Retry the file that failed to download
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param uui path string true "download uuid"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/refile/{uuid} [get]
|
|
||||||
func GetPersonReFile(c *gin.Context) {
|
|
||||||
|
|
||||||
uid := c.Param("uuid")
|
|
||||||
_, err := uuid.FromString(uid)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
task := service.MyService.Download().GetDownloadById(uid)
|
|
||||||
if reflect.DeepEqual(task, model2.PersonDownloadDBModel{}) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
token := task.From
|
|
||||||
if _, ok := service.UDPAddressMap[token]; !ok {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = task.Path
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONDOWNLOAD
|
|
||||||
m.UUId = uid
|
|
||||||
go service.Dial(m, false)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary download file
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param share_id query string true "opponent share_id"
|
|
||||||
// @Param path query string true "file path"
|
|
||||||
// @Param file_name query string true "file name"
|
|
||||||
// @Param local_path query string true "local_path"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/file [get]
|
|
||||||
func GetPersonFile(c *gin.Context) {
|
|
||||||
|
|
||||||
path := c.Query("path")
|
|
||||||
localPath := c.Query("local_path")
|
|
||||||
token := c.Query("share_id")
|
|
||||||
fileName := c.Query("file_name")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if len(path) == 0 || err != nil || len(localPath) == 0 || len(fileName) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if file.CheckNotExist(localPath) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := service.UDPAddressMap[token]; !ok {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := service.UDPAddressMap[token]; !ok {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// task id
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
|
|
||||||
task := model2.PersonDownloadDBModel{}
|
|
||||||
task.UUID = uuid
|
|
||||||
task.Name = fileName
|
|
||||||
task.Length = 0
|
|
||||||
task.From = token
|
|
||||||
task.Path = path
|
|
||||||
task.Size = 0
|
|
||||||
task.State = types.DOWNLOADAWAIT
|
|
||||||
task.Created = time.Now().Unix()
|
|
||||||
task.Type = types.PERSONFILEDOWNLOAD
|
|
||||||
task.LocalPath = localPath
|
|
||||||
if service.MyService.Download().GetDownloadListByPath(task) > 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
service.MyService.Download().AddDownloadTask(task)
|
|
||||||
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = path
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONDOWNLOAD
|
|
||||||
m.UUId = uuid
|
|
||||||
go service.Dial(m, false)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary delete download file records
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param uuid path string true "download uuid"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/file/{uuid} [delete]
|
|
||||||
func DeletePersonDownloadFile(c *gin.Context) {
|
|
||||||
|
|
||||||
id := c.Param("uuid")
|
|
||||||
_, err := uuid.FromString(id)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
task := service.MyService.Download().GetDownloadById(id)
|
|
||||||
if task.State == types.DOWNLOADING {
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = ""
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = task.From
|
|
||||||
m.Type = types.PERSONCANCEL
|
|
||||||
m.UUId = task.UUID
|
|
||||||
service.CancelList[task.UUID] = task.UUID
|
|
||||||
service.Dial(m, false)
|
|
||||||
}
|
|
||||||
service.MyService.Download().DelDownload(id)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get file download list
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param state query int false "wait:0,downloading:1,pause:2,finish:3,error:4,finished:5" Enums(0,1,2,3,4,5)
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {object} []model2.PersonDownloadDBModel
|
|
||||||
// @Router /person/list [get]
|
|
||||||
func GetPersonDownloadList(c *gin.Context) {
|
|
||||||
state := c.DefaultQuery("state", "")
|
|
||||||
list := service.MyService.Download().GetDownloadListByState(state, types.PERSONFILEDOWNLOAD)
|
|
||||||
//if it is downloading, it need to add 'already'
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
if list[i].State == types.DOWNLOADING {
|
|
||||||
tempDir := config.AppInfo.TempPath + "/" + list[i].UUID
|
|
||||||
files, err := ioutil.ReadDir(tempDir)
|
|
||||||
if err == nil {
|
|
||||||
list[i].Already = len(files)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list[i].Duration = time.Now().Unix() - list[i].Created
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary edit friend's remarks
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param remarks formData string true "remarks name"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/remarks/{shareid} [put]
|
|
||||||
func PutPersonRemarks(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
mark := c.PostForm("remarks")
|
|
||||||
if err != nil || len(mark) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = token
|
|
||||||
friend.Mark = mark
|
|
||||||
service.MyService.Friend().EditFriendMark(friend)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary edit friend's
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param write formData bool true "write"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/write/{shareid} [put]
|
|
||||||
func PutPersonWrite(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
write, _ := strconv.ParseBool(c.PostForm("write"))
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = token
|
|
||||||
friend.Write = write
|
|
||||||
service.MyService.Friend().EditFriendMark(friend)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary image thumbnail
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param write formData bool true "write"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/image/thumbnail/{shareid} [get]
|
|
||||||
func GetPersonImageThumbnail(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
path := c.Query("path")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if err != nil || len(path) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = path
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONIMAGETHUMBNAIL
|
|
||||||
m.UUId = uuid
|
|
||||||
|
|
||||||
img, err := service.Dial(m, false)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// var buf bytes.Buffer
|
|
||||||
//err = gob.NewEncoder(&buf).Encode(img.Data)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err = gob.NewEncoder(&buf).Encode(img.Data)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string))
|
|
||||||
c.Writer.WriteString(string(imageBuffer))
|
|
||||||
// c.String(http.StatusOK, "data:image/"+filesuffix+";base64,"+img.Data.(string))
|
|
||||||
//c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: img.Data.(string)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary get my friend list
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {object} []model2.FriendModel
|
|
||||||
// @Router /person/users [get]
|
|
||||||
func GetPersonFriend(c *gin.Context) {
|
|
||||||
list := service.MyService.Friend().GetFriendList()
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 {
|
|
||||||
list[i].OnLine = true
|
|
||||||
if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
|
|
||||||
list[i].LocalIP = strings.Split(v, ":")[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary network type detection
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/detection [get]
|
|
||||||
func GetPersonDetection(c *gin.Context) {
|
|
||||||
// - Blocked
|
|
||||||
// - Open Internet
|
|
||||||
// - Full Cone
|
|
||||||
// - Symmetric UDP Firewall
|
|
||||||
// - Restric NAT
|
|
||||||
// - Restric Port NAT
|
|
||||||
// - Symmetric NAT
|
|
||||||
|
|
||||||
result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com")
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//result := service.MyService.Person().GetPersionNetWorkTypeDetection()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary add friend
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/user/{shareids} [post]
|
|
||||||
func PostAddPersonFriend(c *gin.Context) {
|
|
||||||
token := c.Param("shareids")
|
|
||||||
tokenList := strings.Split(token, ",")
|
|
||||||
|
|
||||||
for _, v := range tokenList {
|
|
||||||
_, err := uuid.FromString(v)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v == config.ServerInfo.Token {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_MYSELF, Message: common_err.GetMsg(common_err.PERSON_MYSELF)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
udb := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: v})
|
|
||||||
if !reflect.DeepEqual(udb, model2.FriendModel{Token: v}) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_FRIEND, Message: common_err.GetMsg(common_err.PERSON_EXIST_FRIEND)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
user := service.MyService.Casa().GetUserInfoByShareId(v)
|
|
||||||
if reflect.DeepEqual(user, model.UserInfo{}) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_NOT_EXIST_USER, Message: common_err.GetMsg(common_err.PERSON_NOT_EXIST_USER)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
message := model.MessageModel{}
|
|
||||||
message.Type = types.PERSONCONNECTION
|
|
||||||
message.Data = v
|
|
||||||
message.From = config.ServerInfo.Token
|
|
||||||
message.To = v
|
|
||||||
message.UUId = uuid.NewV4().String()
|
|
||||||
|
|
||||||
go service.Dial(message, true)
|
|
||||||
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONGETIP
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = v
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
|
|
||||||
service.Dial(msg, true)
|
|
||||||
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = v
|
|
||||||
friend.Avatar = user.Avatar
|
|
||||||
friend.Block = false
|
|
||||||
friend.State = types.FRIENDSTATEWAIT
|
|
||||||
friend.NickName = user.NickName
|
|
||||||
friend.Profile = user.Desc
|
|
||||||
friend.Version = user.Version
|
|
||||||
service.MyService.Friend().AddFriend(friend)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get a list of directories
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param share_id query string true "Opponent share_id"
|
|
||||||
// @Param path query string true "dir path"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {object} []model.Path
|
|
||||||
// @Router /person/directory [get]
|
|
||||||
func GetPersonDirectory(c *gin.Context) {
|
|
||||||
path := c.Query("path")
|
|
||||||
token := c.Query("share_id")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if len(path) == 0 || err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := service.UDPAddressMap[token]; !ok {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = path
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONDIRECTORY
|
|
||||||
m.UUId = uuid
|
|
||||||
result, err := service.Dial(m, false)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dataModel := []model.Path{}
|
|
||||||
if uuid == m.UUId {
|
|
||||||
dataModelByte, _ := json.Marshal(result.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &dataModel)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: dataModel})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Modify the download storage directory
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param path formData string true "path"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/down/dir [post]
|
|
||||||
func PostPersonDownDir(c *gin.Context) {
|
|
||||||
|
|
||||||
downPath := c.PostForm("path")
|
|
||||||
|
|
||||||
if len(downPath) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if file.CheckNotExist(downPath) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
config.Cfg.Section("file").Key("DownloadDir").SetValue(downPath)
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
config.FileSettingInfo.DownloadDir = downPath
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get the download storage directory
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/down/dir [get]
|
|
||||||
func GetPersonDownDir(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.DownloadDir})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Modify the shared directory
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param share formData string true "share"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/share [post]
|
|
||||||
func PostPersonShare(c *gin.Context) {
|
|
||||||
|
|
||||||
share := c.PostForm("share")
|
|
||||||
|
|
||||||
if len(share) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var list []string
|
|
||||||
json.Unmarshal([]byte(share), &list)
|
|
||||||
|
|
||||||
if len(list) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, v := range list {
|
|
||||||
if !file.Exists(v) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Cfg.Section("file").Key("ShareDir").SetValue(strings.Join(list, "|"))
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
config.FileSettingInfo.ShareDir = list
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get the shared directory
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/share [get]
|
|
||||||
func GetPersonShare(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.ShareDir})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get the shareid
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/shareid [get]
|
|
||||||
func GetPersonShareId(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Modify disabled status
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Param block formData bool false "Disable or not,Default:false "
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/block/{shareid} [put]
|
|
||||||
func PutPersonBlock(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
block, _ := strconv.ParseBool(c.PostForm("block"))
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = token
|
|
||||||
friend.Block = block
|
|
||||||
service.MyService.Friend().EditFriendBlock(friend)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Delete my friend
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/user/{shareid} [delete]
|
|
||||||
func DeletePersonFriend(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = token
|
|
||||||
|
|
||||||
service.MyService.Friend().DeleteFriend(friend)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary Get public person
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/public [get]
|
|
||||||
func GetPersonPublic(c *gin.Context) {
|
|
||||||
list := service.MyService.Casa().GetPersonPublic()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary upload file to friend
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Param path formData string true "Destination path"
|
|
||||||
// @Param local_path formData string true "Full path of the file to be uploaded"
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/file/{shareid} [post]
|
|
||||||
func PostPersonFile(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
path := c.PostForm("path")
|
|
||||||
localPath := c.PostForm("local_path")
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !file.Exists(localPath) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = path
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONUPLOAD
|
|
||||||
m.UUId = uuid
|
|
||||||
go service.UDPSendData(m, localPath)
|
|
||||||
|
|
||||||
f, _ := os.Stat(localPath)
|
|
||||||
|
|
||||||
task := model2.PersonDownloadDBModel{}
|
|
||||||
task.UUID = uuid
|
|
||||||
task.Name = f.Name()
|
|
||||||
task.Length = 0
|
|
||||||
task.From = token
|
|
||||||
task.Path = path
|
|
||||||
task.Size = f.Size()
|
|
||||||
task.State = types.DOWNLOADFINISHED
|
|
||||||
task.Created = time.Now().Unix()
|
|
||||||
task.Type = types.PERSONFILEUPLOAD
|
|
||||||
task.LocalPath = localPath
|
|
||||||
if service.MyService.Download().GetDownloadListByPath(task) > 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
service.MyService.Download().AddDownloadTask(task)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary agree add friend
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags person
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /person/friend/{shareid} [put]
|
|
||||||
func PutPersonAgreeFriend(c *gin.Context) {
|
|
||||||
token := c.Param("shareid")
|
|
||||||
_, err := uuid.FromString(token)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
user := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: token})
|
|
||||||
|
|
||||||
if user.State != types.FRIENDSTATEREQUEST {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.COMMAND_ERROR_INVALID_OPERATION, Message: common_err.GetMsg(common_err.COMMAND_ERROR_INVALID_OPERATION)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
service.MyService.Friend().AgreeFrined(user.Token)
|
|
||||||
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = ""
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = token
|
|
||||||
m.Type = types.PERSONAGREEFRIEND
|
|
||||||
m.UUId = uuid
|
|
||||||
go service.Dial(m, true)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// // @Summary upload file
|
|
||||||
// // @Produce application/json
|
|
||||||
// // @Accept multipart/form-data
|
|
||||||
// // @Tags person
|
|
||||||
// // @Security ApiKeyAuth
|
|
||||||
// // @Param path formData string false "file path"
|
|
||||||
// // @Param file formData file true "file"
|
|
||||||
// // @Success 200 {string} string "ok"
|
|
||||||
// // @Router /person/upload/{shareid} [get]
|
|
||||||
// func GetPersonFileUpload(c *gin.Context) {
|
|
||||||
|
|
||||||
// token := c.Param("shareid")
|
|
||||||
// _, err := uuid.FromString(token)
|
|
||||||
// path := c.Query("path")
|
|
||||||
// if err != nil {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// relative := c.Query("relativePath")
|
|
||||||
// fileName := c.Query("filename")
|
|
||||||
// chunkNumber := c.Query("chunkNumber")
|
|
||||||
// totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0"))
|
|
||||||
// dirPath := ""
|
|
||||||
// hash := file.GetHashByContent([]byte(fileName))
|
|
||||||
// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/"
|
|
||||||
// if fileName != relative {
|
|
||||||
// dirPath = strings.TrimSuffix(relative, fileName)
|
|
||||||
// tempDir += dirPath
|
|
||||||
// file.MkDir(path + "/" + dirPath)
|
|
||||||
// }
|
|
||||||
// tempDir += chunkNumber
|
|
||||||
// if !file.CheckNotExist(tempDir) {
|
|
||||||
// c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // @Summary upload file
|
|
||||||
// // @Produce application/json
|
|
||||||
// // @Accept multipart/form-data
|
|
||||||
// // @Tags person
|
|
||||||
// // @Security ApiKeyAuth
|
|
||||||
// // @Param path formData string false "file path"
|
|
||||||
// // @Param file formData file true "file"
|
|
||||||
// // @Success 200 {string} string "ok"
|
|
||||||
// // @Router /person/upload [post]
|
|
||||||
// func PostPersonFileUpload(c *gin.Context) {
|
|
||||||
// token := c.Param("shareid")
|
|
||||||
// _, err := uuid.FromString(token)
|
|
||||||
// if err != nil {
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// f, _, _ := c.Request.FormFile("file")
|
|
||||||
// relative := c.PostForm("relativePath")
|
|
||||||
// fileName := c.PostForm("filename")
|
|
||||||
// totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0"))
|
|
||||||
// chunkNumber := c.PostForm("chunkNumber")
|
|
||||||
// dirPath := ""
|
|
||||||
// path := c.PostForm("path")
|
|
||||||
|
|
||||||
// hash := file.GetHashByContent([]byte(fileName))
|
|
||||||
|
|
||||||
// if len(path) == 0 {
|
|
||||||
// c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/"
|
|
||||||
|
|
||||||
// if fileName != relative {
|
|
||||||
// dirPath = strings.TrimSuffix(relative, fileName)
|
|
||||||
// tempDir += dirPath
|
|
||||||
// file.MkDir(path + "/" + dirPath)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// path += "/" + relative
|
|
||||||
|
|
||||||
// if !file.CheckNotExist(tempDir + chunkNumber) {
|
|
||||||
// file.RMDir(tempDir + chunkNumber)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if totalChunks > 1 {
|
|
||||||
// file.IsNotExistMkDir(tempDir)
|
|
||||||
|
|
||||||
// out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644)
|
|
||||||
// defer out.Close()
|
|
||||||
// _, err := io.Copy(out, f)
|
|
||||||
// if err != nil {
|
|
||||||
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
|
|
||||||
// defer out.Close()
|
|
||||||
// _, err := io.Copy(out, f)
|
|
||||||
// if err != nil {
|
|
||||||
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fileNum, err := ioutil.ReadDir(tempDir)
|
|
||||||
// if err != nil {
|
|
||||||
// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if totalChunks == len(fileNum) {
|
|
||||||
// file.RMDir(tempDir)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
// }
|
|
||||||
180
route/v1/samba.go
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-26 11:08:48
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-05 12:16:39
|
||||||
|
* @FilePath: /CasaOS/route/v1/samba.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"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/service"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// service
|
||||||
|
|
||||||
|
func GetSambaStatus(c *gin.Context) {
|
||||||
|
status := service.MyService.System().IsServiceRunning("smbd")
|
||||||
|
|
||||||
|
if !status {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_NOT_RUNNING, Message: common_err.GetMsg(common_err.SERVICE_NOT_RUNNING)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
needInit := true
|
||||||
|
if file.Exists("/etc/samba/smb.conf") {
|
||||||
|
str := file.ReadLine(1, "/etc/samba/smb.conf")
|
||||||
|
if strings.Contains(str, "# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.") {
|
||||||
|
needInit = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSambaSharesList(c *gin.Context) {
|
||||||
|
shares := service.MyService.Shares().GetSharesList()
|
||||||
|
shareList := []model.Shares{}
|
||||||
|
for _, v := range shares {
|
||||||
|
shareList = append(shareList, model.Shares{
|
||||||
|
Anonymous: v.Anonymous,
|
||||||
|
Path: v.Path,
|
||||||
|
ID: v.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList})
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostSambaSharesCreate(c *gin.Context) {
|
||||||
|
shares := []model.Shares{}
|
||||||
|
c.ShouldBindJSON(&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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range shares {
|
||||||
|
shareDBModel := model2.SharesDBModel{}
|
||||||
|
shareDBModel.Anonymous = true
|
||||||
|
shareDBModel.Path = v.Path
|
||||||
|
shareDBModel.Name = filepath.Base(v.Path)
|
||||||
|
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})
|
||||||
|
}
|
||||||
|
func DeleteSambaShares(c *gin.Context) {
|
||||||
|
id := c.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
|
||||||
|
}
|
||||||
|
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})
|
||||||
|
}
|
||||||
|
|
||||||
|
//client
|
||||||
|
|
||||||
|
func GetSambaConnectionsList(c *gin.Context) {
|
||||||
|
connections := service.MyService.Connections().GetConnectionsList()
|
||||||
|
connectionList := []model.Connections{}
|
||||||
|
for _, v := range connections {
|
||||||
|
connectionList = append(connectionList, model.Connections{
|
||||||
|
ID: v.ID,
|
||||||
|
Username: v.Username,
|
||||||
|
Port: v.Port,
|
||||||
|
Host: v.Host,
|
||||||
|
MountPoint: v.MountPoint,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostSambaConnectionsCreate(c *gin.Context) {
|
||||||
|
connection := model.Connections{}
|
||||||
|
c.ShouldBindJSON(&connection)
|
||||||
|
if connection.Port == "" {
|
||||||
|
connection.Port = "445"
|
||||||
|
}
|
||||||
|
if connection.Username == "" || connection.Host == "" {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionDBModel := model2.ConnectionsDBModel{}
|
||||||
|
connectionDBModel.Username = connection.Username
|
||||||
|
connectionDBModel.Password = connection.Password
|
||||||
|
connectionDBModel.Host = connection.Host
|
||||||
|
connectionDBModel.Port = connection.Port
|
||||||
|
connectionDBModel.Directories = strings.Join(directories, ",")
|
||||||
|
baseHostPath := "/mnt/" + connection.Host
|
||||||
|
connectionDBModel.MountPoint = baseHostPath
|
||||||
|
connection.MountPoint = baseHostPath
|
||||||
|
file.IsNotExistMkDir(baseHostPath)
|
||||||
|
for _, v := range directories {
|
||||||
|
mountPoint := baseHostPath + "/" + v
|
||||||
|
file.IsNotExistMkDir(mountPoint)
|
||||||
|
service.MyService.Connections().MountSmaba(connectionDBModel.Username, connectionDBModel.Host, v, connectionDBModel.Port, mountPoint, connectionDBModel.Password)
|
||||||
|
}
|
||||||
|
|
||||||
|
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})
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteSambaConnections(c *gin.Context) {
|
||||||
|
id := c.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
|
||||||
|
}
|
||||||
|
mountPointList := service.MyService.System().GetDirPath(connection.MountPoint)
|
||||||
|
for _, v := range mountPointList {
|
||||||
|
service.MyService.Connections().UnmountSmaba(v.Path)
|
||||||
|
}
|
||||||
|
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})
|
||||||
|
}
|
||||||
73
route/v1/samba_test.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-08-02 15:10:56
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-02 16:58:42
|
||||||
|
* @FilePath: /CasaOS/route/v1/samba_test.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
|
||||||
|
req, _ := http.NewRequest(method, path, nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
r.ServeHTTP(w, req)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// func TestHelloWorld(t *testing.T) {
|
||||||
|
// // Build our expected body
|
||||||
|
// body := gin.H{
|
||||||
|
// "hello": "world",
|
||||||
|
// }
|
||||||
|
// // Grab our router
|
||||||
|
// router := "SetupRouter()"
|
||||||
|
// // Perform a GET request with that handler.
|
||||||
|
// w := performRequest(router, "GET", "/")
|
||||||
|
// // Assert we encoded correctly,
|
||||||
|
// // the request gives a 200
|
||||||
|
// assert.Equal(t, http.StatusOK, w.Code)
|
||||||
|
// // Convert the JSON response to a map
|
||||||
|
// var response map[string]string
|
||||||
|
// err := json.Unmarshal([]byte(w.Body.String()), &response)
|
||||||
|
// // Grab the value & whether or not it exists
|
||||||
|
// value, exists := response["hello"]
|
||||||
|
// // Make some assertions on the correctness of the response.
|
||||||
|
// assert.Nil(t, err)
|
||||||
|
// assert.True(t, exists)
|
||||||
|
// assert.Equal(t, body["hello"], value)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func TestGetSambaSharesList(t *testing.T) {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
executeWithContext := func() *httptest.ResponseRecorder {
|
||||||
|
response := httptest.NewRecorder()
|
||||||
|
con, ginEngine := gin.CreateTestContext(response)
|
||||||
|
|
||||||
|
requestUrl := "/v1/samba/shares"
|
||||||
|
httpRequest, _ := http.NewRequest("GET", requestUrl, nil)
|
||||||
|
GetSambaSharesList(con)
|
||||||
|
ginEngine.ServeHTTP(response, httpRequest)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Happy", func(t *testing.T) {
|
||||||
|
res := executeWithContext()
|
||||||
|
assert.Equal(t, http.StatusOK, res.Code)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2021-09-30 18:18:14
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-06-15 14:30:05
|
|
||||||
* @FilePath: /CasaOS/route/v1/shortcuts.go
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Summary 获取短链列表
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags shortcuts
|
|
||||||
// @Param username formData string true "User name"
|
|
||||||
// @Param pwd formData string true "password"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /shortcuts/list [get]
|
|
||||||
func GetShortcutsList(c *gin.Context) {
|
|
||||||
list := service.MyService.Shortcuts().GetList()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 添加shortcuts
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags shortcuts
|
|
||||||
// @Param title formData string true "title"
|
|
||||||
// @Param url formData string true "url"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /shortcuts/add [post]
|
|
||||||
func PostShortcutsAdd(c *gin.Context) {
|
|
||||||
var m model2.ShortcutsDBModel
|
|
||||||
|
|
||||||
c.BindJSON(&m)
|
|
||||||
if len(m.Url) == 0 || len(m.Title) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
u, err := url.Parse(m.Url)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
|
||||||
service.MyService.Shortcuts().AddData(m)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 删除shortcuts
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags shortcuts
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /shortcuts/del/{id} [post]
|
|
||||||
func DeleteShortcutsDelete(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
service.MyService.Shortcuts().DeleteData(id)
|
|
||||||
c.JSON(http.StatusOK, model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: "",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 编辑shortcuts
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags shortcuts
|
|
||||||
// @Param title formData string true "title"
|
|
||||||
// @Param url formData string true "url"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /shortcuts/edit [put]
|
|
||||||
func PutShortcutsEdit(c *gin.Context) {
|
|
||||||
var m model2.ShortcutsDBModel
|
|
||||||
c.BindJSON(&m)
|
|
||||||
if len(m.Url) == 0 || len(m.Title) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
u, err := url.Parse(m.Url)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SHORTCUTS_URL_ERROR, Message: common_err.GetMsg(common_err.SHORTCUTS_URL_ERROR), Data: err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m.Icon = "https://api.faviconkit.com/" + u.Host + "/57"
|
|
||||||
service.MyService.Shortcuts().EditData(m)
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""})
|
|
||||||
}
|
|
||||||
104
route/v1/storage.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-11 16:02:29
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-11 14:20:02
|
||||||
|
* @FilePath: /CasaOS/route/v1/storage.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetStorageList(c *gin.Context) {
|
||||||
|
system := c.Query("system")
|
||||||
|
storages := []model.Storages{}
|
||||||
|
disks := service.MyService.Disk().LSBLK(false)
|
||||||
|
diskNumber := 1
|
||||||
|
children := 1
|
||||||
|
findSystem := 0
|
||||||
|
for _, d := range disks {
|
||||||
|
if d.Tran != "usb" {
|
||||||
|
tempSystemDisk := false
|
||||||
|
children = 1
|
||||||
|
tempDisk := model.Storages{
|
||||||
|
DiskName: d.Model,
|
||||||
|
Path: d.Path,
|
||||||
|
Size: d.Size,
|
||||||
|
}
|
||||||
|
|
||||||
|
storageArr := []model.Storage{}
|
||||||
|
temp := service.MyService.Disk().SmartCTL(d.Path)
|
||||||
|
if reflect.DeepEqual(temp, model.SmartctlA{}) {
|
||||||
|
temp.SmartStatus.Passed = true
|
||||||
|
}
|
||||||
|
for _, v := range d.Children {
|
||||||
|
if v.MountPoint != "" {
|
||||||
|
if findSystem == 0 {
|
||||||
|
if v.MountPoint == "/" {
|
||||||
|
tempDisk.DiskName = "System"
|
||||||
|
findSystem = 1
|
||||||
|
tempSystemDisk = true
|
||||||
|
}
|
||||||
|
if len(v.Children) > 0 {
|
||||||
|
for _, c := range v.Children {
|
||||||
|
if c.MountPoint == "/" {
|
||||||
|
tempDisk.DiskName = "System"
|
||||||
|
findSystem = 1
|
||||||
|
tempSystemDisk = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stor := model.Storage{}
|
||||||
|
stor.MountPoint = v.MountPoint
|
||||||
|
stor.Size = v.FSSize
|
||||||
|
stor.Avail = v.FSAvail
|
||||||
|
stor.Path = v.Path
|
||||||
|
stor.Type = v.FsType
|
||||||
|
stor.DriveName = v.Name
|
||||||
|
if len(v.Label) == 0 {
|
||||||
|
stor.Label = "Storage" + strconv.Itoa(diskNumber) + "_" + strconv.Itoa(children)
|
||||||
|
children += 1
|
||||||
|
} else {
|
||||||
|
stor.Label = v.Label
|
||||||
|
}
|
||||||
|
storageArr = append(storageArr, stor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(storageArr) > 0 {
|
||||||
|
if tempSystemDisk && len(system) > 0 {
|
||||||
|
tempStorageArr := []model.Storage{}
|
||||||
|
for i := 0; i < len(storageArr); i++ {
|
||||||
|
if storageArr[i].MountPoint != "/boot/efi" && storageArr[i].Type != "swap" {
|
||||||
|
tempStorageArr = append(tempStorageArr, storageArr[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempDisk.Children = tempStorageArr
|
||||||
|
storages = append(storages, tempDisk)
|
||||||
|
diskNumber += 1
|
||||||
|
} else if !tempSystemDisk {
|
||||||
|
tempDisk.Children = storageArr
|
||||||
|
storages = append(storages, tempDisk)
|
||||||
|
diskNumber += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storages})
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: LinkLeong link@icewhale.com
|
|
||||||
* @Date: 2021-11-08 18:02:02
|
|
||||||
* @LastEditors: LinkLeong
|
|
||||||
* @LastEditTime: 2022-06-21 19:13:59
|
|
||||||
* @FilePath: /CasaOS/route/v1/sync.go
|
|
||||||
* @Description:
|
|
||||||
* @Website: https://www.casaos.io
|
|
||||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetSyncConfig(c *gin.Context) {
|
|
||||||
data := make(map[string]string)
|
|
||||||
data["key"] = config.SystemConfigInfo.SyncKey
|
|
||||||
data["port"] = config.SystemConfigInfo.SyncPort
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -21,7 +20,6 @@ import (
|
|||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
"github.com/IceWhaleTech/CasaOS/types"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
uuid "github.com/satori/go.uuid"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,10 +43,10 @@ func GetSystemCheckVersion(c *gin.Context) {
|
|||||||
service.MyService.Notify().AddLog(installLog)
|
service.MyService.Notify().AddLog(installLog)
|
||||||
}
|
}
|
||||||
data := make(map[string]interface{}, 3)
|
data := make(map[string]interface{}, 3)
|
||||||
data["is_need"] = need
|
data["need_update"] = need
|
||||||
data["version"] = version
|
data["version"] = version
|
||||||
data["current_version"] = types.CURRENTVERSION
|
data["current_version"] = types.CURRENTVERSION
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 系统信息
|
// @Summary 系统信息
|
||||||
@@ -63,12 +61,7 @@ func SystemUpdate(c *gin.Context) {
|
|||||||
if need {
|
if need {
|
||||||
service.MyService.System().UpdateSystemVersion(version.Version)
|
service.MyService.System().UpdateSystemVersion(version.Version)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
|
||||||
|
|
||||||
//Get system config
|
|
||||||
func GetSystemConfig(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get logs
|
// @Summary get logs
|
||||||
@@ -80,86 +73,29 @@ func GetSystemConfig(c *gin.Context) {
|
|||||||
// @Router /sys/error/logs [get]
|
// @Router /sys/error/logs [get]
|
||||||
func GetCasaOSErrorLogs(c *gin.Context) {
|
func GetCasaOSErrorLogs(c *gin.Context) {
|
||||||
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
|
line, _ := strconv.Atoi(c.DefaultQuery("line", "100"))
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)})
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改配置文件
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags sys
|
|
||||||
// @Param config formData string true "config json string"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /sys/changhead [post]
|
|
||||||
func PostSetSystemConfig(c *gin.Context) {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
n, _ := c.Request.Body.Read(buf)
|
|
||||||
|
|
||||||
service.MyService.System().UpSystemConfig(string(buf[0:n]), "")
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: json.RawMessage(config.SystemConfigInfo.ConfigStr),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//系统配置
|
//系统配置
|
||||||
func GetSystemConfigDebug(c *gin.Context) {
|
func GetSystemConfigDebug(c *gin.Context) {
|
||||||
|
|
||||||
array := service.MyService.System().GetSystemConfigDebug()
|
array := service.MyService.System().GetSystemConfigDebug()
|
||||||
disk := service.MyService.System().GetDiskInfo()
|
disk := service.MyService.System().GetDiskInfo()
|
||||||
sys := service.MyService.System().GetSysInfo()
|
sys := service.MyService.System().GetSysInfo()
|
||||||
//todo 准备sync需要显示的数据(镜像,容器)
|
version := service.MyService.Casa().GetCasaosVersion()
|
||||||
var systemAppStatus string
|
|
||||||
images := service.MyService.Docker().IsExistImage("linuxserver/syncthing")
|
|
||||||
systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
|
|
||||||
|
|
||||||
list := service.MyService.App().GetSystemAppList()
|
|
||||||
for _, v := range list {
|
|
||||||
systemAppStatus += v.Image + ",\n\t"
|
|
||||||
}
|
|
||||||
|
|
||||||
systemAppStatus += "Sync Key length: " + strconv.Itoa(len(config.SystemConfigInfo.SyncKey))
|
|
||||||
|
|
||||||
var bugContent string = fmt.Sprintf(`
|
var bugContent string = fmt.Sprintf(`
|
||||||
- OS: %s
|
- OS: %s
|
||||||
- CasaOS Version: %s
|
- CasaOS Version: %s
|
||||||
- Disk Total: %v
|
- Disk Total: %v
|
||||||
- Disk Used: %v
|
- Disk Used: %v
|
||||||
- Sync State: %s
|
|
||||||
- System Info: %s
|
- System Info: %s
|
||||||
|
- Remote Version: %s
|
||||||
- Browser: $Browser$
|
- Browser: $Browser$
|
||||||
- Version: $Version$
|
- Version: $Version$
|
||||||
`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, systemAppStatus, array)
|
`, sys.OS, types.CURRENTVERSION, disk.Total>>20, disk.Used>>20, array, version.Version)
|
||||||
|
|
||||||
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
// array = append(array, fmt.Sprintf("disk,total:%v,used:%v,UsedPercent:%v", disk.Total>>20, disk.Used>>20, disk.UsedPercent))
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: bugContent})
|
||||||
}
|
|
||||||
|
|
||||||
//widget配置
|
|
||||||
func GetWidgetConfig(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(config.SystemConfigInfo.WidgetList)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary 修改组件配置文件
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags sys
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /sys/widget/config [post]
|
|
||||||
func PostSetWidgetConfig(c *gin.Context) {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
n, _ := c.Request.Body.Read(buf)
|
|
||||||
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: json.RawMessage(config.SystemConfigInfo.WidgetList),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary get casaos server port
|
// @Summary get casaos server port
|
||||||
@@ -170,7 +106,7 @@ func PostSetWidgetConfig(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/port [get]
|
// @Router /sys/port [get]
|
||||||
func GetCasaOSPort(c *gin.Context) {
|
func GetCasaOSPort(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -188,13 +124,13 @@ func GetCasaOSPort(c *gin.Context) {
|
|||||||
// @Router /sys/port [put]
|
// @Router /sys/port [put]
|
||||||
func PutCasaOSPort(c *gin.Context) {
|
func PutCasaOSPort(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
portStr := json["port"]
|
portStr := json["port"]
|
||||||
port, err := strconv.Atoi(portStr)
|
port, err := strconv.Atoi(portStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.ERROR,
|
Success: common_err.SERVICE_ERROR,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -202,7 +138,7 @@ func PutCasaOSPort(c *gin.Context) {
|
|||||||
|
|
||||||
isAvailable := port2.IsPortAvailable(port, "tcp")
|
isAvailable := port2.IsPortAvailable(port, "tcp")
|
||||||
if !isAvailable {
|
if !isAvailable {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.PORT_IS_OCCUPIED,
|
Success: common_err.PORT_IS_OCCUPIED,
|
||||||
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
|
Message: common_err.GetMsg(common_err.PORT_IS_OCCUPIED),
|
||||||
@@ -210,40 +146,13 @@ func PutCasaOSPort(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.MyService.System().UpSystemPort(strconv.Itoa(port))
|
service.MyService.System().UpSystemPort(strconv.Itoa(port))
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 检查是否进入引导状态
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags sys
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /sys/init/check [get]
|
|
||||||
func GetSystemInitCheck(c *gin.Context) {
|
|
||||||
data := make(map[string]interface{}, 2)
|
|
||||||
|
|
||||||
if service.MyService.User().GetUserCount() > 0 {
|
|
||||||
data["initialized"] = true
|
|
||||||
data["key"] = ""
|
|
||||||
} else {
|
|
||||||
key := uuid.NewV4().String()
|
|
||||||
service.UserRegisterHash[key] = key
|
|
||||||
data["key"] = key
|
|
||||||
data["initialized"] = false
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary active killing casaos
|
// @Summary active killing casaos
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -263,7 +172,9 @@ func PostKillCasaOS(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /sys/usb/off [put]
|
// @Router /sys/usb/off [put]
|
||||||
func PutSystemUSBAutoMount(c *gin.Context) {
|
func PutSystemUSBAutoMount(c *gin.Context) {
|
||||||
status := c.Param("status")
|
js := make(map[string]string)
|
||||||
|
c.ShouldBind(&js)
|
||||||
|
status := js["state"]
|
||||||
if status == "on" {
|
if status == "on" {
|
||||||
service.MyService.System().UpdateUSBAutoMount("True")
|
service.MyService.System().UpdateUSBAutoMount("True")
|
||||||
service.MyService.System().ExecUSBAutoMountShell("True")
|
service.MyService.System().ExecUSBAutoMountShell("True")
|
||||||
@@ -271,8 +182,32 @@ func PutSystemUSBAutoMount(c *gin.Context) {
|
|||||||
service.MyService.System().UpdateUSBAutoMount("False")
|
service.MyService.System().UpdateUSBAutoMount("False")
|
||||||
service.MyService.System().ExecUSBAutoMountShell("False")
|
service.MyService.System().ExecUSBAutoMountShell("False")
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
usbList := service.MyService.Disk().LSBLK(false)
|
||||||
|
usb := []model.DriveUSB{}
|
||||||
|
for _, v := range usbList {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
isMount := false
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
isMount = true
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
}
|
||||||
|
}
|
||||||
|
if isMount {
|
||||||
|
usb = append(usb, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service.MyService.Notify().SendUSBInfoBySocket(usb)
|
||||||
|
}()
|
||||||
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -291,8 +226,32 @@ func GetSystemUSBAutoMount(c *gin.Context) {
|
|||||||
if config.ServerInfo.USBAutoMount == "False" {
|
if config.ServerInfo.USBAutoMount == "False" {
|
||||||
state = "False"
|
state = "False"
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
usbList := service.MyService.Disk().LSBLK(false)
|
||||||
|
usb := []model.DriveUSB{}
|
||||||
|
for _, v := range usbList {
|
||||||
|
if v.Tran == "usb" {
|
||||||
|
isMount := false
|
||||||
|
temp := model.DriveUSB{}
|
||||||
|
temp.Model = v.Model
|
||||||
|
temp.Name = v.Name
|
||||||
|
temp.Size = v.Size
|
||||||
|
for _, child := range v.Children {
|
||||||
|
if len(child.MountPoint) > 0 {
|
||||||
|
isMount = true
|
||||||
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
|
temp.Avail += avail
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
}
|
||||||
|
}
|
||||||
|
if isMount {
|
||||||
|
usb = append(usb, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service.MyService.Notify().SendUSBInfoBySocket(usb)
|
||||||
|
}()
|
||||||
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -300,6 +259,40 @@ func GetSystemUSBAutoMount(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSystemAppsStatus(c *gin.Context) {
|
||||||
|
systemAppList := service.MyService.App().GetSystemAppList()
|
||||||
|
appList := []model2.MyAppList{}
|
||||||
|
for _, v := range systemAppList {
|
||||||
|
name := strings.ReplaceAll(v.Names[0], "/", "")
|
||||||
|
if len(v.Labels["name"]) > 0 {
|
||||||
|
name = v.Labels["name"]
|
||||||
|
}
|
||||||
|
appList = append(appList, model2.MyAppList{
|
||||||
|
Name: name,
|
||||||
|
Icon: v.Labels["icon"],
|
||||||
|
State: v.State,
|
||||||
|
CustomId: v.Labels["custom_id"],
|
||||||
|
Id: v.ID,
|
||||||
|
Port: v.Labels["web"],
|
||||||
|
Index: v.Labels["index"],
|
||||||
|
//Order: m.Labels["order"],
|
||||||
|
Image: v.Image,
|
||||||
|
Latest: false,
|
||||||
|
//Type: m.Labels["origin"],
|
||||||
|
//Slogan: m.Slogan,
|
||||||
|
//Rely: m.Rely,
|
||||||
|
Host: v.Labels["host"],
|
||||||
|
Protocol: v.Labels["protocol"],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: appList,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary get system hardware info
|
// @Summary get system hardware info
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -311,7 +304,7 @@ func GetSystemHardwareInfo(c *gin.Context) {
|
|||||||
|
|
||||||
data := make(map[string]string, 1)
|
data := make(map[string]string, 1)
|
||||||
data["drive_model"] = service.MyService.System().GetDeviceTree()
|
data["drive_model"] = service.MyService.System().GetDeviceTree()
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -409,21 +402,13 @@ func GetSystemUtilization(c *gin.Context) {
|
|||||||
temp.Model = v.Model
|
temp.Model = v.Model
|
||||||
temp.Name = v.Name
|
temp.Name = v.Name
|
||||||
temp.Size = v.Size
|
temp.Size = v.Size
|
||||||
mountTemp := true
|
|
||||||
if len(v.Children) == 0 {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
|
||||||
for _, child := range v.Children {
|
for _, child := range v.Children {
|
||||||
if len(child.MountPoint) > 0 {
|
if len(child.MountPoint) > 0 {
|
||||||
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
|
||||||
temp.Avail += avail
|
temp.Avail += avail
|
||||||
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
|
|
||||||
temp.Used += used
|
|
||||||
} else {
|
|
||||||
mountTemp = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
temp.Mount = mountTemp
|
|
||||||
usb = append(usb, temp)
|
usb = append(usb, temp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,7 +439,7 @@ func GetSystemUtilization(c *gin.Context) {
|
|||||||
|
|
||||||
data["net"] = newNet
|
data["net"] = newNet
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Get notification port
|
// @Summary Get notification port
|
||||||
@@ -466,11 +451,11 @@ func GetSystemUtilization(c *gin.Context) {
|
|||||||
// @Router /sys/socket/port [get]
|
// @Router /sys/socket/port [get]
|
||||||
func GetSystemSocketPort(c *gin.Context) {
|
func GetSystemSocketPort(c *gin.Context) {
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
Data: config.ServerInfo.SocketPort,
|
Data: config.ServerInfo.SocketPort, // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,26 +525,3 @@ func GetSystemNetInfo(c *gin.Context) {
|
|||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet})
|
||||||
}
|
}
|
||||||
|
|
||||||
//********************************************* Soon to be removed ***********************************************
|
|
||||||
// @Summary 检查是否进入引导状态
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags sys
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /guide/check [get]
|
|
||||||
func GetGuideCheck(c *gin.Context) {
|
|
||||||
initUser := true
|
|
||||||
if service.MyService.User().GetUserCount() > 0 {
|
|
||||||
initUser = false
|
|
||||||
}
|
|
||||||
data := make(map[string]interface{}, 1)
|
|
||||||
data["need_init_user"] = initUser
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
500
route/v1/user.go
@@ -10,15 +10,17 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model/system_model"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
uuid "github.com/satori/go.uuid"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
@@ -29,46 +31,47 @@ import (
|
|||||||
// @Router /user/register/ [post]
|
// @Router /user/register/ [post]
|
||||||
func PostUserRegister(c *gin.Context) {
|
func PostUserRegister(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
username := json["user_name"]
|
|
||||||
|
username := json["username"]
|
||||||
pwd := json["password"]
|
pwd := json["password"]
|
||||||
key := c.Param("key")
|
key := json["key"]
|
||||||
if _, ok := service.UserRegisterHash[key]; !ok {
|
if _, ok := service.UserRegisterHash[key]; !ok {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)})
|
model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(username) == 0 || len(pwd) == 0 {
|
if len(username) == 0 || len(pwd) == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(pwd) < 6 {
|
if len(pwd) < 6 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.PWD_IS_TOO_SIMPLE, Message: common_err.GetMsg(common_err.PWD_IS_TOO_SIMPLE)})
|
model.Result{Success: common_err.PWD_IS_TOO_SIMPLE, Message: common_err.GetMsg(common_err.PWD_IS_TOO_SIMPLE)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
oldUser := service.MyService.User().GetUserInfoByUserName(username)
|
oldUser := service.MyService.User().GetUserInfoByUserName(username)
|
||||||
if oldUser.Id > 0 {
|
if oldUser.Id > 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
|
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := model2.UserDBModel{}
|
user := model2.UserDBModel{}
|
||||||
user.UserName = username
|
user.Username = username
|
||||||
user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD)
|
user.Password = encryption.GetMD5ByStr(pwd)
|
||||||
user.Role = "admin"
|
user.Role = "admin"
|
||||||
|
|
||||||
user = service.MyService.User().CreateUser(user)
|
user = service.MyService.User().CreateUser(user)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
|
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
|
||||||
delete(service.UserRegisterHash, key)
|
delete(service.UserRegisterHash, key)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,44 +85,43 @@ func PostUserRegister(c *gin.Context) {
|
|||||||
// @Router /user/login [post]
|
// @Router /user/login [post]
|
||||||
func PostUserLogin(c *gin.Context) {
|
func PostUserLogin(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
|
|
||||||
username := json["username"]
|
username := json["username"]
|
||||||
pwd := json["pwd"]
|
|
||||||
|
password := json["password"]
|
||||||
//check params is empty
|
//check params is empty
|
||||||
if len(username) == 0 || len(pwd) == 0 {
|
if len(username) == 0 || len(password) == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.ERROR,
|
Success: common_err.CLIENT_ERROR,
|
||||||
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := service.MyService.User().GetUserAllInfoByName(username)
|
user := service.MyService.User().GetUserAllInfoByName(username)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Password != encryption.GetMD5ByStr(pwd) {
|
if user.Password != encryption.GetMD5ByStr(password) {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
token := system_model.VerifyInformation{}
|
||||||
|
token.AccessToken = jwt.GetAccessToken(user.Username, user.Password, user.Id)
|
||||||
|
token.RefreshToken = jwt.GetRefreshToken(user.Username, user.Password, user.Id)
|
||||||
|
token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
||||||
|
data := make(map[string]interface{}, 2)
|
||||||
user.Password = ""
|
user.Password = ""
|
||||||
// token := system_model.VerifyInformation{}
|
data["token"] = token
|
||||||
// token.AccessToken = jwt.GetAccessToken(user.UserName, user.Password, user.Id)
|
|
||||||
// token.RefreshToken = jwt.GetRefreshToken(user.UserName, user.Password, user.Id)
|
// TODO:1 Database fields cannot be external
|
||||||
// token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
|
||||||
// data := make(map[string]interface{}, 2)
|
|
||||||
// data["token"] = token
|
|
||||||
// data["user"] = user
|
|
||||||
data := make(map[string]interface{}, 3)
|
|
||||||
data["token"] = jwt.GetToken(username, pwd)
|
|
||||||
data["version"] = types.CURRENTVERSION
|
|
||||||
data["user"] = user
|
data["user"] = user
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -139,14 +141,14 @@ func PutUserAvatar(c *gin.Context) {
|
|||||||
id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f, err := c.FormFile("file")
|
f, err := c.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(user.Avatar) > 0 {
|
if len(user.Avatar) > 0 {
|
||||||
@@ -165,22 +167,6 @@ func PutUserAvatar(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: get user avatar by user id
|
|
||||||
* @param {query} id string user id
|
|
||||||
* @method: GET
|
|
||||||
*/
|
|
||||||
func GetUserAvatar(c *gin.Context) {
|
|
||||||
id := c.Param("id")
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
|
||||||
|
|
||||||
path := "default.png"
|
|
||||||
if user.Id > 0 {
|
|
||||||
path = user.Avatar
|
|
||||||
}
|
|
||||||
c.File(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary edit user name
|
// @Summary edit user name
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -189,27 +175,42 @@ func GetUserAvatar(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/name/:id [put]
|
// @Router /user/name/:id [put]
|
||||||
func PutUserName(c *gin.Context) {
|
func PutUserInfo(c *gin.Context) {
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
json := make(map[string]string)
|
json := model2.UserDBModel{}
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
//userName := json["user_name"]
|
|
||||||
username := json["username"]
|
|
||||||
id := json["user_id"]
|
|
||||||
if len(username) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.UserName = username
|
if len(json.Username) > 0 {
|
||||||
service.MyService.User().UpdateUser(user)
|
u := service.MyService.User().GetUserInfoByUserName(json.Username)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
if u.Id > 0 {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR,
|
||||||
|
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(json.Email) == 0 {
|
||||||
|
json.Email = user.Email
|
||||||
|
}
|
||||||
|
if len(json.Avatar) == 0 {
|
||||||
|
json.Avatar = user.Avatar
|
||||||
|
}
|
||||||
|
if len(json.Role) == 0 {
|
||||||
|
json.Role = user.Role
|
||||||
|
}
|
||||||
|
if len(json.Description) == 0 {
|
||||||
|
json.Description = user.Description
|
||||||
|
}
|
||||||
|
if len(json.Nickname) == 0 {
|
||||||
|
json.Nickname = user.Nickname
|
||||||
|
}
|
||||||
|
service.MyService.User().UpdateUser(json)
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary edit user password
|
// @Summary edit user password
|
||||||
@@ -219,31 +220,30 @@ func PutUserName(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/password/:id [put]
|
// @Router /user/password/:id [put]
|
||||||
func PutUserPwd(c *gin.Context) {
|
func PutUserPassword(c *gin.Context) {
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
oldPwd := json["old_pwd"]
|
oldPwd := json["old_password"]
|
||||||
pwd := json["pwd"]
|
pwd := json["password"]
|
||||||
id := json["user_id"]
|
|
||||||
if len(oldPwd) == 0 || len(pwd) == 0 {
|
if len(oldPwd) == 0 || len(pwd) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := service.MyService.User().GetUserAllInfoById(id)
|
user := service.MyService.User().GetUserAllInfoById(id)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Password != encryption.GetMD5ByStr(oldPwd) {
|
if user.Password != encryption.GetMD5ByStr(oldPwd) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Password = encryption.GetMD5ByStr(pwd)
|
user.Password = encryption.GetMD5ByStr(pwd)
|
||||||
service.MyService.User().UpdateUserPassword(user)
|
service.MyService.User().UpdateUserPassword(user)
|
||||||
user.Password = ""
|
user.Password = ""
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary edit user nick
|
// @Summary edit user nick
|
||||||
@@ -256,12 +256,11 @@ func PutUserPwd(c *gin.Context) {
|
|||||||
// @Router /user/nick [put]
|
// @Router /user/nick [put]
|
||||||
func PutUserNick(c *gin.Context) {
|
func PutUserNick(c *gin.Context) {
|
||||||
|
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
nickName := json["nick_name"]
|
Nickname := json["nick_name"]
|
||||||
id := json["user_id"]
|
if len(Nickname) == 0 {
|
||||||
if len(nickName) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -271,10 +270,8 @@ func PutUserNick(c *gin.Context) {
|
|||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.NickName = nickName
|
user.Nickname = Nickname
|
||||||
service.MyService.User().UpdateUser(user)
|
service.MyService.User().UpdateUser(user)
|
||||||
//TODO:person remove together
|
|
||||||
go service.MyService.Casa().PushUserInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,10 +284,9 @@ func PutUserNick(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/desc [put]
|
// @Router /user/desc [put]
|
||||||
func PutUserDesc(c *gin.Context) {
|
func PutUserDesc(c *gin.Context) {
|
||||||
// id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
id := json["user_id"]
|
|
||||||
desc := json["description"]
|
desc := json["description"]
|
||||||
if len(desc) == 0 {
|
if len(desc) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
@@ -309,39 +305,6 @@ func PutUserDesc(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Modify user person information (Initialization use)
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept multipart/form-data
|
|
||||||
// @Tags user
|
|
||||||
// @Param nick_name formData string false "user nick name"
|
|
||||||
// @Param description formData string false "Description"
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/person/info [post]
|
|
||||||
func PostUserPersonInfo(c *gin.Context) {
|
|
||||||
json := make(map[string]string)
|
|
||||||
c.BindJSON(&json)
|
|
||||||
desc := json["description"]
|
|
||||||
nickName := json["nick_name"]
|
|
||||||
id := json["user_id"]
|
|
||||||
if len(desc) == 0 || len(nickName) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
|
||||||
if user.Id == 0 {
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//user_service.SetUser("", "", "", "", desc, nickName)
|
|
||||||
user.NickName = nickName
|
|
||||||
user.Description = desc
|
|
||||||
service.MyService.User().UpdateUser(user)
|
|
||||||
go service.MyService.Casa().PushUserInfo()
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary get user info
|
// @Summary get user info
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept application/json
|
// @Accept application/json
|
||||||
@@ -349,51 +312,10 @@ func PostUserPersonInfo(c *gin.Context) {
|
|||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/info/:id [get]
|
// @Router /user/info/:id [get]
|
||||||
func GetUserInfo(c *gin.Context) {
|
func GetUserInfo(c *gin.Context) {
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
//*****
|
c.JSON(common_err.SUCCESS,
|
||||||
var u = make(map[string]string, 5)
|
|
||||||
u["user_name"] = user.UserName
|
|
||||||
u["head"] = user.Avatar
|
|
||||||
u["email"] = user.Email
|
|
||||||
u["description"] = user.NickName
|
|
||||||
u["nick_name"] = user.NickName
|
|
||||||
u["id"] = strconv.Itoa(user.Id)
|
|
||||||
|
|
||||||
//**
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
|
||||||
Success: common_err.SUCCESS,
|
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
|
||||||
Data: u,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Summary get user info
|
|
||||||
// @Produce application/json
|
|
||||||
// @Accept application/json
|
|
||||||
// @Tags user
|
|
||||||
// @Success 200 {string} string "ok"
|
|
||||||
// @Router /user/info [get]
|
|
||||||
func GetUserInfoByUserName(c *gin.Context) {
|
|
||||||
json := make(map[string]string)
|
|
||||||
c.BindJSON(&json)
|
|
||||||
userName := json["user_name"]
|
|
||||||
if len(userName) == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
user := service.MyService.User().GetUserInfoByUserName(userName)
|
|
||||||
if user.Id == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//**
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK,
|
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -401,29 +323,46 @@ func GetUserInfoByUserName(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Get my shareId
|
/**
|
||||||
// @Produce application/json
|
* @description:
|
||||||
// @Accept application/json
|
* @param {*gin.Context} c
|
||||||
// @Tags user
|
* @param {string} Username
|
||||||
// @Security ApiKeyAuth
|
* @return {*}
|
||||||
// @Success 200 {string} string "ok"
|
* @method:
|
||||||
// @Router /user/shareid [get]
|
* @router:
|
||||||
func GetUserShareID(c *gin.Context) {
|
*/
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token})
|
func GetUserInfoByUsername(c *gin.Context) {
|
||||||
|
username := c.Param("username")
|
||||||
|
if len(username) == 0 {
|
||||||
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := service.MyService.User().GetUserInfoByUserName(username)
|
||||||
|
if user.Id == 0 {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(common_err.SUCCESS,
|
||||||
|
model.Result{
|
||||||
|
Success: common_err.SUCCESS,
|
||||||
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: user,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: get all user name
|
* @description: get all Usernames
|
||||||
* @method:GET
|
* @method:GET
|
||||||
* @router:/user/all/name
|
* @router:/user/all/name
|
||||||
*/
|
*/
|
||||||
func GetUserAllUserName(c *gin.Context) {
|
func GetUserAllUsername(c *gin.Context) {
|
||||||
users := service.MyService.User().GetAllUserName()
|
users := service.MyService.User().GetAllUserName()
|
||||||
names := []string{}
|
names := []string{}
|
||||||
for _, v := range users {
|
for _, v := range users {
|
||||||
names = append(names, v.UserName)
|
names = append(names, v.Username)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SUCCESS,
|
||||||
model.Result{
|
model.Result{
|
||||||
Success: common_err.SUCCESS,
|
Success: common_err.SUCCESS,
|
||||||
Message: common_err.GetMsg(common_err.SUCCESS),
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
@@ -440,25 +379,26 @@ func GetUserAllUserName(c *gin.Context) {
|
|||||||
func GetUserCustomConf(c *gin.Context) {
|
func GetUserCustomConf(c *gin.Context) {
|
||||||
name := c.Param("key")
|
name := c.Param("key")
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
// user := service.MyService.User().GetUserInfoByUserName(userName)
|
// user := service.MyService.User().GetUserInfoByUsername(Username)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
|
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
|
||||||
|
|
||||||
data := file.ReadFullFile(filePath)
|
data := file.ReadFullFile(filePath)
|
||||||
if !gjson.ValidBytes(data) {
|
if !gjson.ValidBytes(data) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -468,16 +408,16 @@ func GetUserCustomConf(c *gin.Context) {
|
|||||||
* @router:/user/custom/:key
|
* @router:/user/custom/:key
|
||||||
*/
|
*/
|
||||||
func PostUserCustomConf(c *gin.Context) {
|
func PostUserCustomConf(c *gin.Context) {
|
||||||
|
|
||||||
name := c.Param("key")
|
name := c.Param("key")
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -485,7 +425,7 @@ func PostUserCustomConf(c *gin.Context) {
|
|||||||
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
|
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
|
||||||
|
|
||||||
file.WriteToPath(data, filePath, name+".json")
|
file.WriteToPath(data, filePath, name+".json")
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -497,20 +437,23 @@ func PostUserCustomConf(c *gin.Context) {
|
|||||||
func DeleteUserCustomConf(c *gin.Context) {
|
func DeleteUserCustomConf(c *gin.Context) {
|
||||||
name := c.Param("key")
|
name := c.Param("key")
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK,
|
c.JSON(common_err.SERVICE_ERROR,
|
||||||
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + name + ".json"
|
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + name + ".json"
|
||||||
os.Remove(filePath)
|
err := os.Remove(filePath)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
if err != nil {
|
||||||
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -522,19 +465,18 @@ func DeleteUserCustomConf(c *gin.Context) {
|
|||||||
func DeleteUser(c *gin.Context) {
|
func DeleteUser(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
service.MyService.User().DeleteUserById(id)
|
service.MyService.User().DeleteUserById(id)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:update user image
|
* @description:update user image
|
||||||
* @method:POST
|
* @method:POST
|
||||||
* @router:/user/file/image/:key
|
* @router:/user/current/image/:key
|
||||||
*/
|
*/
|
||||||
func PostUserFileImage(c *gin.Context) {
|
func PutUserImage(c *gin.Context) {
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
json := make(map[string]string)
|
json := make(map[string]string)
|
||||||
c.BindJSON(&json)
|
c.ShouldBind(&json)
|
||||||
|
|
||||||
path := json["path"]
|
path := json["path"]
|
||||||
key := c.Param("key")
|
key := c.Param("key")
|
||||||
@@ -571,50 +513,57 @@ func PostUserFileImage(c *gin.Context) {
|
|||||||
data := make(map[string]string, 3)
|
data := make(map[string]string, 3)
|
||||||
data["path"] = filePath
|
data["path"] = filePath
|
||||||
data["file_name"] = key + ext
|
data["file_name"] = key + ext
|
||||||
data["online_path"] = "/v1/user/image?path=" + filePath
|
data["online_path"] = "/v1/users/image?path=" + filePath
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:create or update user's custom image
|
* @description:
|
||||||
* @param {formData} file file "a file to be uploaded"
|
* @param {*gin.Context} c
|
||||||
* @param {path} key string "file name"
|
* @param {file} file
|
||||||
* @method:POST
|
* @param {string} key
|
||||||
* @router:/user/upload/image/:key
|
* @param {string} type:avatar,background
|
||||||
|
* @return {*}
|
||||||
|
* @method:
|
||||||
|
* @router:
|
||||||
*/
|
*/
|
||||||
func PostUserUploadImage(c *gin.Context) {
|
func PostUserUploadImage(c *gin.Context) {
|
||||||
//id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
f, err := c.FormFile("file")
|
f, err := c.FormFile("file")
|
||||||
key := c.Param("key")
|
key := c.Param("key")
|
||||||
|
t := c.PostForm("type")
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = file.GetImageExtByName(f.Filename)
|
_, err = file.GetImageExtByName(f.Filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ext := filepath.Ext(f.Filename)
|
ext := filepath.Ext(f.Filename)
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
|
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if t == "avatar" {
|
||||||
|
key = "avatar"
|
||||||
|
}
|
||||||
path := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
|
path := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
|
||||||
|
|
||||||
c.SaveUploadedFile(f, path)
|
c.SaveUploadedFile(f, path)
|
||||||
data := make(map[string]string, 3)
|
data := make(map[string]string, 3)
|
||||||
data["path"] = path
|
data["path"] = path
|
||||||
data["file_name"] = key + ext
|
data["file_name"] = key + ext
|
||||||
data["online_path"] = "/v1/user/image?path=" + path
|
data["online_path"] = "/v1/users/image?path=" + path
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -641,95 +590,94 @@ func GetUserImage(c *gin.Context) {
|
|||||||
defer fileTmp.Close()
|
defer fileTmp.Close()
|
||||||
|
|
||||||
fileName := path.Base(filePath)
|
fileName := path.Base(filePath)
|
||||||
|
|
||||||
|
// @tiger - RESTful 规范下不应该返回文件本身内容,而是返回文件的静态URL,由前端去解析
|
||||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
|
||||||
c.File(filePath)
|
c.File(filePath)
|
||||||
}
|
}
|
||||||
func DeleteUserImage(c *gin.Context) {
|
func DeleteUserImage(c *gin.Context) {
|
||||||
// id := c.GetHeader("user_id")
|
id := c.GetHeader("user_id")
|
||||||
id := c.Param("id")
|
|
||||||
path := c.Query("path")
|
path := c.Query("path")
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := service.MyService.User().GetUserInfoById(id)
|
user := service.MyService.User().GetUserInfoById(id)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !file.Exists(path) {
|
if !file.Exists(path) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
|
c.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
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+strconv.Itoa(user.Id)) {
|
if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+strconv.Itoa(user.Id)) {
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
}
|
}
|
||||||
|
|
||||||
////refresh token
|
/**
|
||||||
// func PostUserRefreshToken(c *gin.Context) {
|
* @description:
|
||||||
// json := make(map[string]string)
|
* @param {*gin.Context} c
|
||||||
// c.BindJSON(&json)
|
* @param {string} refresh_token
|
||||||
// refresh := json["refresh_token"]
|
* @return {*}
|
||||||
// claims, err := jwt.ParseToken(refresh)
|
* @method:
|
||||||
// if err != nil {
|
* @router:
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()})
|
*/
|
||||||
// return
|
func PostUserRefreshToken(c *gin.Context) {
|
||||||
// }
|
js := make(map[string]string)
|
||||||
// if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("refresh", true) {
|
c.ShouldBind(&js)
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)})
|
refresh := js["refresh_token"]
|
||||||
// return
|
claims, err := jwt.ParseToken(refresh, true)
|
||||||
// }
|
if err != nil {
|
||||||
// newToken := jwt.GetAccessToken(claims.UserName, claims.PassWord, claims.Id)
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()})
|
||||||
// if err != nil {
|
return
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()})
|
}
|
||||||
// return
|
if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("refresh", true) {
|
||||||
// }
|
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)})
|
||||||
// verifyInfo := system_model.VerifyInformation{}
|
return
|
||||||
// verifyInfo.AccessToken = newToken
|
}
|
||||||
// verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.UserName, claims.PassWord, claims.Id)
|
newToken := jwt.GetAccessToken(claims.Username, claims.PassWord, claims.Id)
|
||||||
// verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
verifyInfo := system_model.VerifyInformation{}
|
||||||
|
verifyInfo.AccessToken = newToken
|
||||||
|
verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.Username, claims.PassWord, claims.Id)
|
||||||
|
verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
|
||||||
|
|
||||||
// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo})
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo})
|
||||||
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
//******** soon to be removed ********
|
func DeleteUserAll(c *gin.Context) {
|
||||||
|
service.MyService.User().DeleteAllUser()
|
||||||
|
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary 设置用户名和密码
|
// @Summary 检查是否进入引导状态
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Accept multipart/form-data
|
// @Accept application/json
|
||||||
// @Tags user
|
// @Tags sys
|
||||||
// @Param username formData string true "User name"
|
|
||||||
// @Param pwd formData string true "password"
|
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Success 200 {string} string "ok"
|
// @Success 200 {string} string "ok"
|
||||||
// @Router /user/setusernamepwd [post]
|
// @Router /sys/init/check [get]
|
||||||
func Set_Name_Pwd(c *gin.Context) {
|
func GetUserStatus(c *gin.Context) {
|
||||||
json := make(map[string]string)
|
data := make(map[string]interface{}, 2)
|
||||||
c.BindJSON(&json)
|
|
||||||
username := json["username"]
|
if service.MyService.User().GetUserCount() > 0 {
|
||||||
pwd := json["pwd"]
|
data["initialized"] = true
|
||||||
if service.MyService.User().GetUserCount() > 0 || len(username) == 0 || len(pwd) == 0 {
|
data["key"] = ""
|
||||||
c.JSON(http.StatusOK,
|
} else {
|
||||||
model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
|
key := uuid.NewV4().String()
|
||||||
return
|
service.UserRegisterHash[key] = key
|
||||||
|
data["key"] = key
|
||||||
|
data["initialized"] = false
|
||||||
}
|
}
|
||||||
user := model2.UserDBModel{}
|
c.JSON(common_err.SUCCESS,
|
||||||
user.UserName = username
|
model.Result{
|
||||||
user.Password = encryption.GetMD5ByStr(pwd)
|
Success: common_err.SUCCESS,
|
||||||
user.Role = "admin"
|
Message: common_err.GetMsg(common_err.SUCCESS),
|
||||||
|
Data: data,
|
||||||
user = service.MyService.User().CreateUser(user)
|
})
|
||||||
if user.Id == 0 {
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR)})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ type AppService interface {
|
|||||||
SaveContainer(m model2.AppListDBModel)
|
SaveContainer(m model2.AppListDBModel)
|
||||||
GetUninstallInfo(id string) model2.AppListDBModel
|
GetUninstallInfo(id string) model2.AppListDBModel
|
||||||
DeleteApp(id string)
|
DeleteApp(id string)
|
||||||
GetContainerInfo(name string) (types.Container, error)
|
GetContainerInfo(id string) (types.Container, error)
|
||||||
GetAppDBInfo(id string) model2.AppListDBModel
|
GetAppDBInfo(id string) model2.AppListDBModel
|
||||||
UpdateApp(m model2.AppListDBModel)
|
UpdateApp(m model2.AppListDBModel)
|
||||||
GetSimpleContainerInfo(name string) (types.Container, error)
|
GetSimpleContainerInfo(id string) (types.Container, error)
|
||||||
DelAppConfigDir(path string)
|
DelAppConfigDir(path string)
|
||||||
GetSystemAppList() []types.Container
|
GetSystemAppList() []types.Container
|
||||||
GetHardwareUsageSteam()
|
GetHardwareUsageStream()
|
||||||
GetHardwareUsage() []model.DockerStatsModel
|
GetHardwareUsage() []model.DockerStatsModel
|
||||||
GetAppStats(id string) string
|
GetAppStats(id string) string
|
||||||
GetAllDBApps() []model2.AppListDBModel
|
GetAllDBApps() []model2.AppListDBModel
|
||||||
@@ -156,13 +156,23 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
|
|||||||
|
|
||||||
for _, m := range containers {
|
for _, m := range containers {
|
||||||
if m.Labels["casaos"] == "casaos" {
|
if m.Labels["casaos"] == "casaos" {
|
||||||
if m.Labels["origin"] == "system" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_, newVersion := NewVersionApp[m.ID]
|
_, newVersion := NewVersionApp[m.ID]
|
||||||
|
name := strings.ReplaceAll(m.Names[0], "/", "")
|
||||||
|
icon := m.Labels["icon"]
|
||||||
|
if len(m.Labels["name"]) > 0 {
|
||||||
|
name = m.Labels["name"]
|
||||||
|
}
|
||||||
|
if m.Labels["origin"] == "system" {
|
||||||
|
name = strings.Split(m.Image, ":")[0]
|
||||||
|
if len(strings.Split(name, "/")) > 1 {
|
||||||
|
icon = "https://icon.casaos.io/main/all/" + strings.Split(name, "/")[1] + ".png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list = append(list, model2.MyAppList{
|
list = append(list, model2.MyAppList{
|
||||||
Name: strings.ReplaceAll(m.Names[0], "/", ""),
|
Name: name,
|
||||||
Icon: m.Labels["icon"],
|
Icon: icon,
|
||||||
State: m.State,
|
State: m.State,
|
||||||
CustomId: m.Labels["custom_id"],
|
CustomId: m.Labels["custom_id"],
|
||||||
Id: m.ID,
|
Id: m.ID,
|
||||||
@@ -170,8 +180,8 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
|
|||||||
Index: m.Labels["index"],
|
Index: m.Labels["index"],
|
||||||
//Order: m.Labels["order"],
|
//Order: m.Labels["order"],
|
||||||
Image: m.Image,
|
Image: m.Image,
|
||||||
NewVersion: newVersion,
|
Latest: newVersion,
|
||||||
Type: m.Labels["origin"],
|
//Type: m.Labels["origin"],
|
||||||
//Slogan: m.Slogan,
|
//Slogan: m.Slogan,
|
||||||
//Rely: m.Rely,
|
//Rely: m.Rely,
|
||||||
Host: m.Labels["host"],
|
Host: m.Labels["host"],
|
||||||
@@ -185,7 +195,7 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
|
|||||||
CustomId: m.ID,
|
CustomId: m.ID,
|
||||||
Id: m.ID,
|
Id: m.ID,
|
||||||
Port: "",
|
Port: "",
|
||||||
NewVersion: false,
|
Latest: false,
|
||||||
Host: "",
|
Host: "",
|
||||||
Protocol: "",
|
Protocol: "",
|
||||||
Image: m.Image,
|
Image: m.Image,
|
||||||
@@ -274,14 +284,14 @@ func (a *appStruct) GetAllDBApps() []model2.AppListDBModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//获取我的应用列表
|
//获取我的应用列表
|
||||||
func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
func (a *appStruct) GetContainerInfo(id string) (types.Container, error) {
|
||||||
//获取docker应用
|
//获取docker应用
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("Failed to init client", zap.Any("err", err))
|
loger.Error("Failed to init client", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
filters := filters.NewArgs()
|
filters := filters.NewArgs()
|
||||||
filters.Add("name", name)
|
filters.Add("id", id)
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("Failed to get container_list", zap.Any("err", err))
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
@@ -294,7 +304,7 @@ func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appStruct) GetSimpleContainerInfo(name string) (types.Container, error) {
|
func (a *appStruct) GetSimpleContainerInfo(id string) (types.Container, error) {
|
||||||
//获取docker应用
|
//获取docker应用
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -302,7 +312,7 @@ func (a *appStruct) GetSimpleContainerInfo(name string) (types.Container, error)
|
|||||||
}
|
}
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
filters := filters.NewArgs()
|
filters := filters.NewArgs()
|
||||||
filters.Add("name", name)
|
filters.Add("id", id)
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.Container{}, err
|
return types.Container{}, err
|
||||||
@@ -366,12 +376,12 @@ func (a *appStruct) GetAppStats(id string) string {
|
|||||||
|
|
||||||
func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel {
|
func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel {
|
||||||
|
|
||||||
steam := true
|
stream := true
|
||||||
for !isFinish {
|
for !isFinish {
|
||||||
if steam {
|
if stream {
|
||||||
steam = false
|
stream = false
|
||||||
go func() {
|
go func() {
|
||||||
a.GetHardwareUsageSteam()
|
a.GetHardwareUsageStream()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
@@ -386,7 +396,7 @@ func (a *appStruct) GetHardwareUsage() []model.DockerStatsModel {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appStruct) GetHardwareUsageSteam() {
|
func (a *appStruct) GetHardwareUsageStream() {
|
||||||
|
|
||||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -400,20 +410,26 @@ func (a *appStruct) GetHardwareUsageSteam() {
|
|||||||
fts := filters.NewArgs()
|
fts := filters.NewArgs()
|
||||||
fts.Add("label", "casaos=casaos")
|
fts.Add("label", "casaos=casaos")
|
||||||
//fts.Add("status", "running")
|
//fts.Add("status", "running")
|
||||||
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||||
|
if err != nil {
|
||||||
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
|
}
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
|
if i%10 == 0 {
|
||||||
|
containers, err = cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||||
|
if err != nil {
|
||||||
|
loger.Error("Failed to get container_list", zap.Any("err", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
if config.CasaOSGlobalVariables.AppChange {
|
if config.CasaOSGlobalVariables.AppChange {
|
||||||
config.CasaOSGlobalVariables.AppChange = false
|
config.CasaOSGlobalVariables.AppChange = false
|
||||||
|
|
||||||
dataStats.Range(func(key, value interface{}) bool {
|
dataStats.Range(func(key, value interface{}) bool {
|
||||||
dataStats.Delete(key)
|
dataStats.Delete(key)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
|
||||||
if err != nil {
|
|
||||||
loger.Error("Failed to get container_list", zap.Any("err", err))
|
|
||||||
}
|
|
||||||
var temp sync.Map
|
var temp sync.Map
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, v := range containers {
|
for _, v := range containers {
|
||||||
@@ -435,12 +451,14 @@ func (a *appStruct) GetHardwareUsageSteam() {
|
|||||||
m, _ := dataStats.Load(v.ID)
|
m, _ := dataStats.Load(v.ID)
|
||||||
dockerStats := model.DockerStatsModel{}
|
dockerStats := model.DockerStatsModel{}
|
||||||
if m != nil {
|
if m != nil {
|
||||||
dockerStats.Pre = m.(model.DockerStatsModel).Data
|
dockerStats.Previous = m.(model.DockerStatsModel).Data
|
||||||
}
|
}
|
||||||
dockerStats.Data = data
|
dockerStats.Data = data
|
||||||
dockerStats.Icon = v.Labels["icon"]
|
dockerStats.Icon = v.Labels["icon"]
|
||||||
dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
|
dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
|
||||||
|
|
||||||
|
// @tiger - 不建议直接把依赖的数据结构封装返回。
|
||||||
|
// 如果依赖的数据结构有变化,应该在这里适配或者保存,这样更加对客户端负责
|
||||||
temp.Store(v.ID, dockerStats)
|
temp.Store(v.ID, dockerStats)
|
||||||
if i == 99 {
|
if i == 99 {
|
||||||
stats.Body.Close()
|
stats.Body.Close()
|
||||||
|
|||||||
155
service/casa.go
@@ -14,24 +14,19 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CasaService interface {
|
type CasaService interface {
|
||||||
GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection
|
GetServerList(index, size, tp, categoryId, key string) (model.ServerAppListCollection, error)
|
||||||
GetServerCategoryList() []model.CategoryList
|
GetServerCategoryList() (list []model.CategoryList, err error)
|
||||||
GetServerAppInfo(id, t string, language string) model.ServerAppList
|
GetServerAppInfo(id, t string, language string) (model.ServerAppList, error)
|
||||||
ShareAppFile(body []byte) string
|
ShareAppFile(body []byte) string
|
||||||
PushHeart(id, t string, language string)
|
|
||||||
|
|
||||||
PushConnectionStatus(uuid, err string, from, to, event string)
|
|
||||||
PushUserInfo()
|
|
||||||
GetUserInfoByShareId(shareId string) model.UserInfo
|
|
||||||
GetPersonPublic() (list []model.FriendsModel)
|
|
||||||
GetCasaosVersion() model.Version
|
GetCasaosVersion() model.Version
|
||||||
AsyncGetServerList() (collection model.ServerAppListCollection)
|
AsyncGetServerList() (collection model.ServerAppListCollection, err error)
|
||||||
AsyncGetServerCategoryList() []model.CategoryList
|
AsyncGetServerCategoryList() ([]model.CategoryList, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type casaService struct {
|
type casaService struct {
|
||||||
@@ -46,7 +41,7 @@ func (o *casaService) ShareAppFile(body []byte) string {
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *casaService) GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection {
|
func (o *casaService) GetServerList(index, size, tp, categoryId, key string) (model.ServerAppListCollection, error) {
|
||||||
|
|
||||||
keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, "en")
|
keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, "en")
|
||||||
collection := model.ServerAppListCollection{}
|
collection := model.ServerAppListCollection{}
|
||||||
@@ -54,7 +49,7 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod
|
|||||||
res, ok := result.(string)
|
res, ok := result.(string)
|
||||||
if ok {
|
if ok {
|
||||||
json2.Unmarshal([]byte(res), &collection)
|
json2.Unmarshal([]byte(res), &collection)
|
||||||
return collection
|
return collection, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +58,10 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod
|
|||||||
err := json2.Unmarshal(collectionStr, &collection)
|
err := json2.Unmarshal(collectionStr, &collection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(collectionStr)))
|
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(collectionStr)))
|
||||||
collection = o.AsyncGetServerList()
|
collection, err = o.AsyncGetServerList()
|
||||||
|
if err != nil {
|
||||||
|
return collection, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go o.AsyncGetServerList()
|
go o.AsyncGetServerList()
|
||||||
@@ -122,20 +120,20 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) mod
|
|||||||
Cache.Set(keyName, string(by), time.Minute*10)
|
Cache.Set(keyName, string(by), time.Minute*10)
|
||||||
}
|
}
|
||||||
|
|
||||||
return collection
|
return collection, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollection) {
|
func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollection, err error) {
|
||||||
|
|
||||||
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_list.json")
|
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_list.json")
|
||||||
err := json2.Unmarshal(results, &collection)
|
errr := json2.Unmarshal(results, &collection)
|
||||||
if err != nil {
|
if errr != nil {
|
||||||
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if collection.Version == o.GetCasaosVersion().Version {
|
if collection.Version == o.GetCasaosVersion().Version {
|
||||||
return collection
|
return collection, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
head := make(map[string]string)
|
head := make(map[string]string)
|
||||||
@@ -155,7 +153,8 @@ func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollec
|
|||||||
collection.List = listModel
|
collection.List = listModel
|
||||||
collection.Recommend = recommendModel
|
collection.Recommend = recommendModel
|
||||||
collection.Version = o.GetCasaosVersion().Version
|
collection.Version = o.GetCasaosVersion().Version
|
||||||
by, err := json.Marshal(collection)
|
var by []byte
|
||||||
|
by, err = json.Marshal(collection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("marshal error", zap.Any("err", err))
|
loger.Error("marshal error", zap.Any("err", err))
|
||||||
}
|
}
|
||||||
@@ -187,33 +186,36 @@ func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollec
|
|||||||
// return list
|
// return list
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (o *casaService) GetServerCategoryList() (list []model.CategoryList) {
|
func (o *casaService) GetServerCategoryList() (list []model.CategoryList, err error) {
|
||||||
category := model.ServerCategoryList{}
|
category := model.ServerCategoryList{}
|
||||||
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json")
|
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json")
|
||||||
err := json2.Unmarshal(results, &category)
|
err = json2.Unmarshal(results, &category)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
||||||
return o.AsyncGetServerCategoryList()
|
return o.AsyncGetServerCategoryList()
|
||||||
}
|
}
|
||||||
go o.AsyncGetServerCategoryList()
|
go o.AsyncGetServerCategoryList()
|
||||||
return category.Item
|
return category.Item, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *casaService) AsyncGetServerCategoryList() []model.CategoryList {
|
func (o *casaService) AsyncGetServerCategoryList() ([]model.CategoryList, error) {
|
||||||
list := model.ServerCategoryList{}
|
list := model.ServerCategoryList{}
|
||||||
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json")
|
results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json")
|
||||||
err := json2.Unmarshal(results, &list)
|
err := json2.Unmarshal(results, &list)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if list.Version == o.GetCasaosVersion().Version {
|
if list.Version == o.GetCasaosVersion().Version {
|
||||||
return nil
|
return list.Item, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
item := []model.CategoryList{}
|
item := []model.CategoryList{}
|
||||||
head := make(map[string]string)
|
head := make(map[string]string)
|
||||||
head["Authorization"] = GetToken()
|
head["Authorization"] = GetToken()
|
||||||
listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head)
|
listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head)
|
||||||
|
if len(listS) == 0 {
|
||||||
|
return item, errors.New("server error")
|
||||||
|
}
|
||||||
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item)
|
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item)
|
||||||
if len(item) > 0 {
|
if len(item) > 0 {
|
||||||
list.Version = o.GetCasaosVersion().Version
|
list.Version = o.GetCasaosVersion().Version
|
||||||
@@ -224,10 +226,10 @@ func (o *casaService) AsyncGetServerCategoryList() []model.CategoryList {
|
|||||||
}
|
}
|
||||||
file.WriteToPath(by, config.AppInfo.DBPath, "app_category.json")
|
file.WriteToPath(by, config.AppInfo.DBPath, "app_category.json")
|
||||||
}
|
}
|
||||||
return item
|
return item, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *casaService) GetServerAppInfo(id, t string, language string) model.ServerAppList {
|
func (o *casaService) GetServerAppInfo(id, t string, language string) (model.ServerAppList, error) {
|
||||||
|
|
||||||
head := make(map[string]string)
|
head := make(map[string]string)
|
||||||
|
|
||||||
@@ -235,9 +237,16 @@ func (o *casaService) GetServerAppInfo(id, t string, language string) model.Serv
|
|||||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t+"&language="+language, head)
|
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t+"&language="+language, head)
|
||||||
|
|
||||||
info := model.ServerAppList{}
|
info := model.ServerAppList{}
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
if infoS == "" {
|
||||||
|
return info, errors.New("server error")
|
||||||
|
}
|
||||||
|
err := json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(infoS)
|
||||||
|
return info, err
|
||||||
|
}
|
||||||
|
|
||||||
return info
|
return info, nil
|
||||||
}
|
}
|
||||||
func GetToken() string {
|
func GetToken() string {
|
||||||
t := make(chan string)
|
t := make(chan string)
|
||||||
@@ -289,86 +298,6 @@ func (o *casaService) GetCasaosVersion() model.Version {
|
|||||||
return version
|
return version
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *casaService) PushHeart(id, t string, language string) {
|
|
||||||
|
|
||||||
m := model.CasaOSHeart{}
|
|
||||||
m.UuId = id
|
|
||||||
m.Type = t
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
|
|
||||||
head := make(map[string]string)
|
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
|
||||||
|
|
||||||
infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/heart", b, "application/json", head)
|
|
||||||
|
|
||||||
info := model.ServerAppList{}
|
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *casaService) PushConnectionStatus(uuid, err string, from, to, event string) {
|
|
||||||
|
|
||||||
m := model.ConnectionStatus{}
|
|
||||||
m.UUId = uuid
|
|
||||||
m.Error = err
|
|
||||||
m.From = from
|
|
||||||
m.To = to
|
|
||||||
m.Event = event
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
|
|
||||||
head := make(map[string]string)
|
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
|
||||||
|
|
||||||
infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/connect", b, "application/json", head)
|
|
||||||
|
|
||||||
info := model.ServerAppList{}
|
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
|
||||||
|
|
||||||
}
|
|
||||||
func (o *casaService) PushUserInfo() {
|
|
||||||
m := model.UserInfo{}
|
|
||||||
m.Desc = config.UserInfo.Description
|
|
||||||
m.Avatar = config.UserInfo.Avatar
|
|
||||||
m.NickName = config.UserInfo.NickName
|
|
||||||
m.ShareId = config.ServerInfo.Token
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
|
|
||||||
head := make(map[string]string)
|
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
|
||||||
|
|
||||||
infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/user/info", b, "application/json", head)
|
|
||||||
|
|
||||||
info := model.ServerAppList{}
|
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *casaService) GetUserInfoByShareId(shareId string) model.UserInfo {
|
|
||||||
|
|
||||||
head := make(map[string]string)
|
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
|
||||||
|
|
||||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/user/info/"+shareId, head)
|
|
||||||
|
|
||||||
info := model.UserInfo{}
|
|
||||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
func (o *casaService) GetPersonPublic() (list []model.FriendsModel) {
|
|
||||||
head := make(map[string]string)
|
|
||||||
|
|
||||||
head["Authorization"] = GetToken()
|
|
||||||
|
|
||||||
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/person/public", head)
|
|
||||||
|
|
||||||
json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func NewCasaService() CasaService {
|
func NewCasaService() CasaService {
|
||||||
return &casaService{}
|
return &casaService{}
|
||||||
}
|
}
|
||||||
|
|||||||
69
service/connections.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-26 18:13:22
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-04 20:10:31
|
||||||
|
* @FilePath: /CasaOS/service/connections.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||||
|
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConnectionsService interface {
|
||||||
|
GetConnectionsList() (connections []model2.ConnectionsDBModel)
|
||||||
|
GetConnectionByHost(host string) (connections []model2.ConnectionsDBModel)
|
||||||
|
GetConnectionByID(id string) (connections model2.ConnectionsDBModel)
|
||||||
|
CreateConnection(connection *model2.ConnectionsDBModel)
|
||||||
|
DeleteConnection(id string)
|
||||||
|
UpdateConnection(connection *model2.ConnectionsDBModel)
|
||||||
|
MountSmaba(username, host, directory, port, mountPoint, password string) string
|
||||||
|
UnmountSmaba(mountPoint string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
type connectionsStruct struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *connectionsStruct) GetConnectionByHost(host string) (connections []model2.ConnectionsDBModel) {
|
||||||
|
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) UnmountSmaba(mountPoint string) string {
|
||||||
|
str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;UMountPorintAndRemoveDir " + mountPoint)
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnectionsService(db *gorm.DB) ConnectionsService {
|
||||||
|
return &connectionsStruct{db: db}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ type DiskService interface {
|
|||||||
DeleteMount(id string)
|
DeleteMount(id string)
|
||||||
UpdateMountPoint(m model2.SerialDisk)
|
UpdateMountPoint(m model2.SerialDisk)
|
||||||
RemoveLSBLKCache()
|
RemoveLSBLKCache()
|
||||||
|
UmountUSB(path string)
|
||||||
}
|
}
|
||||||
type diskService struct {
|
type diskService struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
@@ -45,6 +46,10 @@ func (d *diskService) RemoveLSBLKCache() {
|
|||||||
key := "system_lsblk"
|
key := "system_lsblk"
|
||||||
Cache.Delete(key)
|
Cache.Delete(key)
|
||||||
}
|
}
|
||||||
|
func (d *diskService) UmountUSB(path string) {
|
||||||
|
r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;UDEVILUmount " + path)
|
||||||
|
fmt.Println(r)
|
||||||
|
}
|
||||||
func (d *diskService) SmartCTL(path string) model.SmartctlA {
|
func (d *diskService) SmartCTL(path string) model.SmartctlA {
|
||||||
|
|
||||||
key := "system_smart_" + path
|
key := "system_smart_" + path
|
||||||
@@ -59,6 +64,7 @@ func (d *diskService) SmartCTL(path string) model.SmartctlA {
|
|||||||
str := command2.ExecSmartCTLByPath(path)
|
str := command2.ExecSmartCTLByPath(path)
|
||||||
if str == nil {
|
if str == nil {
|
||||||
loger.Error("failed to exec shell ", zap.Any("err", "smartctl exec error"))
|
loger.Error("failed to exec shell ", zap.Any("err", "smartctl exec error"))
|
||||||
|
Cache.Add(key, m, time.Minute*10)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,8 +248,9 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *diskService) MountDisk(path, volume string) {
|
func (d *diskService) MountDisk(path, volume string) {
|
||||||
|
//fmt.Println("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
|
||||||
r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
|
r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
|
||||||
fmt.Print(r)
|
fmt.Println(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import (
|
|||||||
type DockerService interface {
|
type DockerService interface {
|
||||||
DockerPullImage(imageName string, icon, name string) error
|
DockerPullImage(imageName string, icon, name string) error
|
||||||
IsExistImage(imageName string) bool
|
IsExistImage(imageName string) bool
|
||||||
DockerContainerCreate(imageName string, m model.CustomizationPostData) (containerId string, err error)
|
DockerContainerCreate(m model.CustomizationPostData, id string) (containerId string, err error)
|
||||||
DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error)
|
DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error)
|
||||||
DockerContainerStart(name string) error
|
DockerContainerStart(name string) error
|
||||||
DockerContainerStats(name string) (string, error)
|
DockerContainerStats(name string) (string, error)
|
||||||
@@ -376,7 +376,7 @@ func (ds *dockerService) DockerContainerCopyCreate(info *types.ContainerJSON) (c
|
|||||||
//param mapPort 容器主端口映射到外部的端口
|
//param mapPort 容器主端口映射到外部的端口
|
||||||
//param tcp 容器其他tcp端口
|
//param tcp 容器其他tcp端口
|
||||||
//param udp 容器其他udp端口
|
//param udp 容器其他udp端口
|
||||||
func (ds *dockerService) DockerContainerCreate(imageName string, m model.CustomizationPostData) (containerId string, err error) {
|
func (ds *dockerService) DockerContainerCreate(m model.CustomizationPostData, id string) (containerId string, err error) {
|
||||||
if len(m.NetworkModel) == 0 {
|
if len(m.NetworkModel) == 0 {
|
||||||
m.NetworkModel = "bridge"
|
m.NetworkModel = "bridge"
|
||||||
}
|
}
|
||||||
@@ -385,6 +385,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
ports := make(nat.PortSet)
|
ports := make(nat.PortSet)
|
||||||
portMaps := make(nat.PortMap)
|
portMaps := make(nat.PortMap)
|
||||||
@@ -523,15 +524,26 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
|
|||||||
if len(m.HostName) == 0 {
|
if len(m.HostName) == 0 {
|
||||||
m.HostName = m.Label
|
m.HostName = m.Label
|
||||||
}
|
}
|
||||||
config := &container.Config{
|
|
||||||
Image: imageName,
|
info, err := cli.ContainerInspect(context.Background(), id)
|
||||||
Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin, "casaos": "casaos"},
|
hostConfig := &container.HostConfig{}
|
||||||
Env: envArr,
|
config := &container.Config{}
|
||||||
// Healthcheck: health,
|
config.Labels = map[string]string{}
|
||||||
Hostname: m.HostName,
|
if err == nil {
|
||||||
Cmd: m.Cmd,
|
// info.HostConfig = &container.HostConfig{}
|
||||||
|
// info.Config = &container.Config{}
|
||||||
|
// info.NetworkSettings = &types.NetworkSettings{}
|
||||||
|
hostConfig = info.HostConfig
|
||||||
|
config = info.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.Cmd = m.Cmd
|
||||||
|
config.Image = m.Image
|
||||||
|
config.Env = envArr
|
||||||
|
config.Hostname = m.HostName
|
||||||
|
config.ExposedPorts = ports
|
||||||
|
config.Labels["origin"] = m.Origin
|
||||||
|
config.Labels["casaos"] = "casaos"
|
||||||
config.Labels["web"] = m.PortMap
|
config.Labels["web"] = m.PortMap
|
||||||
config.Labels["icon"] = m.Icon
|
config.Labels["icon"] = m.Icon
|
||||||
config.Labels["desc"] = m.Description
|
config.Labels["desc"] = m.Description
|
||||||
@@ -540,18 +552,26 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
|
|||||||
config.Labels["show_env"] = strings.Join(showENV, ",")
|
config.Labels["show_env"] = strings.Join(showENV, ",")
|
||||||
config.Labels["protocol"] = m.Protocol
|
config.Labels["protocol"] = m.Protocol
|
||||||
config.Labels["host"] = m.Host
|
config.Labels["host"] = m.Host
|
||||||
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(m.NetworkModel), Privileged: m.Privileged, CapAdd: m.CapAdd}
|
config.Labels["name"] = m.Label
|
||||||
|
//container, err := cli.ContainerCreate(context.Background(), info.Config, info.HostConfig, &network.NetworkingConfig{info.NetworkSettings.Networks}, nil, info.Name)
|
||||||
|
|
||||||
|
hostConfig.Mounts = volumes
|
||||||
|
hostConfig.Privileged = m.Privileged
|
||||||
|
hostConfig.CapAdd = m.CapAdd
|
||||||
|
hostConfig.NetworkMode = container.NetworkMode(m.NetworkModel)
|
||||||
|
hostConfig.RestartPolicy = rp
|
||||||
|
hostConfig.Resources = res
|
||||||
|
//hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: , Privileged: m.Privileged, CapAdd: m.CapAdd}
|
||||||
//if net != "host" {
|
//if net != "host" {
|
||||||
config.ExposedPorts = ports
|
|
||||||
hostConfig.PortBindings = portMaps
|
hostConfig.PortBindings = portMaps
|
||||||
//}
|
//}
|
||||||
|
|
||||||
containerDb, err := cli.ContainerCreate(context.Background(),
|
containerDb, err := cli.ContainerCreate(context.Background(),
|
||||||
config,
|
config,
|
||||||
hostConfig,
|
hostConfig,
|
||||||
&network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{m.NetworkModel: {NetworkID: "", Aliases: []string{}}}},
|
&network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{m.NetworkModel: {NetworkID: "", Aliases: []string{}}}},
|
||||||
nil,
|
nil,
|
||||||
m.Label)
|
m.ContainerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DownRecordService interface {
|
|
||||||
AddDownRecord(m model2.PersonDownRecordDBModel)
|
|
||||||
GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel
|
|
||||||
GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel)
|
|
||||||
}
|
|
||||||
type downRecordService struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downRecordService) AddDownRecord(m model2.PersonDownRecordDBModel) {
|
|
||||||
d.db.Create(&m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downRecordService) GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel {
|
|
||||||
var m []model2.PersonDownRecordDBModel
|
|
||||||
d.db.Model(m).Where("from = ?", id).Find(&m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (d *downRecordService) GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel) {
|
|
||||||
d.db.Where("path = ?", path).Find(&list)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDownRecordService(db *gorm.DB) DownRecordService {
|
|
||||||
return &downRecordService{db: db}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DownloadService interface {
|
|
||||||
AddDownloadTask(m model2.PersonDownloadDBModel) //添加下载任务
|
|
||||||
EditDownloadState(m model2.PersonDownloadDBModel) //只修改状态
|
|
||||||
SaveDownload(m model2.PersonDownloadDBModel)
|
|
||||||
DelDownload(uuid string)
|
|
||||||
GetDownloadById(uuid string) model2.PersonDownloadDBModel
|
|
||||||
GetDownloadListByState(state string, t int) []model2.PersonDownloadDBModel
|
|
||||||
SetDownloadError(m model2.PersonDownloadDBModel)
|
|
||||||
GetDownloadListByPath(m model2.PersonDownloadDBModel) int
|
|
||||||
}
|
|
||||||
type downloadService struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downloadService) GetDownloadListByPath(m model2.PersonDownloadDBModel) int {
|
|
||||||
var list []model2.PersonDownloadDBModel
|
|
||||||
d.db.Select("path").Where("path = ? AND `from` = ? AND state = 0", m.Path, m.From).Find(&list)
|
|
||||||
return len(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downloadService) AddDownloadTask(m model2.PersonDownloadDBModel) {
|
|
||||||
|
|
||||||
d.db.Create(&m)
|
|
||||||
}
|
|
||||||
func (d *downloadService) EditDownloadState(m model2.PersonDownloadDBModel) {
|
|
||||||
|
|
||||||
d.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State)
|
|
||||||
}
|
|
||||||
|
|
||||||
//failed during download
|
|
||||||
func (d *downloadService) SetDownloadError(m model2.PersonDownloadDBModel) {
|
|
||||||
d.db.Model(&m).Updates(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downloadService) DelDownload(uuid string) {
|
|
||||||
var m model2.PersonDownloadDBModel
|
|
||||||
d.db.Where("uuid = ?", uuid).Delete(&m)
|
|
||||||
}
|
|
||||||
func (d *downloadService) GetDownloadById(uuid string) model2.PersonDownloadDBModel {
|
|
||||||
var m model2.PersonDownloadDBModel
|
|
||||||
d.db.Model(m).Where("uuid = ?", uuid).First(&m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (d *downloadService) GetDownloadListByState(state string, t int) (list []model2.PersonDownloadDBModel) {
|
|
||||||
if len(state) == 0 {
|
|
||||||
d.db.Where("type = ?", t).Find(&list)
|
|
||||||
} else {
|
|
||||||
d.db.Where("state = ? AND type= ?", state, t).Find(&list)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *downloadService) SaveDownload(m model2.PersonDownloadDBModel) {
|
|
||||||
d.db.Save(&m)
|
|
||||||
}
|
|
||||||
func NewDownloadService(db *gorm.DB) DownloadService {
|
|
||||||
return &downloadService{db: db}
|
|
||||||
}
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
|
||||||
uuid "github.com/satori/go.uuid"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FriendService interface {
|
|
||||||
AddFriend(m model2.FriendModel)
|
|
||||||
DeleteFriend(m model2.FriendModel)
|
|
||||||
EditFriendMark(m model2.FriendModel)
|
|
||||||
EditFriendWrite(m model2.FriendModel)
|
|
||||||
EditFriendBlock(m model2.FriendModel)
|
|
||||||
GetFriendById(m model2.FriendModel) model2.FriendModel
|
|
||||||
GetFriendList() (list []model2.FriendModel)
|
|
||||||
GetFriendListRemote() (list []model2.FriendModel)
|
|
||||||
UpdateAddFriendType(m model2.FriendModel)
|
|
||||||
AgreeFrined(id string)
|
|
||||||
GetFriendByToken(token string) model2.FriendModel
|
|
||||||
UpdateOrCreate(m model2.FriendModel)
|
|
||||||
InternalInspection(ips []string, token string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type friendService struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *friendService) AgreeFrined(id string) {
|
|
||||||
var m model2.FriendModel
|
|
||||||
p.db.Model(&m).Where("token = ?", id).Update("state", types.FRIENDSTATEDEFAULT)
|
|
||||||
}
|
|
||||||
func (p *friendService) AddFriend(m model2.FriendModel) {
|
|
||||||
p.db.Create(&m)
|
|
||||||
}
|
|
||||||
func (p *friendService) DeleteFriend(m model2.FriendModel) {
|
|
||||||
p.db.Where("token = ?", m.Token).Delete(&m)
|
|
||||||
}
|
|
||||||
func (p *friendService) EditFriendMark(m model2.FriendModel) {
|
|
||||||
p.db.Model(&m).Where("token = ?", m.Token).Update("mark", m.Mark)
|
|
||||||
}
|
|
||||||
func (p *friendService) EditFriendWrite(m model2.FriendModel) {
|
|
||||||
p.db.Model(&m).Where("token = ?", m.Token).Update("write", m.Write)
|
|
||||||
}
|
|
||||||
func (p *friendService) EditFriendBlock(m model2.FriendModel) {
|
|
||||||
p.db.Model(&m).Where("token = ?", m.Token).Update("block", m.Block)
|
|
||||||
}
|
|
||||||
func (p *friendService) GetFriendById(m model2.FriendModel) model2.FriendModel {
|
|
||||||
p.db.Model(m).Where("token = ?", m.Token).First(&m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *friendService) GetFriendList() (list []model2.FriendModel) {
|
|
||||||
p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Find(&list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func (p *friendService) GetFriendListRemote() (list []model2.FriendModel) {
|
|
||||||
p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip == '' OR internal_ip is null").Find(&list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func (p *friendService) GetFriendListInternal() (list []model2.FriendModel) {
|
|
||||||
p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip != ''").Find(&list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func (p *friendService) UpdateOrCreate(m model2.FriendModel) {
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
p.db.Where("token = ?", m.Token).First(&friend)
|
|
||||||
if reflect.DeepEqual(friend, model2.FriendModel{}) {
|
|
||||||
p.db.Create(&m)
|
|
||||||
} else {
|
|
||||||
p.db.Model(&m).Updates(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *friendService) UpdateAddFriendType(m model2.FriendModel) {
|
|
||||||
p.db.Model(&m).Updates(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *friendService) GetFriendByToken(token string) model2.FriendModel {
|
|
||||||
var m model2.FriendModel
|
|
||||||
p.db.Model(&m).Where("token = ?", token).First(&m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *friendService) InternalInspection(ips []string, token string) {
|
|
||||||
for _, v := range ips {
|
|
||||||
fmt.Println("开始遍历 ip:", v)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
dstAddr, err := net.ResolveUDPAddr("udp", v)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("1", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
port, err := strconv.Atoi(config.ServerInfo.UDPPort)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("2", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
srcAddr := &net.UDPAddr{
|
|
||||||
IP: net.IPv4zero, Port: port}
|
|
||||||
ticket := token
|
|
||||||
session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("3", err, v)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err := session.OpenStreamSync(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("4", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
uuid := uuid.NewV4().String()
|
|
||||||
SayHello(stream, token)
|
|
||||||
msg := model.MessageModel{
|
|
||||||
Type: types.PERSONPING,
|
|
||||||
Data: "",
|
|
||||||
From: config.ServerInfo.Token,
|
|
||||||
To: token,
|
|
||||||
UUId: uuid,
|
|
||||||
}
|
|
||||||
|
|
||||||
SendData(stream, msg)
|
|
||||||
|
|
||||||
go ReadContent(stream)
|
|
||||||
result := <-Message
|
|
||||||
fmt.Println("ping返回结果:", result, msg)
|
|
||||||
stream.Close()
|
|
||||||
if !reflect.DeepEqual(result, model.MessageModel{}) && result.Data.(string) == token && result.From == token {
|
|
||||||
fmt.Println("获取到正确的ip", v)
|
|
||||||
UDPAddressMap[result.From] = v
|
|
||||||
p.db.Model(&model2.FriendModel{}).Where("token = ?", token).Update("internal_ip", v)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFriendService(db *gorm.DB) FriendService {
|
|
||||||
return &friendService{db: db}
|
|
||||||
}
|
|
||||||
28
service/model/o_connections.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-26 17:17:57
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-01 17:08:08
|
||||||
|
* @FilePath: /CasaOS/service/model/o_connections.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type ConnectionsDBModel struct {
|
||||||
|
ID uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Directories string `json:"directories"` // string array
|
||||||
|
MountPoint string `json:"mount_point"` //parent directory of mount point
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ConnectionsDBModel) TableName() string {
|
||||||
|
return "o_connections"
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-05-30 17:33:21
|
* @LastEditTime: 2022-07-13 10:56:34
|
||||||
* @FilePath: /CasaOS/service/model/o_container.go
|
* @FilePath: /CasaOS/service/model/o_container.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -67,13 +67,12 @@ type MyAppList struct {
|
|||||||
Index string `json:"index"`
|
Index string `json:"index"`
|
||||||
//Order string `json:"order"`
|
//Order string `json:"order"`
|
||||||
Port string `json:"port"`
|
Port string `json:"port"`
|
||||||
UpTime string `json:"up_time"`
|
|
||||||
Slogan string `json:"slogan"`
|
Slogan string `json:"slogan"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
//Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
|
//Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
Volumes string `json:"volumes"`
|
Volumes string `json:"volumes"`
|
||||||
NewVersion bool `json:"new_version"`
|
Latest bool `json:"latest"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type PersonDownRecordDBModel struct {
|
|
||||||
UUID string `gorm:"column:uuid;primary_key" json:"uuid"`
|
|
||||||
Name string `json:"name"` //file name
|
|
||||||
Type int `json:"type"`
|
|
||||||
Size int64 `json:"size"` //file size
|
|
||||||
Downloader string `json:"downloader"` //Error message
|
|
||||||
Path string `json:"path"`
|
|
||||||
Created int64 `gorm:"autoCreateTime" json:"created"`
|
|
||||||
Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PersonDownRecordDBModel) TableName() string {
|
|
||||||
return "o_person_down_record"
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type PersonDownloadDBModel struct {
|
|
||||||
UUID string `gorm:"column:uuid;primary_key" json:"uuid"`
|
|
||||||
State int `json:"state"` //
|
|
||||||
Type int `json:"type"` //defult 0
|
|
||||||
Name string `json:"name"` //file name
|
|
||||||
Size int64 `json:"size"` //file size
|
|
||||||
BlockSize int `json:"block_size"` //Size of each file block
|
|
||||||
Length int `json:"length"` //slice length
|
|
||||||
Hash string `json:"hash"` //File hash value
|
|
||||||
Error string `json:"error"` //
|
|
||||||
From string `json:"from"` //Error message
|
|
||||||
Path string `json:"path"` //Full path to the file
|
|
||||||
Already int `json:"already" gorm:"-"` //Folder blocks that have been downloaded
|
|
||||||
LocalPath string `json:"local_path"` //The address where the file is saved after download
|
|
||||||
Duration int64 `json:"duration" gorm:"-"` //Length of time
|
|
||||||
Created int64 `gorm:"autoCreateTime" json:"created"`
|
|
||||||
Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PersonDownloadDBModel) TableName() string {
|
|
||||||
return "o_person_download"
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type FriendModel struct {
|
|
||||||
State int `json:"state"`
|
|
||||||
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
|
|
||||||
UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"`
|
|
||||||
NickName string `json:"nick_name"`
|
|
||||||
Mark string `json:"mark"` //Remarks
|
|
||||||
Block bool `json:"block"` //Disable or not
|
|
||||||
Avatar string `json:"avatar"` //User avatar
|
|
||||||
Token string `gorm:"column:token;primary_key" json:"token"`
|
|
||||||
Profile string `json:"profile"` //Description
|
|
||||||
OnLine bool `json:"on_line" gorm:"-"`
|
|
||||||
Version int `json:"version"`
|
|
||||||
Write bool `json:"write"`
|
|
||||||
LocalIP string `json:"local_ip"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *FriendModel) TableName() string {
|
|
||||||
return "o_friend"
|
|
||||||
}
|
|
||||||
24
service/model/o_shares.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-26 11:17:17
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-07-27 15:25:07
|
||||||
|
* @FilePath: /CasaOS/service/model/o_shares.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package model
|
||||||
|
|
||||||
|
type SharesDBModel struct {
|
||||||
|
ID uint `gorm:"column:id;primary_key" json:"id"`
|
||||||
|
Anonymous bool `json:"anonymous"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SharesDBModel) TableName() string {
|
||||||
|
return "o_shares"
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type ShortcutsDBModel struct {
|
|
||||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
Icon string `json:"icon"`
|
|
||||||
Sort int `json:"sort"`
|
|
||||||
CreatedAt time.Time `gorm:"<-:create" json:"created_at"`
|
|
||||||
UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ShortcutsDBModel) TableName() string {
|
|
||||||
return "o_shortcuts"
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-05-13 18:15:46
|
* @Date: 2022-05-13 18:15:46
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-23 15:43:07
|
* @LastEditTime: 2022-07-11 17:57:00
|
||||||
* @FilePath: /CasaOS/service/model/o_user.go
|
* @FilePath: /CasaOS/service/model/o_user.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -15,11 +15,11 @@ import "time"
|
|||||||
//Soon to be removed
|
//Soon to be removed
|
||||||
type UserDBModel struct {
|
type UserDBModel struct {
|
||||||
Id int `gorm:"column:id;primary_key" json:"id"`
|
Id int `gorm:"column:id;primary_key" json:"id"`
|
||||||
UserName string `json:"user_name"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
NickName string `json:"nick_name"`
|
Nickname string `json:"nickname"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at,omitempty"`
|
CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at,omitempty"`
|
||||||
@@ -27,5 +27,5 @@ type UserDBModel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *UserDBModel) TableName() string {
|
func (p *UserDBModel) TableName() string {
|
||||||
return "o_user"
|
return "o_users"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,16 +33,31 @@ type NotifyServer interface {
|
|||||||
SendMemInfoBySocket(mem map[string]interface{})
|
SendMemInfoBySocket(mem map[string]interface{})
|
||||||
SendUSBInfoBySocket(list []model2.DriveUSB)
|
SendUSBInfoBySocket(list []model2.DriveUSB)
|
||||||
SendDiskInfoBySocket(disk model2.Summary)
|
SendDiskInfoBySocket(disk model2.Summary)
|
||||||
SendPersonStatusBySocket(status notify.Person)
|
|
||||||
SendFileOperateNotify(nowSend bool)
|
SendFileOperateNotify(nowSend bool)
|
||||||
SendInstallAppBySocket(app notify.Application)
|
SendInstallAppBySocket(app notify.Application)
|
||||||
SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat)
|
SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat)
|
||||||
|
SendStorageBySocket(message notify.StorageMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
type notifyServer struct {
|
type notifyServer struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *notifyServer) SendStorageBySocket(message notify.StorageMessage) {
|
||||||
|
body := make(map[string]interface{})
|
||||||
|
body["data"] = message
|
||||||
|
|
||||||
|
msg := gosf.Message{}
|
||||||
|
msg.Body = body
|
||||||
|
msg.Success = true
|
||||||
|
msg.Text = "storage_status"
|
||||||
|
|
||||||
|
notify := notify.Message{}
|
||||||
|
notify.Path = "storage_status"
|
||||||
|
notify.Msg = msg
|
||||||
|
|
||||||
|
NotifyMsg <- notify
|
||||||
|
}
|
||||||
func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) {
|
func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) {
|
||||||
|
|
||||||
body := make(map[string]interface{})
|
body := make(map[string]interface{})
|
||||||
@@ -224,22 +239,6 @@ func (i *notifyServer) SendFileOperateNotify(nowSend bool) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *notifyServer) SendPersonStatusBySocket(status notify.Person) {
|
|
||||||
body := make(map[string]interface{})
|
|
||||||
body["data"] = status
|
|
||||||
|
|
||||||
msg := gosf.Message{}
|
|
||||||
msg.Body = body
|
|
||||||
msg.Success = true
|
|
||||||
msg.Text = "person_status"
|
|
||||||
|
|
||||||
notify := notify.Message{}
|
|
||||||
notify.Path = "person_status"
|
|
||||||
notify.Msg = msg
|
|
||||||
|
|
||||||
NotifyMsg <- notify
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *notifyServer) SendDiskInfoBySocket(disk model2.Summary) {
|
func (i *notifyServer) SendDiskInfoBySocket(disk model2.Summary) {
|
||||||
body := make(map[string]interface{})
|
body := make(map[string]interface{})
|
||||||
body["data"] = disk
|
body["data"] = disk
|
||||||
|
|||||||
@@ -1,482 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
|
||||||
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
|
||||||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PersonService interface {
|
|
||||||
GetPersionInfo(token string) (m model.PersionModel, err error)
|
|
||||||
GetPersionNetWorkTypeDetection() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type personService struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
var IpInfo model.PersionModel
|
|
||||||
var CancelList map[string]string
|
|
||||||
var InternalInspection map[string][]string
|
|
||||||
|
|
||||||
func PushIpInfo(token string) {
|
|
||||||
|
|
||||||
m := model.PersionModel{}
|
|
||||||
m.Ips = ip_helper.GetDeviceAllIP("")
|
|
||||||
m.Token = token
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
|
|
||||||
if reflect.DeepEqual(IpInfo, m) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
head := make(map[string]string)
|
|
||||||
infoS := httper2.Post(config.ServerInfo.Handshake+"/v1/update", b, "application/json", head)
|
|
||||||
fmt.Println(infoS)
|
|
||||||
}
|
|
||||||
func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err error) {
|
|
||||||
infoS := httper2.Get(config.ServerInfo.Handshake+"/v1/ips/"+token, nil)
|
|
||||||
err = json.Unmarshal([]byte(infoS), &m)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (p *personService) GetPersionNetWorkTypeDetection() string {
|
|
||||||
data := make(chan string)
|
|
||||||
list := []string{"stun.l.google.com", "stun1.l.google.com", "stun2.l.google.com", "stun.sipgate.net"}
|
|
||||||
for _, v := range list {
|
|
||||||
go utils.GetNetWorkTypeDetection(data, v)
|
|
||||||
}
|
|
||||||
result := <-data
|
|
||||||
close(data)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPersonService(db *gorm.DB) PersonService {
|
|
||||||
return &personService{db: db}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================================================================================================================
|
|
||||||
|
|
||||||
var StreamList map[string]quic.Stream
|
|
||||||
var ServiceMessage chan model.MessageModel
|
|
||||||
|
|
||||||
func UDPService() {
|
|
||||||
port := 0
|
|
||||||
if len(config.ServerInfo.UDPPort) > 0 {
|
|
||||||
port, _ = strconv.Atoi(config.ServerInfo.UDPPort)
|
|
||||||
if port != 0 && !port2.IsPortAvailable(port, "udp") {
|
|
||||||
port = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srcAddr := &net.UDPAddr{
|
|
||||||
IP: net.IPv4zero, Port: port}
|
|
||||||
var err error
|
|
||||||
UDPConn, err = net.ListenUDP("udp", srcAddr)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
listener, err := quic.Listen(UDPConn, quic_helper.GetGenerateTLSConfig(config.ServerInfo.Token), quic_helper.GetQUICConfig())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
defer listener.Close()
|
|
||||||
ctx := context.Background()
|
|
||||||
acceptFailures := 0
|
|
||||||
const maxAcceptFailures = 10
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
fmt.Println(ctx.Err())
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
session, err := listener.Accept(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Listen (BEP/quic): Accepting connection:", err)
|
|
||||||
|
|
||||||
acceptFailures++
|
|
||||||
if acceptFailures > maxAcceptFailures {
|
|
||||||
// Return to restart the listener, because something
|
|
||||||
// seems permanently damaged.
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slightly increased delay for each failure.
|
|
||||||
time.Sleep(time.Duration(acceptFailures) * time.Second)
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
acceptFailures = 0
|
|
||||||
|
|
||||||
streamCtx, cancel := context.WithTimeout(ctx, time.Second*10)
|
|
||||||
stream, err := session.AcceptStream(streamCtx)
|
|
||||||
cancel()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("failed to accept stream from %s: %v", session.RemoteAddr(), err)
|
|
||||||
_ = session.CloseWithError(1, err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefixByte := make([]byte, 4)
|
|
||||||
// c1, err := io.ReadFull(stream, prefixByte)
|
|
||||||
// fmt.Println(c1, err)
|
|
||||||
// prefixLength, err := strconv.Atoi(string(prefixByte))
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// }
|
|
||||||
// messageByte := make([]byte, prefixLength)
|
|
||||||
// t, err := io.ReadFull(stream, messageByte)
|
|
||||||
// fmt.Println(t, err)
|
|
||||||
// m := model.MessageModel{}
|
|
||||||
// err = json.Unmarshal(messageByte, &m)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
go ProcessingContent(stream)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//处理内容
|
|
||||||
func ProcessingContent(stream quic.Stream) {
|
|
||||||
for {
|
|
||||||
prefixByte := make([]byte, 6)
|
|
||||||
_, err := io.ReadFull(stream, prefixByte)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
prefixLength, err := strconv.Atoi(string(prefixByte))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
messageByte := make([]byte, prefixLength)
|
|
||||||
_, err = io.ReadFull(stream, messageByte)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m := model.MessageModel{}
|
|
||||||
err = json.Unmarshal(messageByte, &m)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
if m.Type == types.PERSONHELLO {
|
|
||||||
//nothing
|
|
||||||
continue
|
|
||||||
} else if m.Type == types.PERSONDIRECTORY {
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = m.From
|
|
||||||
var list []model.Path
|
|
||||||
rFriend := MyService.Friend().GetFriendById(friend)
|
|
||||||
if !reflect.DeepEqual(rFriend, model2.FriendModel{Token: m.From}) && !rFriend.Block {
|
|
||||||
if m.Data.(string) == "" || m.Data.(string) == "/" {
|
|
||||||
for _, v := range config.FileSettingInfo.ShareDir {
|
|
||||||
//tempList := MyService.ZiMa().GetDirPath(v)
|
|
||||||
temp := MyService.System().GetDirPathOne(v)
|
|
||||||
list = append(list, temp)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list = MyService.System().GetDirPath(m.Data.(string))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list = []model.Path{}
|
|
||||||
}
|
|
||||||
if rFriend.Write {
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
list[i].Write = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.To = m.From
|
|
||||||
m.Data = list
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
SendData(stream, m)
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONDOWNLOAD {
|
|
||||||
|
|
||||||
SendFileData(stream, m.Data.(string), m.From, m.UUId, types.PERSONDOWNLOAD)
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONADDFRIEND {
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
dataModelByte, _ := json.Marshal(m.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &friend)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
go MyService.Friend().UpdateOrCreate(friend)
|
|
||||||
mi := model2.FriendModel{}
|
|
||||||
mi.Avatar = config.UserInfo.Avatar
|
|
||||||
mi.Profile = config.UserInfo.Description
|
|
||||||
mi.NickName = config.UserInfo.NickName
|
|
||||||
m.To = m.From
|
|
||||||
m.Data = mi
|
|
||||||
m.Type = types.PERSONADDFRIEND
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
|
|
||||||
SendData(stream, m)
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONCONNECTION {
|
|
||||||
if len(m.Data.(string)) > 0 {
|
|
||||||
fmt.Println("设置ip", m.Data.(string))
|
|
||||||
UDPAddressMap[m.From] = m.Data.(string)
|
|
||||||
} else {
|
|
||||||
delete(UDPAddressMap, m.From)
|
|
||||||
}
|
|
||||||
// mi := model2.FriendModel{}
|
|
||||||
// mi.Avatar = config.UserInfo.Avatar
|
|
||||||
// mi.Profile = config.UserInfo.Description
|
|
||||||
// mi.NickName = config.UserInfo.NickName
|
|
||||||
// mi.Token = config.ServerInfo.Token
|
|
||||||
|
|
||||||
user := MyService.Casa().GetUserInfoByShareId(m.From)
|
|
||||||
//好友申请 //不是好友
|
|
||||||
friend := model2.FriendModel{}
|
|
||||||
friend.Token = m.From
|
|
||||||
friend.Avatar = user.Avatar
|
|
||||||
friend.Block = false
|
|
||||||
friend.NickName = user.NickName
|
|
||||||
friend.Profile = user.Avatar
|
|
||||||
friend.Write = false
|
|
||||||
friend.Version = user.Version
|
|
||||||
if len(config.UserInfo.Public) > 0 {
|
|
||||||
friend.State = types.FRIENDSTATEREQUEST
|
|
||||||
}
|
|
||||||
MyService.Friend().AddFriend(friend)
|
|
||||||
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONHELLO
|
|
||||||
msg.Data = ""
|
|
||||||
msg.To = m.From
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.UUId = m.UUId
|
|
||||||
Dial(msg, false)
|
|
||||||
|
|
||||||
//agree user
|
|
||||||
if len(config.UserInfo.Public) == 0 {
|
|
||||||
msg.Type = types.PERSONAGREEFRIEND
|
|
||||||
msg.Data = ""
|
|
||||||
msg.To = m.From
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.UUId = m.UUId
|
|
||||||
Dial(msg, true)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONAGREEFRIEND {
|
|
||||||
MyService.Friend().AgreeFrined(m.From)
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONCANCEL {
|
|
||||||
CancelList[m.UUId] = "cancel"
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONSUMMARY {
|
|
||||||
Summary(m, "upload")
|
|
||||||
continue
|
|
||||||
} else if m.Type == types.PERSONUPLOAD {
|
|
||||||
//TODO:检查是否存在如果存在直接结束
|
|
||||||
task := model2.PersonDownloadDBModel{}
|
|
||||||
task.UUID = m.UUId
|
|
||||||
task.LocalPath = m.Data.(string)
|
|
||||||
MyService.Download().AddDownloadTask(task)
|
|
||||||
friend := MyService.Friend().GetFriendById(model2.FriendModel{Token: m.From})
|
|
||||||
if friend.Write {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if m.Type == types.PERSONUPLOADDATA {
|
|
||||||
r := SaveFile(m, stream)
|
|
||||||
if r {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
} else if m.Type == types.PERSONINTERNALINSPECTION {
|
|
||||||
fmt.Println("内网测试")
|
|
||||||
var ips []string
|
|
||||||
dataModelByte, _ := json.Marshal(m.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &ips)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
go MyService.Friend().InternalInspection(ips, m.From)
|
|
||||||
|
|
||||||
} else if m.Type == types.PERSONPING {
|
|
||||||
fmt.Println("来自", m.From, "的ping", m.Data)
|
|
||||||
msg := m
|
|
||||||
m.To = m.From
|
|
||||||
m.Data = config.ServerInfo.Token
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
SendData(stream, m)
|
|
||||||
|
|
||||||
var ips []string
|
|
||||||
dataModelByte, _ := json.Marshal(msg.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &ips)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
backIP := false
|
|
||||||
if v, ok := UDPAddressMap[msg.From]; ok {
|
|
||||||
for _, ip := range ips {
|
|
||||||
if ip == v {
|
|
||||||
backIP = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !backIP {
|
|
||||||
fmt.Println("检测需要查询ip", msg.From)
|
|
||||||
go MyService.Friend().InternalInspection(ips, msg.From)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONIMAGETHUMBNAIL {
|
|
||||||
m.To = m.From
|
|
||||||
|
|
||||||
if data, err := file.GetImage(m.Data.(string), 100, 0); err == nil {
|
|
||||||
m.Data = data
|
|
||||||
} else {
|
|
||||||
m.Data = ""
|
|
||||||
}
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
SendData(stream, m)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
//不应有不做返回的数据
|
|
||||||
//ServiceMessage <- m
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stream.Close()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//文件分片发送
|
|
||||||
func SendFileData(stream quic.Stream, filePath, to, uuid, t string) error {
|
|
||||||
summary := model.FileSummaryModel{}
|
|
||||||
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONSUMMARY
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = to
|
|
||||||
msg.UUId = uuid
|
|
||||||
|
|
||||||
fStat, err := os.Stat(filePath)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
summary.Message = err.Error()
|
|
||||||
|
|
||||||
msg.Data = summary
|
|
||||||
|
|
||||||
summaryByte, _ := json.Marshal(msg)
|
|
||||||
summaryPrefixLength := file.PrefixLength(len(summaryByte))
|
|
||||||
summaryData := append(summaryPrefixLength, summaryByte...)
|
|
||||||
stream.Write(summaryData)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
blockSize, length := file.GetBlockInfo(fStat.Size())
|
|
||||||
|
|
||||||
f, err := os.Open(filePath)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
summary.Message = err.Error()
|
|
||||||
msg.Data = summary
|
|
||||||
|
|
||||||
summaryByte, _ := json.Marshal(msg)
|
|
||||||
summaryPrefixLength := file.PrefixLength(len(summaryByte))
|
|
||||||
summaryData := append(summaryPrefixLength, summaryByte...)
|
|
||||||
stream.Write(summaryData)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
//send file summary first
|
|
||||||
summary.BlockSize = blockSize
|
|
||||||
summary.Hash = file.GetHashByPath(filePath)
|
|
||||||
summary.Length = length
|
|
||||||
summary.Name = fStat.Name()
|
|
||||||
summary.Size = fStat.Size()
|
|
||||||
|
|
||||||
msg.Data = summary
|
|
||||||
|
|
||||||
summaryByte, _ := json.Marshal(msg)
|
|
||||||
summaryPrefixLength := file.PrefixLength(len(summaryByte))
|
|
||||||
summaryData := append(summaryPrefixLength, summaryByte...)
|
|
||||||
stream.Write(summaryData)
|
|
||||||
|
|
||||||
bufferedReader := bufio.NewReader(f)
|
|
||||||
buf := make([]byte, blockSize)
|
|
||||||
|
|
||||||
defer stream.Close()
|
|
||||||
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
|
|
||||||
tran := model.TranFileModel{}
|
|
||||||
|
|
||||||
n, err := bufferedReader.Read(buf)
|
|
||||||
|
|
||||||
if err == io.EOF {
|
|
||||||
fmt.Println("读取完毕", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tran.Hash = file.GetHashByContent(buf[:n])
|
|
||||||
tran.Index = i
|
|
||||||
tran.Length = length
|
|
||||||
|
|
||||||
fileMsg := model.MessageModel{}
|
|
||||||
fileMsg.Type = t
|
|
||||||
fileMsg.Data = tran
|
|
||||||
fileMsg.From = config.ServerInfo.Token
|
|
||||||
fileMsg.To = to
|
|
||||||
fileMsg.UUId = uuid
|
|
||||||
b, _ := json.Marshal(fileMsg)
|
|
||||||
prefixLength := file.PrefixLength(len(b))
|
|
||||||
dataLength := file.DataLength(len(buf[:n]))
|
|
||||||
data := append(append(append(prefixLength, b...), dataLength...), buf[:n]...)
|
|
||||||
if _, ok := CancelList[uuid]; ok {
|
|
||||||
delete(CancelList, uuid)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
stream.Write(data)
|
|
||||||
}
|
|
||||||
record := model2.PersonDownRecordDBModel{}
|
|
||||||
record.UUID = uuid
|
|
||||||
record.Name = f.Name()
|
|
||||||
record.Downloader = to
|
|
||||||
record.Path = filePath
|
|
||||||
record.Size = fStat.Size()
|
|
||||||
record.Type = types.PERSONFILEDOWNLOAD
|
|
||||||
if t == types.PERSONUPLOADDATA {
|
|
||||||
record.Type = types.PERSONFILEUPLOAD
|
|
||||||
}
|
|
||||||
|
|
||||||
MyService.DownRecord().AddDownRecord(record)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -35,6 +35,8 @@ func (r *relyService) Create(rely model2.RelyDBModel) {
|
|||||||
func (r *relyService) GetInfo(id string) model2.RelyDBModel {
|
func (r *relyService) GetInfo(id string) model2.RelyDBModel {
|
||||||
var m model2.RelyDBModel
|
var m model2.RelyDBModel
|
||||||
r.db.Where("custom_id = ?", id).First(&m)
|
r.db.Where("custom_id = ?", id).First(&m)
|
||||||
|
|
||||||
|
// @tiger - 作为出参不应该直接返回数据库内的格式(见类似问题的注释)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.com
|
||||||
|
* @Date: 2022-07-12 09:48:56
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-07-27 10:28:48
|
||||||
|
* @FilePath: /CasaOS/service/service.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -23,15 +33,11 @@ type Repository interface {
|
|||||||
Notify() NotifyServer
|
Notify() NotifyServer
|
||||||
Rely() RelyService
|
Rely() RelyService
|
||||||
System() SystemService
|
System() SystemService
|
||||||
Shortcuts() ShortcutsService
|
Shares() SharesService
|
||||||
Person() PersonService
|
Connections() ConnectionsService
|
||||||
Friend() FriendService
|
|
||||||
Download() DownloadService
|
|
||||||
DownRecord() DownRecordService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(db *gorm.DB) Repository {
|
func NewService(db *gorm.DB) Repository {
|
||||||
|
|
||||||
return &store{
|
return &store{
|
||||||
app: NewAppService(db),
|
app: NewAppService(db),
|
||||||
user: NewUserService(db),
|
user: NewUserService(db),
|
||||||
@@ -41,11 +47,8 @@ func NewService(db *gorm.DB) Repository {
|
|||||||
notify: NewNotifyService(db),
|
notify: NewNotifyService(db),
|
||||||
rely: NewRelyService(db),
|
rely: NewRelyService(db),
|
||||||
system: NewSystemService(),
|
system: NewSystemService(),
|
||||||
shortcuts: NewShortcutsService(db),
|
shares: NewSharesService(db),
|
||||||
person: NewPersonService(db),
|
connections: NewConnectionsService(db),
|
||||||
friend: NewFriendService(db),
|
|
||||||
download: NewDownloadService(db),
|
|
||||||
downrecord: NewDownRecordService(db),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,32 +62,21 @@ type store struct {
|
|||||||
notify NotifyServer
|
notify NotifyServer
|
||||||
rely RelyService
|
rely RelyService
|
||||||
system SystemService
|
system SystemService
|
||||||
shortcuts ShortcutsService
|
shares SharesService
|
||||||
person PersonService
|
connections ConnectionsService
|
||||||
friend FriendService
|
|
||||||
download DownloadService
|
|
||||||
downrecord DownRecordService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *store) DownRecord() DownRecordService {
|
func (s *store) Connections() ConnectionsService {
|
||||||
return c.downrecord
|
return s.connections
|
||||||
|
}
|
||||||
|
func (s *store) Shares() SharesService {
|
||||||
|
return s.shares
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *store) Download() DownloadService {
|
|
||||||
return c.download
|
|
||||||
}
|
|
||||||
func (c *store) Friend() FriendService {
|
|
||||||
return c.friend
|
|
||||||
}
|
|
||||||
func (c *store) Rely() RelyService {
|
func (c *store) Rely() RelyService {
|
||||||
return c.rely
|
return c.rely
|
||||||
}
|
}
|
||||||
func (c *store) Shortcuts() ShortcutsService {
|
|
||||||
return c.shortcuts
|
|
||||||
}
|
|
||||||
func (c *store) Person() PersonService {
|
|
||||||
return c.person
|
|
||||||
}
|
|
||||||
func (c *store) System() SystemService {
|
func (c *store) System() SystemService {
|
||||||
return c.system
|
return c.system
|
||||||
}
|
}
|
||||||
|
|||||||
151
service/shares.go
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* @Author: LinkLeong link@icewhale.org
|
||||||
|
* @Date: 2022-07-26 11:21:14
|
||||||
|
* @LastEditors: LinkLeong
|
||||||
|
* @LastEditTime: 2022-08-11 14:04:00
|
||||||
|
* @FilePath: /CasaOS/service/shares.go
|
||||||
|
* @Description:
|
||||||
|
* @Website: https://www.casaos.io
|
||||||
|
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SharesService interface {
|
||||||
|
GetSharesList() (shares []model2.SharesDBModel)
|
||||||
|
GetSharesByPath(path string) (shares []model2.SharesDBModel)
|
||||||
|
GetSharesByName(name string) (shares []model2.SharesDBModel)
|
||||||
|
CreateShare(share model2.SharesDBModel)
|
||||||
|
DeleteShare(id string)
|
||||||
|
UpdateConfigFile()
|
||||||
|
InitSambaConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
type sharesStruct struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sharesStruct) GetSharesByName(name string) (shares []model2.SharesDBModel) {
|
||||||
|
s.db.Select("anonymous,path,id").Where("name = ?", name).Find(&shares)
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sharesStruct) UpdateConfigFile() {
|
||||||
|
shares := []model2.SharesDBModel{}
|
||||||
|
s.db.Select("anonymous,path").Find(&shares)
|
||||||
|
//generated config file
|
||||||
|
var configStr = ""
|
||||||
|
for _, share := range shares {
|
||||||
|
dirName := filepath.Base(share.Path)
|
||||||
|
configStr += `
|
||||||
|
[` + dirName + `]
|
||||||
|
comment = CasaOS share ` + dirName + `
|
||||||
|
public = Yes
|
||||||
|
path = ` + share.Path + `
|
||||||
|
browseable = Yes
|
||||||
|
read only = No
|
||||||
|
guest ok = Yes
|
||||||
|
create mask = 0777
|
||||||
|
directory mask = 0777
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
|
//write config file
|
||||||
|
file.WriteToPath([]byte(configStr), "/etc/samba", "smb.casa.conf")
|
||||||
|
//restart samba
|
||||||
|
command2.ExecResultStrArray("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")
|
||||||
|
if strings.Contains(str, "# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file.MoveFile("/etc/samba/smb.conf", "/etc/samba/smb.conf.bak")
|
||||||
|
var smbConf = ""
|
||||||
|
smbConf += `# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# ______ _______
|
||||||
|
# ( __ \ ( ___ )
|
||||||
|
# | ( \ ) | ( ) |
|
||||||
|
# | | ) | | | | |
|
||||||
|
# | | | | | | | |
|
||||||
|
# | | ) | | | | |
|
||||||
|
# | (__/ ) | (___) |
|
||||||
|
# (______/ (_______)
|
||||||
|
#
|
||||||
|
# _ _______ _________
|
||||||
|
# ( ( /| ( ___ ) \__ __/
|
||||||
|
# | \ ( | | ( ) | ) (
|
||||||
|
# | \ | | | | | | | |
|
||||||
|
# | (\ \) | | | | | | |
|
||||||
|
# | | \ | | | | | | |
|
||||||
|
# | ) \ | | (___) | | |
|
||||||
|
# |/ )_) (_______) )_(
|
||||||
|
#
|
||||||
|
# _______ _______ ______ _________ _______
|
||||||
|
# ( ) ( ___ ) ( __ \ \__ __/ ( ____ \ |\ /|
|
||||||
|
# | () () | | ( ) | | ( \ ) ) ( | ( \/ ( \ / )
|
||||||
|
# | || || | | | | | | | ) | | | | (__ \ (_) /
|
||||||
|
# | |(_)| | | | | | | | | | | | | __) \ /
|
||||||
|
# | | | | | | | | | | ) | | | | ( ) (
|
||||||
|
# | ) ( | | (___) | | (__/ ) ___) (___ | ) | |
|
||||||
|
# |/ \| (_______) (______/ \_______/ |/ \_/
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# IMPORTANT: CasaOS will not provide technical support for any issues
|
||||||
|
# caused by unauthorized modification to the configuration.
|
||||||
|
|
||||||
|
[global]
|
||||||
|
## fruit settings
|
||||||
|
min protocol = SMB2
|
||||||
|
ea support = yes
|
||||||
|
## vfs objects = fruit streams_xattr
|
||||||
|
fruit:metadata = stream
|
||||||
|
fruit:model = Macmini
|
||||||
|
fruit:veto_appledouble = no
|
||||||
|
fruit:posix_rename = yes
|
||||||
|
fruit:zero_file_id = yes
|
||||||
|
fruit:wipe_intentionally_left_blank_rfork = yes
|
||||||
|
fruit:delete_empty_adfiles = yes
|
||||||
|
map to guest = bad user
|
||||||
|
include=/etc/samba/smb.casa.conf`
|
||||||
|
file.WriteToPath([]byte(smbConf), "/etc/samba", "smb.conf")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSharesService(db *gorm.DB) SharesService {
|
||||||
|
return &sharesStruct{db: db}
|
||||||
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ShortcutsService interface {
|
|
||||||
DeleteData(id string)
|
|
||||||
AddData(m model2.ShortcutsDBModel)
|
|
||||||
EditData(m model2.ShortcutsDBModel)
|
|
||||||
GetList() (list []model2.ShortcutsDBModel)
|
|
||||||
}
|
|
||||||
type shortcutsService struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *shortcutsService) AddData(m model2.ShortcutsDBModel) {
|
|
||||||
s.db.Create(&m)
|
|
||||||
}
|
|
||||||
func (s *shortcutsService) EditData(m model2.ShortcutsDBModel) {
|
|
||||||
s.db.Save(&m)
|
|
||||||
}
|
|
||||||
func (s *shortcutsService) DeleteData(id string) {
|
|
||||||
var m model2.ShortcutsDBModel
|
|
||||||
s.db.Where("id=?", id).Delete(&m)
|
|
||||||
}
|
|
||||||
func (s *shortcutsService) GetList() (list []model2.ShortcutsDBModel) {
|
|
||||||
s.db.Order("sort desc,id").Find(&list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func NewShortcutsService(db *gorm.DB) ShortcutsService {
|
|
||||||
return &shortcutsService{db: db}
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SystemService interface {
|
type SystemService interface {
|
||||||
UpSystemConfig(str string, widget string)
|
|
||||||
UpdateSystemVersion(version string)
|
UpdateSystemVersion(version string)
|
||||||
GetSystemConfigDebug() []string
|
GetSystemConfigDebug() []string
|
||||||
GetCasaOSLogs(lineNumber int) string
|
GetCasaOSLogs(lineNumber int) string
|
||||||
@@ -50,10 +49,17 @@ type SystemService interface {
|
|||||||
CreateFile(path string) (int, error)
|
CreateFile(path string) (int, error)
|
||||||
RenameFile(oldF, newF string) (int, error)
|
RenameFile(oldF, newF string) (int, error)
|
||||||
MkdirAll(path string) (int, error)
|
MkdirAll(path string) (int, error)
|
||||||
|
IsServiceRunning(name string) bool
|
||||||
}
|
}
|
||||||
type systemService struct {
|
type systemService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *systemService) UpdateUSBAutoMount(state string) {
|
||||||
|
config.ServerInfo.USBAutoMount = state
|
||||||
|
config.Cfg.Section("server").Key("USBAutoMount").SetValue(state)
|
||||||
|
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *systemService) MkdirAll(path string) (int, error) {
|
func (c *systemService) MkdirAll(path string) (int, error) {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -66,7 +72,7 @@ func (c *systemService) MkdirAll(path string) (int, error) {
|
|||||||
return common_err.FILE_OR_DIR_EXISTS, err
|
return common_err.FILE_OR_DIR_EXISTS, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return common_err.ERROR, err
|
return common_err.SERVICE_ERROR, err
|
||||||
}
|
}
|
||||||
func (c *systemService) RenameFile(oldF, newF string) (int, error) {
|
func (c *systemService) RenameFile(oldF, newF string) (int, error) {
|
||||||
|
|
||||||
@@ -77,12 +83,12 @@ func (c *systemService) RenameFile(oldF, newF string) (int, error) {
|
|||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err := os.Rename(oldF, newF)
|
err := os.Rename(oldF, newF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common_err.ERROR, err
|
return common_err.SERVICE_ERROR, err
|
||||||
}
|
}
|
||||||
return common_err.SUCCESS, nil
|
return common_err.SUCCESS, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return common_err.ERROR, err
|
return common_err.SERVICE_ERROR, err
|
||||||
}
|
}
|
||||||
func (c *systemService) CreateFile(path string) (int, error) {
|
func (c *systemService) CreateFile(path string) (int, error) {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
@@ -94,7 +100,7 @@ func (c *systemService) CreateFile(path string) (int, error) {
|
|||||||
return common_err.SUCCESS, nil
|
return common_err.SUCCESS, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return common_err.ERROR, err
|
return common_err.SERVICE_ERROR, err
|
||||||
}
|
}
|
||||||
func (c *systemService) GetDeviceTree() string {
|
func (c *systemService) GetDeviceTree() string {
|
||||||
return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree")
|
return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree")
|
||||||
@@ -208,7 +214,12 @@ func (c *systemService) GetNet(physics bool) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *systemService) UpdateSystemVersion(version string) {
|
func (s *systemService) UpdateSystemVersion(version string) {
|
||||||
command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash")
|
if file.Exists(config.AppInfo.LogPath + "/upgrade.log") {
|
||||||
|
os.Remove(config.AppInfo.LogPath + "/upgrade.log")
|
||||||
|
}
|
||||||
|
file.CreateFile(config.AppInfo.LogPath + "/upgrade.log")
|
||||||
|
//go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/update.sh | bash")
|
||||||
|
go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash")
|
||||||
//s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
|
//s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
|
||||||
//s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version))
|
//s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version))
|
||||||
}
|
}
|
||||||
@@ -222,38 +233,22 @@ func (s *systemService) GetTimeZone() string {
|
|||||||
|
|
||||||
func (s *systemService) ExecUSBAutoMountShell(state string) {
|
func (s *systemService) ExecUSBAutoMountShell(state string) {
|
||||||
if state == "False" {
|
if state == "False" {
|
||||||
command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;USB_Remove_File")
|
command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;USB_Stop_Auto")
|
||||||
} else {
|
} else {
|
||||||
command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;USB_Move_File")
|
command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;USB_Start_Auto")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *systemService) GetSystemConfigDebug() []string {
|
func (s *systemService) GetSystemConfigDebug() []string {
|
||||||
return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetSysInfo")
|
return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetSysInfo")
|
||||||
}
|
}
|
||||||
func (s *systemService) UpSystemConfig(str string, widget string) {
|
|
||||||
if len(str) > 0 && str != config.SystemConfigInfo.ConfigStr {
|
|
||||||
config.Cfg.Section("system").Key("ConfigStr").SetValue(str)
|
|
||||||
config.SystemConfigInfo.ConfigStr = str
|
|
||||||
}
|
|
||||||
if len(widget) > 0 && widget != config.SystemConfigInfo.WidgetList {
|
|
||||||
config.Cfg.Section("system").Key("WidgetList").SetValue(widget)
|
|
||||||
config.SystemConfigInfo.WidgetList = widget
|
|
||||||
}
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
func (s *systemService) UpAppOrderFile(str, id string) {
|
func (s *systemService) UpAppOrderFile(str, id string) {
|
||||||
file.WriteToPath([]byte(str), config.AppInfo.DBPath+"/"+id, "app_order.json")
|
file.WriteToPath([]byte(str), config.AppInfo.DBPath+"/"+id, "app_order.json")
|
||||||
}
|
}
|
||||||
func (s *systemService) GetAppOrderFile(id string) []byte {
|
func (s *systemService) GetAppOrderFile(id string) []byte {
|
||||||
return file.ReadFullFile(config.AppInfo.UserDataPath + "/" + id + "/app_order.json")
|
return file.ReadFullFile(config.AppInfo.UserDataPath + "/" + id + "/app_order.json")
|
||||||
}
|
}
|
||||||
func (s *systemService) UpdateUSBAutoMount(state string) {
|
|
||||||
config.ServerInfo.USBAutoMount = state
|
|
||||||
config.Cfg.Section("server").Key("USBAutoMount").SetValue(state)
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
func (s *systemService) UpSystemPort(port string) {
|
func (s *systemService) UpSystemPort(port string) {
|
||||||
if len(port) > 0 && port != config.ServerInfo.HttpPort {
|
if len(port) > 0 && port != config.ServerInfo.HttpPort {
|
||||||
config.Cfg.Section("server").Key("HttpPort").SetValue(port)
|
config.Cfg.Section("server").Key("HttpPort").SetValue(port)
|
||||||
@@ -293,6 +288,12 @@ func GetDeviceAllIP() []string {
|
|||||||
}
|
}
|
||||||
return address
|
return address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *systemService) IsServiceRunning(name string) bool {
|
||||||
|
status := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;CheckServiceStatus smbd")
|
||||||
|
return strings.TrimSpace(status) == "running"
|
||||||
|
|
||||||
|
}
|
||||||
func NewSystemService() SystemService {
|
func NewSystemService() SystemService {
|
||||||
return &systemService{}
|
return &systemService{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,503 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
path2 "path"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/model/notify"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
|
|
||||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/types"
|
|
||||||
"github.com/lucas-clemente/quic-go"
|
|
||||||
uuid "github.com/satori/go.uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
var UDPConn *net.UDPConn
|
|
||||||
var PeopleMap map[string]quic.Stream
|
|
||||||
var Message chan model.MessageModel
|
|
||||||
var UDPAddressMap map[string]string
|
|
||||||
|
|
||||||
func UDPSendData(msg model.MessageModel, localFilePath string) error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
Message = make(chan model.MessageModel)
|
|
||||||
_, port, err := net.SplitHostPort(UDPConn.LocalAddr().String())
|
|
||||||
if config.ServerInfo.UDPPort != port {
|
|
||||||
config.ServerInfo.UDPPort = port
|
|
||||||
config.Cfg.Section("server").Key("UDPPort").SetValue(port)
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
p, err := strconv.Atoi(port)
|
|
||||||
srcAddr := &net.UDPAddr{
|
|
||||||
IP: net.IPv4zero, Port: p} //注意端口必须固定
|
|
||||||
addr := UDPAddressMap[msg.To]
|
|
||||||
ticket := msg.To
|
|
||||||
dstAddr, err := net.ResolveUDPAddr("udp", addr)
|
|
||||||
|
|
||||||
session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig())
|
|
||||||
if err != nil {
|
|
||||||
if msg.Type == types.PERSONDOWNLOAD {
|
|
||||||
task := MyService.Download().GetDownloadById(msg.UUId)
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err := session.OpenStreamSync(ctx)
|
|
||||||
if err != nil {
|
|
||||||
if msg.Type == types.PERSONDOWNLOAD {
|
|
||||||
task := MyService.Download().GetDownloadById(msg.UUId)
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
session.CloseWithError(1, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
SayHello(stream, msg.To)
|
|
||||||
//TODO:发送
|
|
||||||
SendData(stream, msg)
|
|
||||||
SendFileData(stream, localFilePath, msg.To, msg.UUId, types.PERSONUPLOADDATA)
|
|
||||||
|
|
||||||
stream.Close()
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
Message = make(chan model.MessageModel)
|
|
||||||
_, port, err := net.SplitHostPort(UDPConn.LocalAddr().String())
|
|
||||||
if config.ServerInfo.UDPPort != port {
|
|
||||||
config.ServerInfo.UDPPort = port
|
|
||||||
config.Cfg.Section("server").Key("UDPPort").SetValue(port)
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
}
|
|
||||||
p, err := strconv.Atoi(port)
|
|
||||||
srcAddr := &net.UDPAddr{
|
|
||||||
IP: net.IPv4zero, Port: p} //注意端口必须固定
|
|
||||||
addr := UDPAddressMap[msg.To]
|
|
||||||
ticket := msg.To
|
|
||||||
if server {
|
|
||||||
addr = config.ServerInfo.Handshake + ":9527"
|
|
||||||
ticket = "bench"
|
|
||||||
}
|
|
||||||
dstAddr, err := net.ResolveUDPAddr("udp", addr)
|
|
||||||
|
|
||||||
//DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6";如果laddr不是nil,将使用它作为本地地址,否则自动选择一个本地地址。
|
|
||||||
//(conn)UDPConn代表一个UDP网络连接,实现了Conn和PacketConn接口
|
|
||||||
|
|
||||||
session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig())
|
|
||||||
if err != nil {
|
|
||||||
if msg.Type == types.PERSONDOWNLOAD {
|
|
||||||
task := MyService.Download().GetDownloadById(msg.UUId)
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return m, err
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err := session.OpenStreamSync(ctx)
|
|
||||||
if err != nil {
|
|
||||||
if msg.Type == types.PERSONDOWNLOAD {
|
|
||||||
task := MyService.Download().GetDownloadById(msg.UUId)
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
session.CloseWithError(1, err.Error())
|
|
||||||
return m, err
|
|
||||||
}
|
|
||||||
|
|
||||||
SayHello(stream, msg.To)
|
|
||||||
|
|
||||||
SendData(stream, msg)
|
|
||||||
|
|
||||||
go ReadContent(stream)
|
|
||||||
result := <-Message
|
|
||||||
stream.Close()
|
|
||||||
if config.SystemConfigInfo.Analyse != "False" {
|
|
||||||
go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SayHello(stream quic.Stream, to string) {
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONHELLO
|
|
||||||
msg.Data = "hello"
|
|
||||||
msg.To = to
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
SendData(stream, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送数据
|
|
||||||
func SendData(stream quic.Stream, m model.MessageModel) {
|
|
||||||
b, _ := json.Marshal(m)
|
|
||||||
prefixLength := file.PrefixLength(len(b))
|
|
||||||
data := append(prefixLength, b...)
|
|
||||||
stream.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
//读取数据
|
|
||||||
func ReadContent(stream quic.Stream) {
|
|
||||||
for {
|
|
||||||
prefixByte := make([]byte, 6)
|
|
||||||
_, err := io.ReadFull(stream, prefixByte)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
time.Sleep(time.Second * 1)
|
|
||||||
for k, v := range CancelList {
|
|
||||||
tempPath := config.AppInfo.TempPath + "/" + v
|
|
||||||
fmt.Println(file.RMDir(tempPath))
|
|
||||||
delete(CancelList, k)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
prefixLength, err := strconv.Atoi(string(prefixByte))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
messageByte := make([]byte, prefixLength)
|
|
||||||
_, err = io.ReadFull(stream, messageByte)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
m := model.MessageModel{}
|
|
||||||
err = json.Unmarshal(messageByte, &m)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if m.Type == types.PERSONDOWNLOAD {
|
|
||||||
r := SaveFile(m, stream)
|
|
||||||
if r {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if m.Type == types.PERSONSUMMARY {
|
|
||||||
Summary(m, "download")
|
|
||||||
} else if m.Type == types.PERSONCONNECTION {
|
|
||||||
if len(m.Data.(string)) > 0 {
|
|
||||||
UDPAddressMap[m.From] = m.Data.(string)
|
|
||||||
} else {
|
|
||||||
delete(UDPAddressMap, m.From)
|
|
||||||
}
|
|
||||||
// mi := model2.FriendModel{}
|
|
||||||
// mi.Avatar = config.UserInfo.Avatar
|
|
||||||
// mi.Profile = config.UserInfo.Description
|
|
||||||
// mi.NickName = config.UserInfo.NickName
|
|
||||||
// mi.Token = config.ServerInfo.Token
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONHELLO
|
|
||||||
msg.Data = ""
|
|
||||||
msg.To = m.From
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.UUId = m.UUId
|
|
||||||
go Dial(msg, false)
|
|
||||||
Message <- m
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONGETIP {
|
|
||||||
notify := notify.Person{}
|
|
||||||
notify.ShareId = m.From
|
|
||||||
if len(m.Data.(string)) == 0 {
|
|
||||||
if _, ok := UDPAddressMap[m.From]; ok {
|
|
||||||
notify.Type = "OFFLINE"
|
|
||||||
go MyService.Notify().SendPersonStatusBySocket(notify)
|
|
||||||
}
|
|
||||||
delete(UDPAddressMap, m.From)
|
|
||||||
Message <- m
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if _, ok := UDPAddressMap[m.From]; !ok {
|
|
||||||
notify.Type = "ONLINE"
|
|
||||||
go MyService.Notify().SendPersonStatusBySocket(notify)
|
|
||||||
}
|
|
||||||
UDPAddressMap[m.From] = m.Data.(string)
|
|
||||||
if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] {
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONINTERNALINSPECTION
|
|
||||||
msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort)
|
|
||||||
msg.To = m.From
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.UUId = m.UUId
|
|
||||||
go Dial(msg, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Message <- m
|
|
||||||
break
|
|
||||||
} else if m.Type == types.PERSONINTERNALINSPECTION {
|
|
||||||
fmt.Println("接收到反验证")
|
|
||||||
var ips []string
|
|
||||||
dataModelByte, _ := json.Marshal(m.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &ips)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
go MyService.Friend().InternalInspection(ips, m.From)
|
|
||||||
Message <- m
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Message <- m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message <- model.MessageModel{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SendIPToServer() {
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONHELLO
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = config.ServerInfo.Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
|
|
||||||
Dial(msg, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoopFriend() {
|
|
||||||
list := MyService.Friend().GetFriendList()
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONGETIP
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = config.ServerInfo.Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
Dial(msg, true)
|
|
||||||
|
|
||||||
for i := 0; i < len(list); i++ {
|
|
||||||
if _, ok := UDPAddressMap[list[i].Token]; !ok {
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONGETIP
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = list[i].Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
Dial(msg, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Type = types.PERSONPING
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = list[i].Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
|
|
||||||
if v, ok := UDPAddressMap[list[i].Token]; ok {
|
|
||||||
if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
|
|
||||||
msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort)
|
|
||||||
}
|
|
||||||
oldIP := UDPAddressMap[list[i].Token]
|
|
||||||
data, err := Dial(msg, false)
|
|
||||||
if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 {
|
|
||||||
if oldIP == UDPAddressMap[list[i].Token] {
|
|
||||||
notify := notify.Person{}
|
|
||||||
notify.ShareId = data.From
|
|
||||||
notify.Type = "LEAVE"
|
|
||||||
go MyService.Notify().SendPersonStatusBySocket(notify)
|
|
||||||
|
|
||||||
delete(UDPAddressMap, list[i].Token)
|
|
||||||
|
|
||||||
msg := model.MessageModel{}
|
|
||||||
msg.Type = types.PERSONGETIP
|
|
||||||
msg.Data = ""
|
|
||||||
msg.From = config.ServerInfo.Token
|
|
||||||
msg.To = list[i].Token
|
|
||||||
msg.UUId = uuid.NewV4().String()
|
|
||||||
Dial(msg, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
go func(shareId string) {
|
|
||||||
user := MyService.Casa().GetUserInfoByShareId(shareId)
|
|
||||||
m := model2.FriendModel{}
|
|
||||||
m.Token = shareId
|
|
||||||
friend := MyService.Friend().GetFriendById(m)
|
|
||||||
if friend.Version != user.Version {
|
|
||||||
friend.Avatar = user.Avatar
|
|
||||||
friend.NickName = user.NickName
|
|
||||||
friend.Profile = user.Desc
|
|
||||||
friend.Version = user.Version
|
|
||||||
MyService.Friend().UpdateOrCreate(friend)
|
|
||||||
}
|
|
||||||
}(list[i].Token)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//file summary
|
|
||||||
func Summary(m model.MessageModel, t string) {
|
|
||||||
dataModel := model.FileSummaryModel{}
|
|
||||||
dataModelByte, _ := json.Marshal(m.Data)
|
|
||||||
err := json.Unmarshal(dataModelByte, &dataModel)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
task := MyService.Download().GetDownloadById(m.UUId)
|
|
||||||
|
|
||||||
task.State = types.DOWNLOADING
|
|
||||||
fullPath := path2.Join(task.LocalPath, task.Name)
|
|
||||||
|
|
||||||
if len(dataModel.Message) > 0 {
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
task.Error = dataModel.Message
|
|
||||||
}
|
|
||||||
//The file already exists and the file is the same, no need to download
|
|
||||||
if t != "upload" && file.Exists(fullPath) && file.GetHashByPath(fullPath) == dataModel.Hash {
|
|
||||||
task.State = types.DOWNLOADFINISHED
|
|
||||||
go func(from, uuid string) {
|
|
||||||
m := model.MessageModel{}
|
|
||||||
m.Data = ""
|
|
||||||
m.From = config.ServerInfo.Token
|
|
||||||
m.To = from
|
|
||||||
m.Type = types.PERSONCANCEL
|
|
||||||
m.UUId = uuid
|
|
||||||
CancelList[uuid] = uuid
|
|
||||||
Dial(m, false)
|
|
||||||
}(task.From, task.UUID)
|
|
||||||
|
|
||||||
}
|
|
||||||
task.UUID = m.UUId
|
|
||||||
task.Name = dataModel.Name
|
|
||||||
task.Length = dataModel.Length
|
|
||||||
task.Size = dataModel.Size
|
|
||||||
task.BlockSize = dataModel.BlockSize
|
|
||||||
task.Hash = dataModel.Hash
|
|
||||||
task.Type = types.PERSONFILEDOWNLOAD
|
|
||||||
task.From = m.From
|
|
||||||
if t == "upload" {
|
|
||||||
task.Type = types.PERSONFILERECEIVEUPLOAD
|
|
||||||
}
|
|
||||||
MyService.Download().SaveDownload(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Save file fragment
|
|
||||||
func SaveFile(m model.MessageModel, stream quic.Stream) bool {
|
|
||||||
dataModelByte, _ := json.Marshal(m.Data)
|
|
||||||
dataModel := model.TranFileModel{}
|
|
||||||
err := json.Unmarshal(dataModelByte, &dataModel)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
dataLengthByte := make([]byte, 8)
|
|
||||||
_, err = io.ReadFull(stream, dataLengthByte)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
dataLength, err := strconv.Atoi(string(dataLengthByte))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
dataByte := make([]byte, dataLength)
|
|
||||||
_, err = io.ReadFull(stream, dataByte)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
sum := md5.Sum(dataByte)
|
|
||||||
hash := hex.EncodeToString(sum[:])
|
|
||||||
if dataModel.Hash != hash {
|
|
||||||
fmt.Println("hash不匹配", hash, dataModel.Hash)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
tempPath := config.AppInfo.TempPath + "/" + m.UUId
|
|
||||||
file.IsNotExistMkDir(tempPath)
|
|
||||||
filepath := tempPath + "/" + strconv.Itoa(dataModel.Index)
|
|
||||||
_, err = os.Stat(filepath)
|
|
||||||
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
err = ioutil.WriteFile(filepath, dataByte, 0644)
|
|
||||||
task := model2.PersonDownloadDBModel{}
|
|
||||||
task.UUID = m.UUId
|
|
||||||
if err != nil {
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if file.GetHashByPath(filepath) != dataModel.Hash {
|
|
||||||
os.Remove(filepath)
|
|
||||||
err = ioutil.WriteFile(filepath, dataByte, 0644)
|
|
||||||
task := model2.PersonDownloadDBModel{}
|
|
||||||
task.UUID = m.UUId
|
|
||||||
if err != nil {
|
|
||||||
task.Error = err.Error()
|
|
||||||
task.State = types.DOWNLOADERROR
|
|
||||||
MyService.Download().SetDownloadError(task)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(tempPath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(files) >= dataModel.Length {
|
|
||||||
summary := MyService.Download().GetDownloadById(m.UUId)
|
|
||||||
summary.State = types.DOWNLOADFINISH
|
|
||||||
MyService.Download().EditDownloadState(summary)
|
|
||||||
fullPath := file.GetNoDuplicateFileName(path2.Join(summary.LocalPath, summary.Name))
|
|
||||||
file.SpliceFiles(tempPath, fullPath, dataModel.Length, 0)
|
|
||||||
if file.GetHashByPath(fullPath) == summary.Hash {
|
|
||||||
file.RMDir(tempPath)
|
|
||||||
summary.State = types.DOWNLOADFINISHED
|
|
||||||
MyService.Download().EditDownloadState(summary)
|
|
||||||
} else {
|
|
||||||
os.Remove(config.FileSettingInfo.DownloadDir + "/" + summary.Name)
|
|
||||||
|
|
||||||
summary.State = types.DOWNLOADERROR
|
|
||||||
summary.Error = "hash mismatch"
|
|
||||||
MyService.Download().SetDownloadError(summary)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-03-18 11:40:55
|
* @Date: 2022-03-18 11:40:55
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-06-23 19:45:49
|
* @LastEditTime: 2022-07-12 10:05:37
|
||||||
* @FilePath: /CasaOS/service/user.go
|
* @FilePath: /CasaOS/service/user.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -15,13 +15,11 @@ import (
|
|||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/service/model"
|
"github.com/IceWhaleTech/CasaOS/service/model"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserService interface {
|
type UserService interface {
|
||||||
SetUser(username, pwd, token, email, desc, nickName string) error
|
|
||||||
UpLoadFile(file multipart.File, name string) error
|
UpLoadFile(file multipart.File, name string) error
|
||||||
CreateUser(m model.UserDBModel) model.UserDBModel
|
CreateUser(m model.UserDBModel) model.UserDBModel
|
||||||
GetUserCount() (userCount int64)
|
GetUserCount() (userCount int64)
|
||||||
@@ -31,6 +29,7 @@ type UserService interface {
|
|||||||
GetUserAllInfoById(id string) (m model.UserDBModel)
|
GetUserAllInfoById(id string) (m model.UserDBModel)
|
||||||
GetUserAllInfoByName(userName string) (m model.UserDBModel)
|
GetUserAllInfoByName(userName string) (m model.UserDBModel)
|
||||||
DeleteUserById(id string)
|
DeleteUserById(id string)
|
||||||
|
DeleteAllUser()
|
||||||
GetUserInfoByUserName(userName string) (m model.UserDBModel)
|
GetUserInfoByUserName(userName string) (m model.UserDBModel)
|
||||||
GetAllUserName() (list []model.UserDBModel)
|
GetAllUserName() (list []model.UserDBModel)
|
||||||
}
|
}
|
||||||
@@ -41,12 +40,15 @@ type userService struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userService) DeleteAllUser() {
|
||||||
|
u.db.Where("1=1").Delete(&model.UserDBModel{})
|
||||||
|
}
|
||||||
func (u *userService) DeleteUserById(id string) {
|
func (u *userService) DeleteUserById(id string) {
|
||||||
u.db.Where("id= ?", id).Delete(&model.UserDBModel{})
|
u.db.Where("id= ?", id).Delete(&model.UserDBModel{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userService) GetAllUserName() (list []model.UserDBModel) {
|
func (u *userService) GetAllUserName() (list []model.UserDBModel) {
|
||||||
u.db.Select("user_name").Find(&list)
|
u.db.Select("username").Find(&list)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (u *userService) CreateUser(m model.UserDBModel) model.UserDBModel {
|
func (u *userService) CreateUser(m model.UserDBModel) model.UserDBModel {
|
||||||
@@ -70,47 +72,19 @@ func (u *userService) GetUserAllInfoById(id string) (m model.UserDBModel) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (u *userService) GetUserAllInfoByName(userName string) (m model.UserDBModel) {
|
func (u *userService) GetUserAllInfoByName(userName string) (m model.UserDBModel) {
|
||||||
u.db.Where("user_name= ?", userName).First(&m)
|
u.db.Where("username= ?", userName).First(&m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) {
|
func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) {
|
||||||
u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("id= ?", id).First(&m)
|
u.db.Select("username", "id", "role", "nickname", "description", "avatar", "email").Where("id= ?", id).First(&m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userService) GetUserInfoByUserName(userName string) (m model.UserDBModel) {
|
func (u *userService) GetUserInfoByUserName(userName string) (m model.UserDBModel) {
|
||||||
u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("user_name= ?", userName).First(&m)
|
u.db.Select("username", "id", "role", "nickname", "description", "avatar", "email").Where("username= ?", userName).First(&m)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置用户名密码
|
|
||||||
func (u *userService) SetUser(username, pwd, token, email, desc, nickName string) error {
|
|
||||||
if len(username) > 0 {
|
|
||||||
config.Cfg.Section("user").Key("UserName").SetValue(username)
|
|
||||||
config.UserInfo.UserName = username
|
|
||||||
config.Cfg.Section("user").Key("Initialized").SetValue("true")
|
|
||||||
config.UserInfo.Initialized = true
|
|
||||||
}
|
|
||||||
if len(pwd) > 0 {
|
|
||||||
config.Cfg.Section("user").Key("PWD").SetValue(pwd)
|
|
||||||
config.UserInfo.PWD = pwd
|
|
||||||
}
|
|
||||||
if len(email) > 0 {
|
|
||||||
config.Cfg.Section("user").Key("Email").SetValue(email)
|
|
||||||
config.UserInfo.Email = email
|
|
||||||
}
|
|
||||||
if len(desc) > 0 {
|
|
||||||
config.Cfg.Section("user").Key("Description").SetValue(desc)
|
|
||||||
config.UserInfo.Description = desc
|
|
||||||
}
|
|
||||||
if len(nickName) > 0 {
|
|
||||||
config.Cfg.Section("user").Key("NickName").SetValue(nickName)
|
|
||||||
config.UserInfo.NickName = nickName
|
|
||||||
}
|
|
||||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//上传文件
|
//上传文件
|
||||||
func (c *userService) UpLoadFile(file multipart.File, url string) error {
|
func (c *userService) UpLoadFile(file multipart.File, url string) error {
|
||||||
out, _ := os.OpenFile(url, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
|
out, _ := os.OpenFile(url, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
|
||||||
|
|||||||
@@ -330,19 +330,60 @@ TarFolder() {
|
|||||||
du -sh /DATA
|
du -sh /DATA
|
||||||
}
|
}
|
||||||
|
|
||||||
USB_Move_File() {
|
USB_Start_Auto() {
|
||||||
((EUID)) && sudo_cmd="sudo"
|
((EUID)) && sudo_cmd="sudo"
|
||||||
$sudo_cmd cp -rf /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
|
$sudo_cmd systemctl enable devmon@devmon
|
||||||
$sudo_cmd chmod +x /casaOS/server/shell/usb-mount.sh
|
$sudo_cmd systemctl start devmon@devmon
|
||||||
$sudo_cmd cp -rf /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USB_Remove_File() {
|
USB_Stop_Auto() {
|
||||||
((EUID)) && sudo_cmd="sudo"
|
((EUID)) && sudo_cmd="sudo"
|
||||||
$sudo_cmd rm -fr /etc/udev/rules.d/11-usb-mount.rules
|
$sudo_cmd systemctl stop devmon@devmon
|
||||||
$sudo_cmd rm -fr /etc/systemd/system/usb-mount@.service
|
$sudo_cmd systemctl disable devmon@devmon
|
||||||
|
$sudo_cmd udevil clean
|
||||||
}
|
}
|
||||||
|
|
||||||
GetDeviceTree(){
|
GetDeviceTree(){
|
||||||
cat /proc/device-tree/model
|
cat /proc/device-tree/model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# restart samba service
|
||||||
|
RestartSMBD(){
|
||||||
|
$sudo_cmd systemctl restart smbd
|
||||||
|
}
|
||||||
|
|
||||||
|
# edit user password $1:username
|
||||||
|
EditSmabaUserPassword(){
|
||||||
|
$sudo_cmd smbpasswd $1
|
||||||
|
}
|
||||||
|
|
||||||
|
AddSmabaUser(){
|
||||||
|
$sudo_cmd useradd $1
|
||||||
|
$sudo_cmd smbpasswd -a $1 <<EOF
|
||||||
|
$2
|
||||||
|
$2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1:username $2:host $3:share $4:port $5:mountpoint $6:password
|
||||||
|
MountCIFS(){
|
||||||
|
$sudo_cmd mount -t cifs -o username=$1,password=$6,port=$4 //$2/$3 $5
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1:service name
|
||||||
|
CheckServiceStatus(){
|
||||||
|
rs="`systemctl status $1 |grep -E 'Active|PID'`"
|
||||||
|
#echo "$rs"
|
||||||
|
run="`echo "$rs" |grep -B 2 'running'`"
|
||||||
|
fai="`echo "$rs" |grep -E -B 2 'failed|inactive|dead'`"
|
||||||
|
if [ "$run" == "" ]
|
||||||
|
then
|
||||||
|
echo "failed"
|
||||||
|
else
|
||||||
|
echo "running"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
UDEVILUmount(){
|
||||||
|
$sudo_cmd udevil umount -f $1
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
snapshot-dark.jpg
Normal file
|
After Width: | Height: | Size: 1004 KiB |
BIN
snapshot-light.jpg
Normal file
|
After Width: | Height: | Size: 1004 KiB |
@@ -2,7 +2,7 @@
|
|||||||
* @Author: LinkLeong link@icewhale.com
|
* @Author: LinkLeong link@icewhale.com
|
||||||
* @Date: 2022-02-17 18:53:22
|
* @Date: 2022-02-17 18:53:22
|
||||||
* @LastEditors: LinkLeong
|
* @LastEditors: LinkLeong
|
||||||
* @LastEditTime: 2022-07-01 15:15:09
|
* @LastEditTime: 2022-08-10 13:50:57
|
||||||
* @FilePath: /CasaOS/types/system.go
|
* @FilePath: /CasaOS/types/system.go
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Website: https://www.casaos.io
|
* @Website: https://www.casaos.io
|
||||||
@@ -10,6 +10,6 @@
|
|||||||
*/
|
*/
|
||||||
package types
|
package types
|
||||||
|
|
||||||
const CURRENTVERSION = "0.3.3"
|
const CURRENTVERSION = "0.3.5"
|
||||||
|
|
||||||
const BODY = ""
|
const BODY = " "
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 394 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 468 KiB |