1

I have already searched for this issue. But the task was different on each question/blog. So those answers or solution are not relevant to me.

First, here my task details.

User uploads a CSV file in a request. I'm storing that file using laravel's filesystem (local driver).

$path = $request->file('csv_file')->storeAs('requests/' . $userRequest->id, 'input.csv');

So that CSV file will be stored as storage/app/requests/{$userRequest->id}/input.csv. I have checked owner of requests directory, and it is www-data.

Now I have set some artisan command in cronjobs to process the user requests. And I have to store output of the process in that request directory i.e, storage/app/requests/{$userRequest->id}/output/output_1.csv.

$file = 'requests/' . $userRequest->id . '/output/' . $outputfilename . '.csv';
\Storage::put($file, $content);

But while creating output file, it throws error

Impossible to create the root directory

I know the reason. It is because of the owner who runs artisan command. Artisan command is run by another user (akshay), while requests directory is created by www-data.

So here are possible ways to fix this according to me.

  1. Run artisan command by the www-data user.
  2. create request directory and upload the file with user akshay as owner.

Many users have suggested changing the owner of the directory. e.g, this one. But as we can see, in my case, the creation of directories is fully dynamic. So I can't do that. But I don't know how to do any of the above with laravel.

I would prefer option (2) because only "request file uploading" will be done by the www-data user. All other executions will be done by akshay user. e.g, I have to upload file only one time. But I have to store process output for 500 times.

If anyone knows the answer, it will be appreciated.

Akshay Vaghasiya
  • 1,597
  • 9
  • 36
  • 60

3 Answers3

1

After struggling my head all the day with this, I decided to use the easy solution:

Create the cronjob for the www-data user

sudo -u www-data cronjob -e

I hope it helps, I really could not find a best solution when working with cron jobs, artisan commands and directories.

cristiancastrodc
  • 188
  • 1
  • 13
0

It's nothing to do with the owner of the directory. I had this problem once. you must check if the directory doesn't exist you create with File::makeDirectory method:

  File::exists(storage_path($csvPath )) or File::makeDirectory(storage_path($csvPath ));

So you must first get the file from the request.Give it a name. and then determine the path the file should be saved. Then make that directory. And next move the file there.If the extension of the uploaded file is .csv you just get that extension by this $file->getClientOriginalExtension() , and then save the file. If the original extension is not csv you make it your self by .csv, you should do something like this code below:

      $file = $request->file('csv_file');

      $name = $outputfilename . "." .$file->getClientOriginalExtension();

      $csvPath = '/requests/' . $userRequest->id . '/output/';

      File::exists(storage_path($csvPath )) or File::makeDirectory(storage_path($csvPath ));

      $file->move(storage_path() . '/requests/' . $userRequest->id . '/output/', $name);

So make sure that you first check the existence of directory and then make the directory by checking if the directory exists or not.

Then for accessing that csv_file if you use laravel version 5.3 or higher, you type this command in command line:

php artisan storage:link

this will make a storage link in your public directory named storage. so that you can access the file from there. if you delete Or update the file through public/storage/... it automatically makes that changes to the file in storage/app/... path.

Hope it would help!

Salar Bahador
  • 1,433
  • 1
  • 14
  • 26
0

My system threw this exception on a Debian box because the path didn't exist because a mount hadn't remounted. (So mount -a as root worked.)

jezmck
  • 1,138
  • 3
  • 18
  • 38