6

I have an Azure function running on App service plan. This Function app downloads the file from sftp and do some process/validation and then uploads to blob storage.

This was working code and I had to make some changes so that I will have to save the physical file, FileStream instead of MemoryStream. This also worked in my local environment but once deployed to Azure, I am getting FileNotFound error at the step where I download the sftp file.

Error text (edited file/class names)

System.IO.FileNotFoundException: Could not find file 'D:\home\site\wwwroot\myfile.csv'.
File name: 'D:\home\site\wwwroot\myfile.csv'
   at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
   at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at MyProcessDataLoadProcess.DownLoadMyProcessFilesFromSftp.DownloadFileFromSftp(SftpClient sftp, SftpFile sftpFile, String localRootPath) in D:\a\1\s\MyProcessDataLoadProcess\DownLoadMyProcessFilesFromSftp.cs:line 173
   at MyProcessDataLoadProcess.DownLoadMyProcessFilesFromSftp.Run(TimerInfo timerInfo, ILogger log, ExecutionContext context) in D:\a\1\s\MyProcessDataLoadProcess\DownLoadMyProcessFilesFromSftp.cs:line 106

I am sure this is something to do with the permissions because when I tried to create a test file using simple dir . > test.txt from platform features' command line tool, I am getting the "system could not find file specefied error". enter image description here

I am sure this has to do something with settings that will allow writing to the local disc because I did a POC using different subsciption where I have full permissions. I am not sure if this can be configured somewhere in app settings or need to give permissions at storage level or subscription level permissions.

Update:

For now, I found a workaround to use a temporary folder by using Path.GetTempPath(). However, I am bit puzzled what is that restriction stopping me to create the file in the root folder.

dejjub-AIS
  • 1,501
  • 2
  • 24
  • 50
  • 1
    can you verify if you have WEBSITE_RUN_FROM_PACKAGE set to 1 in your Application Setting in portal ? – Ketan Jan 16 '20 at 19:55
  • Yes @KetanChawda-MSFT its set to 1. – dejjub-AIS Jan 17 '20 at 07:39
  • With the WEBSITE_RUN_FROM_PACKAGE app setting value of 1, the zip deployment APIs copy your package to the d:\home\data\SitePackages folder instead of extracting the files to d:\home\site\wwwroot. It also creates the packagename.txt file. After a restart, the package is mounted to wwwroot as a read-only filesystem. Run From Package makes wwwroot read-only, so you will receive an error when writing files to this directory. – Ketan Jan 17 '20 at 07:55
  • Thanks @KetanChawda-MSFT. I quickly changed settings in a functions app where I was able to create file, after making this setting to 0, I am unable to create the file. Thanks, i will accept answer – dejjub-AIS Jan 17 '20 at 09:10
  • 3
    A note on performance: If durability is of no concern, always use `Path.GetTempPath()` to write (ephemeral) files to. That's going to be local storage to the web worker VM, much faster than `d:\home\site` which is network storage. – evilSnobu Jan 17 '20 at 21:23

2 Answers2

5

With the WEBSITE_RUN_FROM_PACKAGE app setting value of 1, the zip deployment APIs copy your package to the d:\home\data\SitePackages folder instead of extracting the files to d:\home\site\wwwroot. It also creates the packagename.txt file. After a restart, the package is mounted to wwwroot as a read-only filesystem. Run From Package makes wwwroot read-only, so you will receive an error when writing files to this directory.

Ketan
  • 1,530
  • 7
  • 16
  • If its copied * SitePackages can I read like below ? ExecutionContext context --> which will be parameter of Http function. string templateFile = Path.Combine(context.FunctionAppDirectory, "Images", "azure.Jpeg"); – Ravi Macha Nov 23 '20 at 21:58
1

Well, in my case, it did not allow me to change the WEBSITE_RUN_FROM_PACKAGE value. What worked for me was simply changing the deployment method from Zip deploy to Web deploy. Actually, when we do a Zip deploy our folder structures become read only in the cloud and therefore creating folders and files runtime is not allowed and we get the above error. The web deploy solves this problem and gives us the freedom to play with our solution explorer in the cloud during runtime. Please refer the below link for more details: https://tomasherceg.com/blog/post/azure-app-service-cannot-create-directories-and-write-to-filesystem-when-deployed-using-azure-devops