-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AWS S3 sync #2815
Add AWS S3 sync #2815
Conversation
Thanks @alexchee, the code looks pretty good already. What test is failing at the moment? |
@@ -357,6 +357,16 @@ function shimInit() { | |||
return Buffer.byteLength(string, 'utf-8'); | |||
}; | |||
|
|||
shim.readFileToBlob = async function(path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be in fsdriver. But what is the purpose of it? It seems similar to fsDriver.readFile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad you brought this up, I wasn't sure if I needed to handle deal with binary files on React Native differently. But readFile
would be simplier.
if (!options.path) throw new Error('get: target options.path is missing'); | ||
|
||
// TODO: check if this ever hits on RN | ||
await shim.fsDriver().writeBinaryFile(options.path, output); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@laurent22 I have a question here for React Native, how should the driver handle get
for files on RN? writeBinaryFile
will raise an exception on the RN shim.
It's varies between 5 and 45 failed tests each run. I think I know my issue. S3 here are the current fails:
|
After playing with this more, S3 isn't good enough for syncing notes. The reads are inconsistent, I'll need to redo this with another AWS service like DynamoDB. I'll close it for now until I get it working with another AWS service. Thanks for the help @laurent22 . |
Hi @alexchee , sorry for the delay, I didn't realize that the forums weren't notifying me of your responses. @laurent22 , what's your take on the possibilities for s3-compatible storage at this point, given all the work that @alexchee has done? Still think it's doable? I've been meaning to see if I can serve up s3 (from minio) via webdav without it being too hacky. May try that now. |
I'd be ok with adding an S3 sync target to the app, but I guess it's not up to me as I don't know enough about it. I'm surprised that reads are inconsistent actually, given how widely used S3 is, do you know exactly what the issue was @alexchee? |
The current issue is using s3 as a lock for syncing. S3 has eventual consistency (read-after-write), but it's not reliable on it's own for locking syncs between multiple devices. S3 is ok for one device to write time with mutliple devices to only read and download. But, if there's multiple devices/processes trying to write and obtain a lock, it'll behave like in the tests where it'll see files with unexpected timestamps because another process/test has written to that same file. If something else can be using to determine locks for syncing with S3, this would make s3 a better storage option. Usually if people need to do something with syncing on s3, they assume there's only one source for that specific object being written or built something else around it to lock the s3 objects. I'm testing out something with dynamoDB (consistent reads/write but 40kb file limit) and S3 but that seems like a hassle for most users. Any ideas here? |
Hmm yes Joplin sync has never really be tested with eventual consistency storage. I suppose it could work, it just means that changes will take a bit longer to be applied to all clients. Test units however wouldn't work as it is because the test checks that the data has been written, and S3 will report that it has not. Perhaps for testing purposes you could add a delay of x seconds after each put operation? That will ensure that following reads will be correct. As for dynamoDB the 40kb limit would not be enough I think. |
I agree about dynamoDB. So running each of the fail tests individually and deleting the bucket after each run makes most of the test pass. Only 3 tests are failing:
My guess is my delete method probably needs to be recursive with directories like |
Ok, I got it working and the tests passing. I found out my implementation of FileApi |
I still an uncertain about if will work on ReactNative because I do some |
|
||
async s3UploadFileFrom(path, key) { | ||
if (!shim.fsDriver().exists(path)) throw new Error('s3UploadFileFrom: file does not exist'); | ||
const body = await shim.fsDriver().readFile(path, 'Buffer'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for put
with options.source === 'file'
, not sure if this will break on ReactNative/mobile apps.
I'm not sure why Travis is failing, the logs show the tests passing. I did do some file operations in the new tests, would that impact travis? |
7419215
to
1f0d299
Compare
looks like it's failing with NoteHistory test, after I rebased with master:
Any advice on where I should look to fix this? |
@alexchee, there was some problem on the test units on master, but it should be fixed now if you rebase. Do you currently use the S3 sync target on desktop? If it works, I guess we could release it for desktop only for now and see if users might be interested. If they are, we could test on mobile and enable for it too. What do you think? |
That sounds like a good step. I currently use Dropbox sync so I can have it on my desktop and mobile, but I'll switch it over to S3 for my desktops to get more usage. |
It would be good if this was able to be configured to work with S3 compatible API's like Minio as well |
I like that idea to get more people to use this feature. But I have not used minIO. How easy would it be to adapt that API to this and would it require people to use minIO on their S3 buckets? |
Minio allows a user to run their own S3 compatible server. So for example you can use a client like Boto3 to connect to either AWS S3 or to a minio installation.The only changes will likely be in configuration - allowing the user to specify the _entire_ URL etcI can try have a hack at it later this week and see if I can make it work.On 14 Jul 2020 18:56, alexchee <notifications@github.com> wrote:
I like that idea to get more people to use this feature. But I have not used minIO. How easy would it be to adapt that API to this and would it require people to use minIO on their S3 buckets?
—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or unsubscribe.
|
Check this link, minio with the same package you have used: https://docs.min.io/docs/how-to-use-aws-sdk-for-javascript-with-minio-server.html
Yeah, looking at your code - it looks like it just needs additional config fieldsOn 14 Jul 2020 19:09, iain@matchdev.co.uk wrote:Minio allows a user to run their own S3 compatible server. So for example you can use a client like Boto3 to connect to either AWS S3 or to a minio installation. The only changes will likely be in configuration - allowing the user to specify the _entire_ URL etcI can try have a hack at it later this week and see if I can make it work
|
As long as it's "s3-compatible" we should be most of the way there and then we can test it against the specific storage backends. For instance, I run Ceph at work and would hapilly run Joplin on my own personal Ceph cluster. S3 compatibility would open so many more (and better) storage options. How can I help test the builds? Are there releases for your branch? |
I think @laurent22 was waiting for people that wanted to use it before releasing it to test out. |
Is this branch in a working state ATM?
|
It is working. And the conflicts with master seems to be resolvable. |
Cool, I'm rebuilding my work laptop 2m, I'll see about spinning it up and testing it with minio
|
* added tests for FileApiDriver
I just resolved the conflict and force pushed out the resolved code. You might want to pull down the new branch |
(please be gentle - been a long while since I've done anything React or Electron based) it didn't take much - but the PR appears to sync with minio :) |
Headlines are:
|
@alexchee, thanks for the pull request. I've checked again and don't see any issue so let's merge. For now I've added (Beta) to the sync target label to make it clear we might need a bit more real-life testing, but I expect we can make it official quite soon. |
Adds syncing with AWS bucket, requires read/write access to the whole bucket. DO NOT share bucket with any thing else, it will erase them.
I am able to get it to sync with my s3 bucket over the electron app with resources and E2EE enabled, but tests are failing. I'm making a PR it here in case someone can help me figure out what is causing the fails. Also I haven't had much experience with React Native and can use someone to help me test that.
Setup
Block all public access
if you don't want your notes available to public: https://s3.console.aws.amazon.com/For extra access control, make sure the user can only read and write to s3 bucket. Here's an example Policy, if the bucket is called
my-joplin-bucket
:Create access key
under User's security credentials, and save the ID and Secret.AWS S3
Running
cd ElectronClient
npm start
Testing
CliClient/tests/support/amazon-s3-auth.json
with your AWS credentials. Should use a different AWS bucket than your dev one to prevent it deleting all your dev content.CliClient/tests/test-utils.js
, comment outuncomment
npm run test
TODO: