I am migrating from a Drupal 7 site hosted on Pantheon to Drupal 8.8.4. I am using the migrate upgrade module and running the commands through drush.
The public files all imported correctly, including the files in subdirectories. But I can't get any of the private files to work. I can't tell if the issue is the private files or the subdirectories (all of the private files are in subdirectories so it's hard to isolate).
When I run drush migrate:import upgrade_d7_file_private
and check the migrate messages I get errors such as Cannot read from non-readable stream (http://[hostname]/sites/default/files/private/subdirectory/file.pdf)
I see the MigratePrivateFileTest.php test passes, so I assume it's not just private files only that are the problem. The test sets the private directory at sites/default/private
, but Pantheon requires it to be at sites/default/files/private
. Maybe that is the problem?
I tried creating a test for that scenario (file_private_path set to sites/default/files/private, no further subdirectories) and it fails. But I also tried creating a test for public files in subdirectories (which works on my site migration) and that test fails too so something is not correct about my test.
I'm attaching a patch with those two tests. If anyone has advice on making the MigrateFileSubdirectoryTest.php
pass (since I believe the functionality is working) then I can make a tests that shows my problem better.
Comment | File | Size | Author |
---|---|---|---|
#39 | 3123350-11.x-MR6919.patch | 974 bytes | anybody |
#29 | patch-29.patch | 974 bytes | grevil |
#2 | migrate_files_alternate_path_tests_3123350_1.patch | 3.31 KB | sagannotcarl |
Issue fork drupal-3123350
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
sagannotcarl CreditAttribution: sagannotcarl as a volunteer commentedComment #3
quietone CreditAttribution: quietone as a volunteer commented@sagannotcarl, the source path for files is set in the migration, d7_file_private. You should only have to edit the configured migration to set the correct path for your system. It is 'source_base_path'. See https://git.drupalcode.org/project/drupal/-/blob/8.8.x/core/modules/file...
I hope that helps.
Comment #4
sagannotcarl CreditAttribution: sagannotcarl as a volunteer commented@quietone I have 'source_base_path' set in the configured migration, and that part is working. In the
Cannot read from non-readable stream
error the base path is there and appears to be correct.By correct I mean that it's looking for the file at
http://[base_path]/sites/default/files/private/subdirectory/file.pdf
, the base path is correct, the private files live at sites/default/files/private, the subdirectory is correct and the filename is correct. Is there something else that would make it a non-readable stream? Something about the files being private?Thanks so much for the help.
Comment #5
jim.shreds CreditAttribution: jim.shreds commentedAlso seeing this on upgrade_d7_file_private.
Comment #6
sagannotcarl CreditAttribution: sagannotcarl as a volunteer commented@quietone I guess the other question is whether you think these tests I wrote are valid (i.e. properly demonstrate the bug)?
Comment #7
mrP CreditAttribution: mrP commentedI had to patch core/modules/file/src/Plugin/migrate/source/d7/File.php to get around this type of issue when migrating a D7 (multisite installation type) to D8 (also multisite installation type).
file_public_path was properly set on my D7 site, but it wasn't reading it in for some reason and kept defaulting to 'sites/default/files'. Example error:
File '/var/www/drupal7//sites/default/files/picture_282.png' does not exist.
file_public_path in D7 = sites/example.com/files
Comment #8
sagannotcarl CreditAttribution: sagannotcarl as a volunteer commented@mrP I tried your patch is it's not helping in my situation. For me the the
prepareRow()
function in.../d7/File.php
is preparing my path correctly. At least it is the actual path of the file in the filesystem. My hypothosis is that because it's a private file the stream is expecting something else other than the actual filepath? Does anyone know if that is true?If
$row->setSourceProperty('filepath', $path);
is correctly setting the actual path of the file on the d7 site for a private fle, why else would I get aCannot read from non-readable stream
error?Comment #9
jim.shreds CreditAttribution: jim.shreds commentedim a dummy. forgot to remove the htaccess file from within the top level of the directory holding the private files.
Comment #10
sagannotcarl CreditAttribution: sagannotcarl as a volunteer commented@jim.shreds Is removing the htaccess file from the top level of the private files directory a requirement for migration? I haven't seen that mentioned anywhere but it does make sense if it's true. I assume that would cause a
Cannot read from non-readable stream
error?Comment #11
jim.shreds CreditAttribution: jim.shreds commented@sagannotcarl i have not seen it mentioned anywhere in any documentation. i only did it while quadruple checking file permissions inside of terminal. but yea in the end private files are now migrating.
Comment #14
quietone CreditAttribution: quietone as a volunteer commented@sagannotcarl, did the suggestion by jim.shreds to remove .htaccess allow you to migrate the files?
Comment #15
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedCould it perhaps be the same problem as described here?
https://drupal.stackexchange.com/questions/283175/files-migration-issue
We're currently running into the same situation where the OLD source directory is prepended to the file path,
The link describes it perfectly! Or is that a different issue? This is the closest one I could find.
Example:
Expected:
"../_migration/files/old-private-files-source/dirXYZ/fileABC.pdf"
Actual / current result:
"../_migration/files/old-private-files-source//my-old-drupal7-private-file-directory-path-from-db-variables/dirXYZ/fileABC.pdf"
The OLD results from private:// should NOT be used here, as the directory is environment specific. And if someone needs it, it can be added to source_base_path! But removing it (without changing the source db or hacking core like in #7) seems problematic!?
Comment #16
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedIndeed the most simple, but dirty workaround is to delete the "file_privat_path" row from the copy of the source database variables table...
DELETE FROM variables WHERE name="file_private_path";
Tadaaa... problems gone! So I think this should be rated as major problem / bug for private files.
And like written in #7 the problem starts with these two functions in File.php:
In contrast to the private path, appending the old directory to public paths (or URL) is correct as that's still the folder to search in, while it's not for private files.
I'd suggest to make this configurable in the yml file by splitting the variables for example... something like this (especially for public files);
and removing the files directory variable from filepath!
Or simply documenting that source_base_path for private files should contain the /sites/default/files directory?
@quietone: Do you see the problem and what do you think?
Comment #17
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedAdding #3189876: Add documentation for file source plugins as related for documentation update after this was fixed.
Comment #18
anybodyDid the debugging with @Grevil and agree that for private files the combination with the private file path in "filepath" is a problem, while it leads to expected results for public files. Splitting the variables would be the most flexible way to solve this, I guess. "filepath" should never contain the replacement of the private:// or public:// scheme like it currently does.
Quite complex... especially not introducing a breaking change.
Currently I think it CAN only work if migration source and target are on the same machine, accessing the same directory structure or using an identical one for private files...
Comment #19
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedIt's also worth reading the old issue: #2505283: Handle import of private files.
In #58 there was a constant "source_private_file_path" which got lost later on?
Comment #20
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedComment #21
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedAs alternative to the SQL we added a dirty workaround in the issue fork to never prepend the file_private_path to the filepath. Of course that's not a real solution.
One could also discuss to split "filepath" variable from "filedir" and put them together in source_full_path for a non-BC!
@quietone I guess we need your feedback :)
Comment #23
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedComment #24
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedComment #25
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commented#2925899: MigrateUpgradeImportBatch does not use source_private_file_path & source_base_path correctly, making it impossible to have public & private files in separate locations also seems possibly related?
Comment #27
anybodyJust migrated another project and can confirm the issue still exists. The workaround in the MR fixes it. So we may proceed here with a cleaner fix, for example provide the private path in a separate migration variable or as
source_base_path
!Comment #28
quietone CreditAttribution: quietone at PreviousNext commentedJust updating tags,
Comment #29
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedHere is a static patch for the time being.
Comment #32
steve hanson CreditAttribution: steve hanson as a volunteer commentedI have applied patch 29 but am still seeing the path being built incorrectly by concatenating the public and private paths together after also applying the patch for https://www.drupal.org/project/migrate_upgrade/issues/2921617#comment-15... so that the private path can be applied while setting up a drush migration. I'm somewhat bewildered that I cannot determine a way to make this work properly considering how long it has been broken.
Comment #38
anybodyRerolled MR!1367 againt 11.x in MR!6919. Verified both are the same and equal to #29.
Applies cleanly against 11.x - but still a quickfix as documented.
Comment #39
anybodyMR!6919 as patch attached!
Comment #40
grevil CreditAttribution: grevil as a volunteer and at DROWL.de commentedPatch from #39 applies perfectly on 11.x, thx!