mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-11-07 07:09:46 +00:00
wip
This commit is contained in:
parent
26d4f69652
commit
a6df45dd79
2
go.mod
2
go.mod
@ -3,6 +3,7 @@ module github.com/IceWhaleTech/CasaOS
|
|||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
bazil.org/fuse v0.0.0-20200524192727-fb710f7dfd05
|
||||||
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/IceWhaleTech/CasaOS-Common v0.4.2-alpha3
|
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3
|
||||||
github.com/Xhofe/go-cache v0.0.0-20220723083548-714439c8af9a
|
github.com/Xhofe/go-cache v0.0.0-20220723083548-714439c8af9a
|
||||||
@ -49,7 +50,6 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5 // indirect
|
|
||||||
cloud.google.com/go/compute v1.12.1 // indirect
|
cloud.google.com/go/compute v1.12.1 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.1 // indirect
|
cloud.google.com/go/compute/metadata v0.2.1 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.4 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.4 // indirect
|
||||||
|
|||||||
12
go.sum
12
go.sum
@ -1,6 +1,5 @@
|
|||||||
bazil.org/fuse v0.0.0-20200524192727-fb710f7dfd05 h1:UrYe9YkT4Wpm6D+zByEyCJQzDqTPXqTDUI7bZ41i9VE=
|
bazil.org/fuse v0.0.0-20200524192727-fb710f7dfd05 h1:UrYe9YkT4Wpm6D+zByEyCJQzDqTPXqTDUI7bZ41i9VE=
|
||||||
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5 h1:A0NsYy4lDBZAC6QiYeJ4N+XuHIKBpyhAVRMHRQZKTeQ=
|
bazil.org/fuse v0.0.0-20200524192727-fb710f7dfd05/go.mod h1:h0h5FBYpXThbvSfTqthw+0I4nmHnhTHkO5BoOHsBWqg=
|
||||||
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5/go.mod h1:gG3RZAMXCa/OTes6rr9EwusmR1OH1tDDy+cg9c5YliY=
|
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
@ -59,6 +58,7 @@ 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/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/IceWhaleTech/CasaOS-Common v0.4.2-alpha3 h1:WJUYo+hJpLmza7mQngoJVeUJOfnrZevNrX5wzTuOJo0=
|
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3 h1:WJUYo+hJpLmza7mQngoJVeUJOfnrZevNrX5wzTuOJo0=
|
||||||
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3/go.mod h1:xcemiRsXcs1zrmQxYMyExDjZ7UHYwkJqYE71IDIV0xA=
|
github.com/IceWhaleTech/CasaOS-Common v0.4.2-alpha3/go.mod h1:xcemiRsXcs1zrmQxYMyExDjZ7UHYwkJqYE71IDIV0xA=
|
||||||
|
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||||
github.com/Max-Sum/base32768 v0.0.0-20191205131208-7937843c71d5 h1:w/vNc+SQRYKGWBHeDrzvvNttHwZEbSAP0kmTdORl4OI=
|
github.com/Max-Sum/base32768 v0.0.0-20191205131208-7937843c71d5 h1:w/vNc+SQRYKGWBHeDrzvvNttHwZEbSAP0kmTdORl4OI=
|
||||||
github.com/Max-Sum/base32768 v0.0.0-20191205131208-7937843c71d5/go.mod h1:C8yoIfvESpM3GD07OCHU7fqI7lhwyZ2Td1rbNbTAhnc=
|
github.com/Max-Sum/base32768 v0.0.0-20191205131208-7937843c71d5/go.mod h1:C8yoIfvESpM3GD07OCHU7fqI7lhwyZ2Td1rbNbTAhnc=
|
||||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||||
@ -150,6 +150,8 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ
|
|||||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw=
|
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw=
|
||||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||||
|
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
@ -543,6 +545,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
|
|||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/rfjakob/eme v1.1.2 h1:SxziR8msSOElPayZNFfQw4Tjx/Sbaeeh3eRvrHVMUs4=
|
github.com/rfjakob/eme v1.1.2 h1:SxziR8msSOElPayZNFfQw4Tjx/Sbaeeh3eRvrHVMUs4=
|
||||||
github.com/rfjakob/eme v1.1.2/go.mod h1:cVvpasglm/G3ngEfcfT/Wt0GwhkuO32pf/poW6Nyk1k=
|
github.com/rfjakob/eme v1.1.2/go.mod h1:cVvpasglm/G3ngEfcfT/Wt0GwhkuO32pf/poW6Nyk1k=
|
||||||
|
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
@ -575,6 +578,7 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq
|
|||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||||
|
github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
|
||||||
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
@ -603,6 +607,8 @@ github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+Kd
|
|||||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||||
|
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
|
||||||
|
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
@ -791,6 +797,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -894,6 +901,7 @@ golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapK
|
|||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||||
|
golang.org/x/tools v0.0.0-20200423201157-2723c5de0d66/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
|
|||||||
5
main.go
5
main.go
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS-Common/model"
|
"github.com/IceWhaleTech/CasaOS-Common/model"
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
"github.com/rclone/rclone/cmd/mountlib"
|
||||||
"github.com/rclone/rclone/fs/config/configfile"
|
"github.com/rclone/rclone/fs/config/configfile"
|
||||||
|
|
||||||
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
||||||
@ -83,6 +84,7 @@ func init() {
|
|||||||
service.MyService.Storages().InitStorages()
|
service.MyService.Storages().InitStorages()
|
||||||
route.InitFunction()
|
route.InitFunction()
|
||||||
configfile.Install()
|
configfile.Install()
|
||||||
|
service.MountLists = make(map[string]*mountlib.MountPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @title casaOS API
|
// @title casaOS API
|
||||||
@ -97,6 +99,7 @@ func init() {
|
|||||||
// @name Authorization
|
// @name Authorization
|
||||||
// @BasePath /v1
|
// @BasePath /v1
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
if *versionFlag {
|
if *versionFlag {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -227,7 +230,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("CasaOS main service is listening...", zap.Any("address", listener.Addr().String()))
|
logger.Info("CasaOS main service is listening...", zap.Any("address", listener.Addr().String()))
|
||||||
|
//defer service.MyService.Storage().UnmountAllStorage()
|
||||||
err = s.Serve(listener) // not using http.serve() to fix G114: Use of net/http serve function that has no support for setting timeouts (see https://github.com/securego/gosec)
|
err = s.Serve(listener) // not using http.serve() to fix G114: Use of net/http serve function that has no support for setting timeouts (see https://github.com/securego/gosec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package service
|
package mount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package service
|
package mount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package service
|
package mount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
113
pkg/mount/mount.go
Normal file
113
pkg/mount/mount.go
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package mount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"bazil.org/fuse"
|
||||||
|
fusefs "bazil.org/fuse/fs"
|
||||||
|
"github.com/rclone/rclone/cmd/mountlib"
|
||||||
|
"github.com/rclone/rclone/fs"
|
||||||
|
"github.com/rclone/rclone/fs/log"
|
||||||
|
"github.com/rclone/rclone/vfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MountFn(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error, func() error, error) {
|
||||||
|
|
||||||
|
f := VFS.Fs()
|
||||||
|
fs.Debugf(f, "Mounting on %q", mountpoint)
|
||||||
|
c, err := fuse.Mount(mountpoint, mountOptions(VFS, opt.DeviceName, opt)...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
filesys := NewFS(VFS, opt)
|
||||||
|
filesys.server = fusefs.New(c, nil)
|
||||||
|
|
||||||
|
// Serve the mount point in the background returning error to errChan
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
err := filesys.server.Serve(filesys)
|
||||||
|
closeErr := c.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
errChan <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
unmount := func() error {
|
||||||
|
// Shutdown the VFS
|
||||||
|
filesys.VFS.Shutdown()
|
||||||
|
return fuse.Unmount(mountpoint)
|
||||||
|
}
|
||||||
|
return errChan, unmount, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func NewFS(VFS *vfs.VFS, opt *mountlib.Options) *FS {
|
||||||
|
fsys := &FS{
|
||||||
|
VFS: VFS,
|
||||||
|
f: VFS.Fs(),
|
||||||
|
opt: opt,
|
||||||
|
}
|
||||||
|
return fsys
|
||||||
|
}
|
||||||
|
|
||||||
|
type FS struct {
|
||||||
|
*vfs.VFS
|
||||||
|
f fs.Fs
|
||||||
|
opt *mountlib.Options
|
||||||
|
server *fusefs.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
// mountOptions configures the options from the command line flags
|
||||||
|
func mountOptions(VFS *vfs.VFS, device string, opt *mountlib.Options) (options []fuse.MountOption) {
|
||||||
|
options = []fuse.MountOption{
|
||||||
|
fuse.MaxReadahead(uint32(opt.MaxReadAhead)),
|
||||||
|
fuse.Subtype("rclone"),
|
||||||
|
fuse.FSName(device),
|
||||||
|
|
||||||
|
// Options from benchmarking in the fuse module
|
||||||
|
//fuse.MaxReadahead(64 * 1024 * 1024),
|
||||||
|
//fuse.WritebackCache(),
|
||||||
|
}
|
||||||
|
if opt.AsyncRead {
|
||||||
|
options = append(options, fuse.AsyncRead())
|
||||||
|
}
|
||||||
|
if opt.AllowNonEmpty {
|
||||||
|
options = append(options, fuse.AllowNonEmptyMount())
|
||||||
|
}
|
||||||
|
if opt.AllowOther {
|
||||||
|
options = append(options, fuse.AllowOther())
|
||||||
|
}
|
||||||
|
if opt.AllowRoot {
|
||||||
|
// options = append(options, fuse.AllowRoot())
|
||||||
|
fs.Errorf(nil, "Ignoring --allow-root. Support has been removed upstream - see https://github.com/bazil/fuse/issues/144 for more info")
|
||||||
|
}
|
||||||
|
if opt.DefaultPermissions {
|
||||||
|
options = append(options, fuse.DefaultPermissions())
|
||||||
|
}
|
||||||
|
if VFS.Opt.ReadOnly {
|
||||||
|
options = append(options, fuse.ReadOnly())
|
||||||
|
}
|
||||||
|
if opt.WritebackCache {
|
||||||
|
options = append(options, fuse.WritebackCache())
|
||||||
|
}
|
||||||
|
if opt.DaemonTimeout != 0 {
|
||||||
|
options = append(options, fuse.DaemonTimeout(fmt.Sprint(int(opt.DaemonTimeout.Seconds()))))
|
||||||
|
}
|
||||||
|
if len(opt.ExtraOptions) > 0 {
|
||||||
|
fs.Errorf(nil, "-o/--option not supported with this FUSE backend")
|
||||||
|
}
|
||||||
|
if len(opt.ExtraFlags) > 0 {
|
||||||
|
fs.Errorf(nil, "--fuse-flag not supported with this FUSE backend")
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root returns the root node
|
||||||
|
func (f *FS) Root() (node fusefs.Node, err error) {
|
||||||
|
defer log.Trace("", "")("node=%+v, err=%v", &node, &err)
|
||||||
|
root, err := f.VFS.Root()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Dir{root, f}, nil
|
||||||
|
}
|
||||||
@ -1,24 +1,17 @@
|
|||||||
package httper
|
package httper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
|
||||||
"github.com/go-resty/resty/v2"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MountList struct {
|
type MountList struct {
|
||||||
MountPoints []struct {
|
MountPoints []MountPoints `json:"mountPoints"`
|
||||||
|
}
|
||||||
|
type MountPoints struct {
|
||||||
MountPoint string `json:"MountPoint"`
|
MountPoint string `json:"MountPoint"`
|
||||||
Fs string `json:"Fs"`
|
Fs string `json:"Fs"`
|
||||||
Icon string `json:"Icon"`
|
Icon string `json:"Icon"`
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
} `json:"mountPoints"`
|
|
||||||
}
|
}
|
||||||
type MountPoint struct {
|
type MountPoint struct {
|
||||||
MountPoint string `json:"mount_point"`
|
MountPoint string `json:"mount_point"`
|
||||||
@ -43,125 +36,126 @@ type RemotesResult struct {
|
|||||||
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
|
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
|
||||||
var DefaultTimeout = time.Second * 30
|
var DefaultTimeout = time.Second * 30
|
||||||
|
|
||||||
func NewRestyClient() *resty.Client {
|
// func NewRestyClient() *resty.Client {
|
||||||
|
|
||||||
unixSocket := "/var/run/rclone/rclone.sock"
|
// unixSocket := "/var/run/rclone/rclone.sock"
|
||||||
|
|
||||||
transport := http.Transport{
|
// transport := http.Transport{
|
||||||
Dial: func(_, _ string) (net.Conn, error) {
|
// Dial: func(_, _ string) (net.Conn, error) {
|
||||||
return net.Dial("unix", unixSocket)
|
// return net.Dial("unix", unixSocket)
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
|
||||||
client := resty.New()
|
// client := resty.New()
|
||||||
|
|
||||||
client.SetTransport(&transport).SetBaseURL("http://localhost")
|
// client.SetTransport(&transport).SetBaseURL("http://localhost")
|
||||||
client.SetRetryCount(3).SetRetryWaitTime(5*time.Second).SetTimeout(DefaultTimeout).SetHeader("User-Agent", UserAgent)
|
// client.SetRetryCount(3).SetRetryWaitTime(5*time.Second).SetTimeout(DefaultTimeout).SetHeader("User-Agent", UserAgent)
|
||||||
return client
|
// return client
|
||||||
}
|
// }
|
||||||
|
|
||||||
func GetMountList() (MountList, error) {
|
// func GetMountList() (MountList, error) {
|
||||||
var result MountList
|
// var result MountList
|
||||||
res, err := NewRestyClient().R().Post("/mount/listmounts")
|
// res, err := NewRestyClient().R().Post("/mount/listmounts")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return result, err
|
// return result, err
|
||||||
}
|
// }
|
||||||
if res.StatusCode() != 200 {
|
// if res.StatusCode() != 200 {
|
||||||
return result, fmt.Errorf("get mount list failed")
|
// return result, fmt.Errorf("get mount list failed")
|
||||||
}
|
// }
|
||||||
json.Unmarshal(res.Body(), &result)
|
// json.Unmarshal(res.Body(), &result)
|
||||||
for i := 0; i < len(result.MountPoints); i++ {
|
// for i := 0; i < len(result.MountPoints); i++ {
|
||||||
result.MountPoints[i].Fs = result.MountPoints[i].Fs[:len(result.MountPoints[i].Fs)-1]
|
// result.MountPoints[i].Fs = result.MountPoints[i].Fs[:len(result.MountPoints[i].Fs)-1]
|
||||||
}
|
// }
|
||||||
return result, err
|
// return result, err
|
||||||
}
|
// }
|
||||||
func Mount(mountPoint string, fs string) error {
|
//
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{
|
// func Mount(mountPoint string, fs string) error {
|
||||||
"mountPoint": mountPoint,
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{
|
||||||
"fs": fs,
|
// "mountPoint": mountPoint,
|
||||||
"mountOpt": `{"AllowOther": true}`,
|
// "fs": fs,
|
||||||
}).Post("/mount/mount")
|
// "mountOpt": `{"AllowOther": true}`,
|
||||||
if err != nil {
|
// }).Post("/mount/mount")
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
if res.StatusCode() != 200 {
|
// }
|
||||||
return fmt.Errorf("mount failed")
|
// if res.StatusCode() != 200 {
|
||||||
}
|
// return fmt.Errorf("mount failed")
|
||||||
logger.Info("mount then", zap.Any("res", res.Body()))
|
// }
|
||||||
return nil
|
// logger.Info("mount then", zap.Any("res", res.Body()))
|
||||||
}
|
// return nil
|
||||||
func Unmount(mountPoint string) error {
|
// }
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{
|
// func Unmount(mountPoint string) error {
|
||||||
"mountPoint": mountPoint,
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{
|
||||||
}).Post("/mount/unmount")
|
// "mountPoint": mountPoint,
|
||||||
if err != nil {
|
// }).Post("/mount/unmount")
|
||||||
logger.Error("when unmount", zap.Error(err))
|
// if err != nil {
|
||||||
return err
|
// logger.Error("when unmount", zap.Error(err))
|
||||||
}
|
// return err
|
||||||
if res.StatusCode() != 200 {
|
// }
|
||||||
logger.Error("then unmount failed", zap.Any("res", res.Body()))
|
// if res.StatusCode() != 200 {
|
||||||
return fmt.Errorf("unmount failed")
|
// logger.Error("then unmount failed", zap.Any("res", res.Body()))
|
||||||
}
|
// return fmt.Errorf("unmount failed")
|
||||||
logger.Info("unmount then", zap.Any("res", res.Body()))
|
// }
|
||||||
return nil
|
// logger.Info("unmount then", zap.Any("res", res.Body()))
|
||||||
}
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
func CreateConfig(data map[string]string, name, t string) error {
|
// func CreateConfig(data map[string]string, name, t string) error {
|
||||||
data["config_is_local"] = "false"
|
// data["config_is_local"] = "false"
|
||||||
dataStr, _ := json.Marshal(data)
|
// dataStr, _ := json.Marshal(data)
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{
|
||||||
"name": name,
|
// "name": name,
|
||||||
"parameters": string(dataStr),
|
// "parameters": string(dataStr),
|
||||||
"type": t,
|
// "type": t,
|
||||||
}).Post("/config/create")
|
// }).Post("/config/create")
|
||||||
logger.Info("when create config then", zap.Any("res", res.Body()))
|
// logger.Info("when create config then", zap.Any("res", res.Body()))
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if res.StatusCode() != 200 {
|
// if res.StatusCode() != 200 {
|
||||||
return fmt.Errorf("create config failed")
|
// return fmt.Errorf("create config failed")
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func GetConfigByName(name string) (map[string]string, error) {
|
// func GetConfigByName(name string) (map[string]string, error) {
|
||||||
|
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{
|
||||||
"name": name,
|
// "name": name,
|
||||||
}).Post("/config/get")
|
// }).Post("/config/get")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
if res.StatusCode() != 200 {
|
// if res.StatusCode() != 200 {
|
||||||
return nil, fmt.Errorf("create config failed")
|
// return nil, fmt.Errorf("create config failed")
|
||||||
}
|
// }
|
||||||
var result map[string]string
|
// var result map[string]string
|
||||||
json.Unmarshal(res.Body(), &result)
|
// json.Unmarshal(res.Body(), &result)
|
||||||
return result, nil
|
// return result, nil
|
||||||
}
|
// }
|
||||||
func GetAllConfigName() (RemotesResult, error) {
|
// func GetAllConfigName() (RemotesResult, error) {
|
||||||
var result RemotesResult
|
// var result RemotesResult
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{}).Post("/config/listremotes")
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{}).Post("/config/listremotes")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return result, err
|
// return result, err
|
||||||
}
|
// }
|
||||||
if res.StatusCode() != 200 {
|
// if res.StatusCode() != 200 {
|
||||||
return result, fmt.Errorf("get config failed")
|
// return result, fmt.Errorf("get config failed")
|
||||||
}
|
// }
|
||||||
|
|
||||||
json.Unmarshal(res.Body(), &result)
|
// json.Unmarshal(res.Body(), &result)
|
||||||
return result, nil
|
// return result, nil
|
||||||
}
|
// }
|
||||||
func DeleteConfigByName(name string) error {
|
// func DeleteConfigByName(name string) error {
|
||||||
res, err := NewRestyClient().R().SetFormData(map[string]string{
|
// res, err := NewRestyClient().R().SetFormData(map[string]string{
|
||||||
"name": name,
|
// "name": name,
|
||||||
}).Post("/config/delete")
|
// }).Post("/config/delete")
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
if res.StatusCode() != 200 {
|
// if res.StatusCode() != 200 {
|
||||||
return fmt.Errorf("delete config failed")
|
// return fmt.Errorf("delete config failed")
|
||||||
}
|
// }
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -56,7 +56,7 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dmap := make(map[string]string)
|
dmap := make(map[string]interface{})
|
||||||
dmap["username"] = username
|
dmap["username"] = username
|
||||||
configs, err := service.MyService.Storage().GetConfig()
|
configs, err := service.MyService.Storage().GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -68,16 +68,17 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, v := range configs.Remotes {
|
for _, v := range configs.Remotes {
|
||||||
cf, err := service.MyService.Storage().GetConfigByName(v)
|
t := service.MyService.Storage().GetAttributeValueByName(v, "type")
|
||||||
|
username := service.MyService.Storage().GetAttributeValueByName(v, "username")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cf["type"] == "drive" && cf["username"] == dmap["username"] {
|
if t == "drive" && username == dmap["username"] {
|
||||||
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||||
err := service.MyService.Storage().CheckAndMountByName(v)
|
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", username))
|
||||||
}
|
}
|
||||||
notify["status"] = "warn"
|
notify["status"] = "warn"
|
||||||
notify["message"] = "The same configuration has been added"
|
notify["message"] = "The same configuration has been added"
|
||||||
@ -138,7 +139,7 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dmap := make(map[string]string)
|
dmap := make(map[string]interface{})
|
||||||
dmap["username"] = username
|
dmap["username"] = username
|
||||||
|
|
||||||
configs, err := service.MyService.Storage().GetConfig()
|
configs, err := service.MyService.Storage().GetConfig()
|
||||||
@ -151,16 +152,18 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, v := range configs.Remotes {
|
for _, v := range configs.Remotes {
|
||||||
cf, err := service.MyService.Storage().GetConfigByName(v)
|
|
||||||
|
t := service.MyService.Storage().GetAttributeValueByName(v, "type")
|
||||||
|
username := service.MyService.Storage().GetAttributeValueByName(v, "username")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cf["type"] == "dropbox" && cf["username"] == dmap["username"] {
|
if t == "dropbox" && username == dmap["username"] {
|
||||||
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||||
err := service.MyService.Storage().CheckAndMountByName(v)
|
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", username))
|
||||||
}
|
}
|
||||||
|
|
||||||
notify["status"] = "warn"
|
notify["status"] = "warn"
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
"github.com/IceWhaleTech/CasaOS/model"
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
@ -12,7 +11,6 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ListStorages(c *gin.Context) {
|
func ListStorages(c *gin.Context) {
|
||||||
@ -41,18 +39,14 @@ func ListStorages(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(r.MountPoints); i++ {
|
for i := 0; i < len(r.MountPoints); i++ {
|
||||||
dataMap, err := service.MyService.Storage().GetConfigByName(r.MountPoints[i].Fs)
|
t := service.MyService.Storage().GetAttributeValueByName(r.MountPoints[i].Fs, "type")
|
||||||
if err != nil {
|
if t == "drive" {
|
||||||
logger.Error("GetConfigByName", zap.Any("err", err))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if dataMap["type"] == "drive" {
|
|
||||||
r.MountPoints[i].Icon = google_drive.ICONURL
|
r.MountPoints[i].Icon = google_drive.ICONURL
|
||||||
}
|
}
|
||||||
if dataMap["type"] == "dropbox" {
|
if t == "dropbox" {
|
||||||
r.MountPoints[i].Icon = dropbox.ICONURL
|
r.MountPoints[i].Icon = dropbox.ICONURL
|
||||||
}
|
}
|
||||||
r.MountPoints[i].Name = dataMap["username"]
|
r.MountPoints[i].Name = service.MyService.Storage().GetAttributeValueByName(r.MountPoints[i].Fs, "username")
|
||||||
}
|
}
|
||||||
list := []httper.MountPoint{}
|
list := []httper.MountPoint{}
|
||||||
|
|
||||||
|
|||||||
@ -2,20 +2,23 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"io/ioutil"
|
"log"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"bazil.org/fuse"
|
|
||||||
fusefs "bazil.org/fuse/fs"
|
|
||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/mount"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
_ "github.com/rclone/rclone/backend/all"
|
_ "github.com/rclone/rclone/backend/all"
|
||||||
"github.com/rclone/rclone/cmd/mountlib"
|
"github.com/rclone/rclone/cmd/mountlib"
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
rconfig "github.com/rclone/rclone/fs/config"
|
rconfig "github.com/rclone/rclone/fs/config"
|
||||||
"github.com/rclone/rclone/fs/log"
|
"github.com/rclone/rclone/fs/rc"
|
||||||
"github.com/rclone/rclone/vfs"
|
|
||||||
"github.com/rclone/rclone/vfs/vfscommon"
|
"github.com/rclone/rclone/vfs/vfscommon"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
@ -23,220 +26,173 @@ import (
|
|||||||
type StorageService interface {
|
type StorageService interface {
|
||||||
MountStorage(mountPoint, fs string) error
|
MountStorage(mountPoint, fs string) error
|
||||||
UnmountStorage(mountPoint string) error
|
UnmountStorage(mountPoint string) error
|
||||||
|
UnmountAllStorage()
|
||||||
GetStorages() (httper.MountList, error)
|
GetStorages() (httper.MountList, error)
|
||||||
CreateConfig(data map[string]string, name string, t string) error
|
CreateConfig(data rc.Params, name string, t string) error
|
||||||
CheckAndMountByName(name string) error
|
CheckAndMountByName(name string) error
|
||||||
CheckAndMountAll() error
|
CheckAndMountAll() error
|
||||||
GetConfigByName(name string) (map[string]string, error)
|
GetConfigByName(name string) []string
|
||||||
DeleteConfigByName(name string) error
|
GetAttributeValueByName(name, key string) string
|
||||||
|
DeleteConfigByName(name string)
|
||||||
GetConfig() (httper.RemotesResult, error)
|
GetConfig() (httper.RemotesResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type storageStruct struct {
|
type storageStruct struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storageStruct) MountStorage(mountPoint, fs string) error {
|
var MountLists map[string]*mountlib.MountPoint
|
||||||
|
var mountMu sync.Mutex
|
||||||
|
|
||||||
|
func (s *storageStruct) MountStorage(mountPoint, deviceName string) error {
|
||||||
file.IsNotExistMkDir(mountPoint)
|
file.IsNotExistMkDir(mountPoint)
|
||||||
return httper.Mount(mountPoint, fs)
|
mountMu.Lock()
|
||||||
|
defer mountMu.Unlock()
|
||||||
|
currentFS, err := fs.NewFs(context.TODO(), deviceName+":")
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("when CheckAndMountAll then", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mountOptin := mountlib.Options{
|
||||||
|
MaxReadAhead: 128 * 1024,
|
||||||
|
AttrTimeout: 1 * time.Second,
|
||||||
|
DaemonWait: 60 * time.Second,
|
||||||
|
NoAppleDouble: true,
|
||||||
|
NoAppleXattr: false,
|
||||||
|
AsyncRead: true,
|
||||||
|
AllowOther: true,
|
||||||
|
}
|
||||||
|
vfsOpt := vfscommon.Options{
|
||||||
|
NoModTime: false,
|
||||||
|
NoChecksum: false,
|
||||||
|
NoSeek: false,
|
||||||
|
DirCacheTime: 5 * 60 * time.Second,
|
||||||
|
PollInterval: time.Minute,
|
||||||
|
ReadOnly: false,
|
||||||
|
Umask: 0,
|
||||||
|
UID: ^uint32(0), // these values instruct WinFSP-FUSE to use the current user
|
||||||
|
GID: ^uint32(0), // overridden for non windows in mount_unix.go
|
||||||
|
DirPerms: os.FileMode(0777),
|
||||||
|
FilePerms: os.FileMode(0666),
|
||||||
|
CacheMode: 3,
|
||||||
|
CacheMaxAge: 3600 * time.Second,
|
||||||
|
CachePollInterval: 60 * time.Second,
|
||||||
|
ChunkSize: 128 * fs.Mebi,
|
||||||
|
ChunkSizeLimit: -1,
|
||||||
|
CacheMaxSize: -1,
|
||||||
|
CaseInsensitive: runtime.GOOS == "windows" || runtime.GOOS == "darwin", // default to true on Windows and Mac, false otherwise
|
||||||
|
WriteWait: 1000 * time.Millisecond,
|
||||||
|
ReadWait: 20 * time.Millisecond,
|
||||||
|
WriteBack: 5 * time.Second,
|
||||||
|
ReadAhead: 0 * fs.Mebi,
|
||||||
|
UsedIsSize: false,
|
||||||
|
DiskSpaceTotalSize: -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
mnt := mountlib.NewMountPoint(mount.MountFn, mountPoint, currentFS, &mountOptin, &vfsOpt)
|
||||||
|
_, err = mnt.Mount()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("when CheckAndMountAll then", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
if err = mnt.Wait(); err != nil {
|
||||||
|
log.Printf("unmount FAILED: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mountMu.Lock()
|
||||||
|
defer mountMu.Unlock()
|
||||||
|
delete(MountLists, mountPoint)
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
func (s *storageStruct) UnmountStorage(mountPoint string) error {
|
func (s *storageStruct) UnmountStorage(mountPoint string) error {
|
||||||
err := httper.Unmount(mountPoint)
|
|
||||||
if err == nil {
|
|
||||||
dir, _ := ioutil.ReadDir(mountPoint)
|
|
||||||
|
|
||||||
if len(dir) == 0 {
|
err := MountLists[mountPoint].Unmount()
|
||||||
file.RMDir(mountPoint)
|
if err != nil {
|
||||||
|
logger.Error("when umount then", zap.Error(err))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
func (s *storageStruct) UnmountAllStorage() {
|
||||||
|
for _, v := range MountLists {
|
||||||
|
err := v.Unmount()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("when umount then", zap.Error(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
func (s *storageStruct) GetStorages() (httper.MountList, error) {
|
func (s *storageStruct) GetStorages() (httper.MountList, error) {
|
||||||
|
ls := httper.MountList{}
|
||||||
return httper.GetMountList()
|
list := []httper.MountPoints{}
|
||||||
|
for _, v := range MountLists {
|
||||||
|
list = append(list, httper.MountPoints{
|
||||||
|
MountPoint: v.MountPoint,
|
||||||
|
Fs: v.Fs.Name(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ls.MountPoints = list
|
||||||
|
return ls, nil
|
||||||
|
// return httper.GetMountList()
|
||||||
}
|
}
|
||||||
func (s *storageStruct) CreateConfig(data map[string]string, name string, t string) error {
|
func (s *storageStruct) CreateConfig(data rc.Params, name string, t string) error {
|
||||||
httper.CreateConfig(data, name, t)
|
_, err := rconfig.CreateRemote(context.Background(), name, t, data, rconfig.UpdateRemoteOpt{State: "*oauth-islocal,teamdrive,,", NonInteractive: true})
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
func (s *storageStruct) CheckAndMountByName(name string) error {
|
func (s *storageStruct) CheckAndMountByName(name string) error {
|
||||||
storages, _ := MyService.Storage().GetStorages()
|
|
||||||
currentRemote, _ := httper.GetConfigByName(name)
|
mountPoint, found := rconfig.LoadedData().GetValue(name, "mount_point")
|
||||||
mountPoint := currentRemote["mount_point"]
|
if !found && len(mountPoint) == 0 {
|
||||||
isMount := false
|
logger.Error("when CheckAndMountAll then mountpint is empty", zap.String("mountPoint", mountPoint), zap.String("fs", name))
|
||||||
for _, v := range storages.MountPoints {
|
return errors.New("mountpoint is empty")
|
||||||
if v.MountPoint == mountPoint {
|
|
||||||
isMount = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
return MyService.Storage().MountStorage(mountPoint, name)
|
||||||
if !isMount {
|
|
||||||
return MyService.Storage().MountStorage(mountPoint, name+":")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mountOptions configures the options from the command line flags
|
|
||||||
func mountOptions(VFS *vfs.VFS, device string, opt *mountlib.Options) (options []fuse.MountOption) {
|
|
||||||
options = []fuse.MountOption{
|
|
||||||
fuse.MaxReadahead(uint32(opt.MaxReadAhead)),
|
|
||||||
fuse.Subtype("rclone"),
|
|
||||||
fuse.FSName(device),
|
|
||||||
|
|
||||||
// Options from benchmarking in the fuse module
|
|
||||||
//fuse.MaxReadahead(64 * 1024 * 1024),
|
|
||||||
//fuse.WritebackCache(),
|
|
||||||
}
|
|
||||||
if opt.AsyncRead {
|
|
||||||
options = append(options, fuse.AsyncRead())
|
|
||||||
}
|
|
||||||
if opt.AllowNonEmpty {
|
|
||||||
options = append(options, fuse.AllowNonEmptyMount())
|
|
||||||
}
|
|
||||||
if opt.AllowOther {
|
|
||||||
options = append(options, fuse.AllowOther())
|
|
||||||
}
|
|
||||||
if opt.AllowRoot {
|
|
||||||
// options = append(options, fuse.AllowRoot())
|
|
||||||
fs.Errorf(nil, "Ignoring --allow-root. Support has been removed upstream - see https://github.com/bazil/fuse/issues/144 for more info")
|
|
||||||
}
|
|
||||||
if opt.DefaultPermissions {
|
|
||||||
options = append(options, fuse.DefaultPermissions())
|
|
||||||
}
|
|
||||||
if VFS.Opt.ReadOnly {
|
|
||||||
options = append(options, fuse.ReadOnly())
|
|
||||||
}
|
|
||||||
if opt.WritebackCache {
|
|
||||||
options = append(options, fuse.WritebackCache())
|
|
||||||
}
|
|
||||||
if opt.DaemonTimeout != 0 {
|
|
||||||
options = append(options, fuse.DaemonTimeout(fmt.Sprint(int(opt.DaemonTimeout.Seconds()))))
|
|
||||||
}
|
|
||||||
if len(opt.ExtraOptions) > 0 {
|
|
||||||
fs.Errorf(nil, "-o/--option not supported with this FUSE backend")
|
|
||||||
}
|
|
||||||
if len(opt.ExtraFlags) > 0 {
|
|
||||||
fs.Errorf(nil, "--fuse-flag not supported with this FUSE backend")
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
type FS struct {
|
|
||||||
*vfs.VFS
|
|
||||||
f fs.Fs
|
|
||||||
opt *mountlib.Options
|
|
||||||
server *fusefs.Server
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFS(VFS *vfs.VFS, opt *mountlib.Options) *FS {
|
|
||||||
fsys := &FS{
|
|
||||||
VFS: VFS,
|
|
||||||
f: VFS.Fs(),
|
|
||||||
opt: opt,
|
|
||||||
}
|
|
||||||
return fsys
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root returns the root node
|
|
||||||
func (f *FS) Root() (node fusefs.Node, err error) {
|
|
||||||
defer log.Trace("", "")("node=%+v, err=%v", &node, &err)
|
|
||||||
root, err := f.VFS.Root()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Dir{root, f}, nil
|
|
||||||
}
|
|
||||||
func (s *storageStruct) CheckAndMountAll() error {
|
func (s *storageStruct) CheckAndMountAll() error {
|
||||||
fmt.Println(rconfig.LoadedData().GetSectionList())
|
|
||||||
mo := mountlib.Options{DeviceName: "a624669980_dropbox_1676528086"}
|
|
||||||
a, e := fs.NewFs(context.TODO(), "/root/.config/rclone/rclone.conf")
|
|
||||||
fmt.Println(e)
|
|
||||||
aaa := func(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error, func() error, error) {
|
|
||||||
f := VFS.Fs()
|
|
||||||
fs.Debugf(f, "Mounting on %q", mountpoint)
|
|
||||||
c, err := fuse.Mount(mountpoint, mountOptions(VFS, opt.DeviceName, opt)...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
filesys := NewFS(VFS, opt)
|
|
||||||
filesys.server = fusefs.New(c, nil)
|
|
||||||
|
|
||||||
// Serve the mount point in the background returning error to errChan
|
|
||||||
errChan := make(chan error, 1)
|
|
||||||
go func() {
|
|
||||||
err := filesys.server.Serve(filesys)
|
|
||||||
closeErr := c.Close()
|
|
||||||
if err == nil {
|
|
||||||
err = closeErr
|
|
||||||
}
|
|
||||||
errChan <- err
|
|
||||||
}()
|
|
||||||
|
|
||||||
// unmount := func() error {
|
|
||||||
// // Shutdown the VFS
|
|
||||||
// filesys.VFS.Shutdown()
|
|
||||||
// return fuse.Unmount(mountpoint)
|
|
||||||
// }
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
mt := mountlib.NewMountPoint(aaa, "/mnt/test", a, &mo, &vfscommon.Options{})
|
|
||||||
d, e := mt.Mount()
|
|
||||||
fmt.Println(d, e)
|
|
||||||
|
|
||||||
if e != nil {
|
|
||||||
logger.Error("when CheckAndMountAll then", zap.Error(e))
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
defer mt.Unmount()
|
|
||||||
|
|
||||||
storages, err := MyService.Storage().GetStorages()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Info("when CheckAndMountAll storages", zap.Any("storages", storages))
|
|
||||||
|
|
||||||
section := rconfig.LoadedData().GetSectionList()
|
section := rconfig.LoadedData().GetSectionList()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Info("when CheckAndMountAll section", zap.Any("section", section))
|
logger.Info("when CheckAndMountAll section", zap.Any("section", section))
|
||||||
for _, v := range section {
|
for _, v := range section {
|
||||||
|
command.OnlyExec("umount /mnt/" + v)
|
||||||
mountPoint, found := rconfig.LoadedData().GetValue(v, "mount_point")
|
mountPoint, found := rconfig.LoadedData().GetValue(v, "mount_point")
|
||||||
|
|
||||||
if !found && len(mountPoint) == 0 {
|
if !found && len(mountPoint) == 0 {
|
||||||
|
logger.Info("when CheckAndMountAll then mountpint is empty", zap.String("mountPoint", mountPoint), zap.String("fs", v))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
isMount := false
|
err := MyService.Storage().MountStorage(mountPoint, v)
|
||||||
for _, v := range storages.MountPoints {
|
|
||||||
if v.MountPoint == mountPoint {
|
|
||||||
isMount = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !isMount {
|
|
||||||
logger.Info("when CheckAndMountAll MountStorage", zap.String("mountPoint", mountPoint), zap.String("fs", v))
|
|
||||||
err := MyService.Storage().MountStorage(mountPoint, v+":")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("when CheckAndMountAll then", zap.String("mountPoint", mountPoint), zap.String("fs", v), zap.Error(err))
|
logger.Error("when CheckAndMountAll then", zap.Error(err))
|
||||||
}
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storageStruct) GetConfigByName(name string) (map[string]string, error) {
|
func (s *storageStruct) GetConfigByName(name string) []string {
|
||||||
return httper.GetConfigByName(name)
|
return rconfig.LoadedData().GetKeyList(name)
|
||||||
}
|
}
|
||||||
func (s *storageStruct) DeleteConfigByName(name string) error {
|
|
||||||
return httper.DeleteConfigByName(name)
|
func (s *storageStruct) GetAttributeValueByName(name, key string) string {
|
||||||
|
value, found := rconfig.LoadedData().GetValue(name, key)
|
||||||
|
if !found {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storageStruct) DeleteConfigByName(name string) {
|
||||||
|
rconfig.DeleteRemote(name)
|
||||||
}
|
}
|
||||||
func (s *storageStruct) GetConfig() (httper.RemotesResult, error) {
|
func (s *storageStruct) GetConfig() (httper.RemotesResult, error) {
|
||||||
section, err := httper.GetAllConfigName()
|
//TODO: check data
|
||||||
if err != nil {
|
// section, err := httper.GetAllConfigName()
|
||||||
return httper.RemotesResult{}, err
|
// if err != nil {
|
||||||
}
|
// return httper.RemotesResult{}, err
|
||||||
return section, nil
|
// }
|
||||||
|
// return section, nil
|
||||||
|
return httper.RemotesResult{}, nil
|
||||||
}
|
}
|
||||||
func NewStorageService() StorageService {
|
func NewStorageService() StorageService {
|
||||||
return &storageStruct{}
|
return &storageStruct{}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user