Skip to content
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

SFTP-Storage: Correctly Sync mtime #22294

Closed
wants to merge 1 commit into from

Conversation

msander
Copy link

@msander msander commented Aug 18, 2020

Currently uploading a file to an external SFTP storage does not keep the mtime.
Besides losing this information is bad by itself, fast repeated changing / syncing of a file on the external storage, creates conflicts randomly (maybe if a change happens during the upload?).

Using the provided change, I was not able to reproduce the issue anymore.

@MorrisJobke
Copy link
Member

Looks good - but maybe @icewind1991 or so has another look at this.

@kesselb
Copy link
Contributor

kesselb commented Aug 20, 2020

Thanks for taking the time to submit a pull request 👍

I had a short look at the code and phpseclib. Here are my thoughts:

  1. touch method. I would remove the file_exists check, try-catch block and forward the call to phpseclib's sftp implementation: https://github.com/nextcloud/3rdparty/blob/10acc20198442f3c04bc1abbf9ad540a3afbab40/phpseclib/phpseclib/phpseclib/Net/SFTP.php#L1403-L1452
	/**
	 * {@inheritdoc}
	 */
	public function touch($path, $mtime = null) {
		return $this->getConnection()->touch($this->absPath($path), $mtime);
	}

It seems that the upstream implementation does everything we need.

  1. loose mtime on upload. A recent commit phpseclib/phpseclib@ea653e1#diff-f0500f119a16ba4ff6303ba9008b1ce1 added a feature to preserve access and modified time on download/upload to phpseclib's sftp implementation. I guess we need something similar for our SFTPWriteStream and SFTPReadStream wrapper to keep the information. I'm not sure if touch is always called after a write operation thus it's not enough to fix only the touch method.

@rullzer rullzer mentioned this pull request Aug 21, 2020
19 tasks
@msander
Copy link
Author

msander commented Aug 23, 2020

  1. loose mtime on upload. A recent commit phpseclib/phpseclib@ea653e1#diff-f0500f119a16ba4ff6303ba9008b1ce1 added a feature to preserve access and modified time on download/upload to phpseclib's sftp implementation. I guess we need something similar for our SFTPWriteStream and SFTPReadStream wrapper to keep the information. I'm not sure if touch is always called after a write operation thus it's not enough to fix only the touch method.

I don't think we need to handle the mtime for streams. The mtime is part of the file status, a stream just handles the content.

@msander
Copy link
Author

msander commented Aug 23, 2020

Thanks for taking the time to submit a pull request

I had a short look at the code and phpseclib. Here are my thoughts:

  1. touch method. I would remove the file_exists check, try-catch block and forward the call to phpseclib's sftp implementation: https://github.com/nextcloud/3rdparty/blob/10acc20198442f3c04bc1abbf9ad540a3afbab40/phpseclib/phpseclib/phpseclib/Net/SFTP.php#L1403-L1452
	/**
	 * {@inheritdoc}
	 */
	public function touch($path, $mtime = null) {
		return $this->getConnection()->touch($this->absPath($path), $mtime);
	}

It seems that the upstream implementation does everything we need.

Thank you for your suggestions, I have changed my commit accordingly.

@msander
Copy link
Author

msander commented Aug 24, 2020

Thank you for your suggestions, I have changed my commit accordingly.

Today, this change has resulted in a sync conflict again.
I have changed it on our server back to the old version, which was running in production for over a week without issues:

        public function touch($path, $mtime=null) {
		try {
			if (!$this->file_exists($path)) {	
				$this->getConnection()->put($this->absPath($path), '');	
			} else {	
				$this->getConnection()->touch($this->absPath($path), $mtime);
			}	
		} catch (\Exception $e) {	
			return false;	
		}
		return true;
	}

@rullzer rullzer mentioned this pull request Aug 27, 2020
21 tasks
@rullzer rullzer mentioned this pull request Sep 3, 2020
13 tasks
@rullzer rullzer mentioned this pull request Sep 11, 2020
5 tasks
@rullzer rullzer modified the milestones: Nextcloud 20, Nextcloud 21 Sep 17, 2020
@rullzer
Copy link
Member

rullzer commented Sep 17, 2020

Since not many of the devs here use sftp. I think moving this to 21 to have all the things properly reviewed and possibly backported.

@kesselb any idea why your suggestions did 💥 ?

This was referenced Dec 14, 2020
This was referenced Dec 28, 2020
@rullzer
Copy link
Member

rullzer commented Jan 7, 2021

@kesselb can you have another look here?

@rullzer rullzer modified the milestones: Nextcloud 21, Nextcloud 22 Jan 8, 2021
@PVince81
Copy link
Member

@msander doing just a put might not be enough to have the exact same mtime due to network round trips.
You might need to first do a put with empty file, and then directly touch afterwards.

This was referenced May 20, 2021
@blizzz blizzz mentioned this pull request Jun 2, 2021
57 tasks
@MorrisJobke MorrisJobke mentioned this pull request Jun 10, 2021
59 tasks
@blizzz blizzz mentioned this pull request Jun 16, 2021
45 tasks
@blizzz
Copy link
Member

blizzz commented Jun 16, 2021

what's the current state here?

@blizzz blizzz mentioned this pull request Jun 23, 2021
39 tasks
@blizzz blizzz modified the milestones: Nextcloud 22, Nextcloud 23 Jun 24, 2021
@skjnldsv skjnldsv mentioned this pull request Oct 13, 2021
@skjnldsv
Copy link
Member

As there is no feedback since a while I will close this PR. If you are still willing to get this in, please address the potential comments and rebase to latest master. Then, feel free to re-open.

@skjnldsv skjnldsv closed this Oct 13, 2021
@skjnldsv skjnldsv removed this from the Nextcloud 23 milestone Oct 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants