0

I am deploying a .NET Core 3.1 Console app as an Application Package to execute jobs through Azure's batch service.

When I attempt to execute the job, the execution fails with the following error:

Unhandled exception. System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is '/mnt/batch/tasks/workitems/FeedUpdates_Prod/job-1/FeedUpdate-20200107_1/wd/appsettings.json'.
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at App.jobs.Program.Main(String[] args) in C:\Development\app\app\app.jobs\Program.cs:line 24
Aborted (core dumped)

Here is the code where I am setting up the host and instructing it to use the json file (note that it gets the same error whether the config.SetBasePath line is called or not).

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile(
                       "appsettings.json", optional: false, reloadOnChange: false);
                    config.AddCommandLine(args);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

        }

The appsettings.json file is included in the application package I uploaded but is not present in the directory it's looking in ('/mnt/batch/tasks/workitems/FeedUpdates_Prod/job-1/FeedUpdate-20200107_1/wd/appsettings.json') so the message is accurate but I'm unclear as to why it's looking in that particular folder or how to tell it to look in the application's folder.

This is the command being executed to fire the job:

/bin/sh -c $AZ_BATCH_APP_PACKAGE_app_jobs"/app.Jobs -jFeedUpdate" 

File Listing Showing appsettings.json

3 Answers3

1

I would recommend reading through this document: https://learn.microsoft.com/en-us/azure/batch/batch-application-packages

envinroment var access I think this is the wrong location you are looking at, please refer to this : https://learn.microsoft.com/en-us/azure/batch/batch-application-packages#execute-the-installed-applications

Idea for physical location: you can remote into the node or use tool like Batch-explorer to see where the right directory level is but if I am not wrong the task level application packages are residing usually at: /mnt/batch/tasks/applications/ folder level (I think).

Tats_innit
  • 33,991
  • 10
  • 71
  • 77
  • Thanks for the links but I'm not quite sure what you mean by 'environment var access - I think this the wrong location you are looking at'. I am executing the application using the following command line: /bin/sh -c $AZ_BATCH_APP_PACKAGE_app_jobs"/app.Jobs" -j "FeedUpdate" and it's finding the application code but for some reason it is looking in a completely different directory for the appsettings.json. – Mark Thompson Jan 08 '20 at 05:55
  • 1
    Cool, so the reason I mention that is because nowhere in the OP I see reference of the correct env var. Also what do you mean by “looking in a completely different directory” reason I ask is because that can only happen if you are using wrong environment variable. **Few debugging pointer** I would recommend that you should try running just ‘env’ command so that it will print all the environment variables and that way you can see what is the correct environment variable to be used. **secondly** the commaline shared above has random (“”) double quotes is that intentional. Thanks, this will help. – Tats_innit Jan 08 '20 at 15:01
  • I'll try running the env command as you suggest. As to the random double quotes, this is running on a linux and the env vars aren't delimited at the beginning and end as they are in windows with % so I need to delimit the env var from the remainder of the command line. Without them, I get an error. – Mark Thompson Jan 08 '20 at 15:13
  • Cool, sounds good! Glad you added the command line in your post now. Also regarding how to pass the path here is the sample which might help you: https://stackoverflow.com/questions/52138427/how-to-pass-application-path-to-task-in-azure-batch. **Or** https://github.com/Azure-Samples/azure-batch-samples/blob/master/Python/Batch/README.md#azure-batch-on-linux-best-practices have a play around and I think you will find out right way to use, I have a feeling it’s the use of extra quote and env car so run “env” and that way you should be able to see available env vars. Thanks! – Tats_innit Jan 08 '20 at 15:19
1

Your stack trace shows the directory your code is trying to load the configuration file from:

Unhandled exception.
System.IO.FileNotFoundException:
The configuration file 'appsettings.json' was not found and is not optional.
The physical path is '/mnt/batch/tasks/workitems/FeedUpdates_Prod/job-1/FeedUpdate-20200107_1/wd/appsettings.json'.

This folder is the task working directory.

Application packages aren't downloaded into the task working directory because they can be used by multiple tasks - this is why your commandline needs to use the environment variable $AZ_BATCH_APP_PACKAGE_app_jobs.

In your code snippet, you have this line:

config.SetBasePath(Directory.GetCurrentDirectory());

This is setting the current directory as the location from which to load the configuration file.

Instead, you want to load the configuration file from the deployment location of the console application itself.

I'm not familiar with the way ASP.NET Core handles configuration, but I would expect the directory you need to be available on hostingContext.

Modify your call to config.SetBasePath() to pass the directory containing your application; you should then be able to load your configuration file.

Bevan
  • 43,618
  • 10
  • 81
  • 133
  • Thanks for the tip but I actually tried that before posting. Whether I include that line or not, it still looks in the same location for the appsettings.json and doesn't find it. – Mark Thompson Jan 09 '20 at 16:46
0

I was able to work around this by adding the appsettings as a Resource to the task which then brought it into the working directory.

It's not ideal and I don't understand why it can find the executable and supporting files but not the appsettings which is located in the same application package so if anyone has an answer to that, I'd like to know.