[v11,11/12] config: Make configuration file configurable
diff mbox series

Message ID 20250624083612.27230-12-mzamazal@redhat.com
State Superseded
Headers show
Series
  • Add global configuration file
Related show

Commit Message

Milan Zamazal June 24, 2025, 8:36 a.m. UTC
To support easy switching of configurations, let's introduce
LIBCAMERA_CONFIG_NAME environment variable, which denotes:

- The path of the configuration file to load if it is an absolute path; or
- the path of the configuration file to load, relative to the configuration
  directories.

If such a configuration file doesn't exist, no custom configuration is
loaded.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 Documentation/runtime_configuration.rst |  8 ++++++
 src/libcamera/global_configuration.cpp  | 33 ++++++++++++++++---------
 2 files changed, 30 insertions(+), 11 deletions(-)

Comments

Barnabás Pőcze June 27, 2025, 2 p.m. UTC | #1
Hi

2025. 06. 24. 10:36 keltezéssel, Milan Zamazal írta:
> To support easy switching of configurations, let's introduce
> LIBCAMERA_CONFIG_NAME environment variable, which denotes:
> 
> - The path of the configuration file to load if it is an absolute path; or
> - the path of the configuration file to load, relative to the configuration
>    directories.
> 
> If such a configuration file doesn't exist, no custom configuration is
> loaded.
> 
> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
> ---
>   Documentation/runtime_configuration.rst |  8 ++++++
>   src/libcamera/global_configuration.cpp  | 33 ++++++++++++++++---------
>   2 files changed, 30 insertions(+), 11 deletions(-)
> 
> diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst
> index de74fa732..5648db7d7 100644
> --- a/Documentation/runtime_configuration.rst
> +++ b/Documentation/runtime_configuration.rst
> @@ -19,6 +19,14 @@ order:
>   - LIBCAMERA_SYSCONF_DIR/configuration.yaml
>   - /etc/libcamera/configuration.yaml
>   
> +The default name of the configuration file, configuration.yaml, can be
> +overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable
> +can specify just an alternative configuration file name to be looked up
> +in the locations above, or it can contain a whole relative or absolute
> +path. If an absolute path is specified then it is the only location that
> +is used; if the given file doesn't exist then no configuration file is
> +read.
> +
>   The first configuration file found wins, contingent configuration files
>   in other locations are ignored.
>   
> diff --git a/src/libcamera/global_configuration.cpp b/src/libcamera/global_configuration.cpp
> index f7c69890c..2c3b6cf97 100644
> --- a/src/libcamera/global_configuration.cpp
> +++ b/src/libcamera/global_configuration.cpp
> @@ -23,13 +23,6 @@
>   
>   namespace libcamera {
>   
> -namespace {
> -const std::vector<std::filesystem::path> globalConfigurationFiles = {
> -	std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml",
> -	std::filesystem::path("/etc/libcamera/configuration.yaml"),
> -};
> -}
> -
>   LOG_DEFINE_CATEGORY(Configuration)
>   
>   /**
> @@ -74,6 +67,25 @@ bool GlobalConfiguration::loadFile(const std::filesystem::path &fileName)
>   
>   bool GlobalConfiguration::load()
>   {
> +	const std::vector<std::filesystem::path> globalConfigurationDirectories = {
> +		std::filesystem::path(LIBCAMERA_SYSCONF_DIR),

I would probably add `LIBCAMERA_DATA_DIR` after the above, so e.g. `/usr/share/libcamera/configuration.yaml`
could be the configuration that libcamera ships by default. Although I suppose
it might not be too useful until configuration file merging is implemented.


> +		std::filesystem::path("/etc/libcamera"),

I am not sure if we want any hard-coded paths. I believe removing this won't affect
the vast majority, but e.g. if one wants a local installation with a custom prefix,
it might be surprising that libcamera loads configuration from outside.


Regards,
Barnabás Pőcze


> +	};
> +
> +	const char *libcameraConfigName =
> +		utils::secure_getenv("LIBCAMERA_CONFIG_NAME");
> +	if (!libcameraConfigName)
> +		libcameraConfigName = "";
> +	std::filesystem::path configName(libcameraConfigName);
> +
> +	if (configName.is_absolute()) {
> +		loadFile(configName);
> +		return !!yamlConfiguration_;
> +	}
> +
> +	if (configName.empty())
> +		configName = std::filesystem::path("configuration.yaml");
> +
>   	std::filesystem::path userConfigurationDirectory;
>   	const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
>   	if (xdgConfigHome) {
> @@ -87,15 +99,14 @@ bool GlobalConfiguration::load()
>   
>   	if (!userConfigurationDirectory.empty()) {
>   		std::filesystem::path user_configuration_file =
> -			userConfigurationDirectory / "libcamera" / "configuration.yaml";
> +			userConfigurationDirectory / "libcamera" / configName;
>   		if (loadFile(user_configuration_file))
>   			return !!yamlConfiguration_;
>   	}
>   
> -	for (const auto &path : globalConfigurationFiles) {
> -		if (loadFile(path))
> +	for (const auto &path : globalConfigurationDirectories)
> +		if (loadFile(path / configName))
>   			return !!yamlConfiguration_;
> -	}
>   
>   	yamlConfiguration_ = std::make_unique<YamlObject>();
>   	return true;
Milan Zamazal June 27, 2025, 9:32 p.m. UTC | #2
Hi Barnabás,

Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:

> Hi
>
> 2025. 06. 24. 10:36 keltezéssel, Milan Zamazal írta:
>> To support easy switching of configurations, let's introduce
>> LIBCAMERA_CONFIG_NAME environment variable, which denotes:
>> - The path of the configuration file to load if it is an absolute path; or
>> - the path of the configuration file to load, relative to the configuration
>>    directories.
>> If such a configuration file doesn't exist, no custom configuration is
>> loaded.
>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>> ---
>>   Documentation/runtime_configuration.rst |  8 ++++++
>>   src/libcamera/global_configuration.cpp  | 33 ++++++++++++++++---------
>>   2 files changed, 30 insertions(+), 11 deletions(-)
>> diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst
>> index de74fa732..5648db7d7 100644
>> --- a/Documentation/runtime_configuration.rst
>> +++ b/Documentation/runtime_configuration.rst
>> @@ -19,6 +19,14 @@ order:
>>   - LIBCAMERA_SYSCONF_DIR/configuration.yaml
>>   - /etc/libcamera/configuration.yaml
>>   +The default name of the configuration file, configuration.yaml, can be
>> +overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable
>> +can specify just an alternative configuration file name to be looked up
>> +in the locations above, or it can contain a whole relative or absolute
>> +path. If an absolute path is specified then it is the only location that
>> +is used; if the given file doesn't exist then no configuration file is
>> +read.
>> +
>>   The first configuration file found wins, contingent configuration files
>>   in other locations are ignored.
>>   diff --git a/src/libcamera/global_configuration.cpp b/src/libcamera/global_configuration.cpp
>> index f7c69890c..2c3b6cf97 100644
>> --- a/src/libcamera/global_configuration.cpp
>> +++ b/src/libcamera/global_configuration.cpp
>> @@ -23,13 +23,6 @@
>>     namespace libcamera {
>>   -namespace {
>> -const std::vector<std::filesystem::path> globalConfigurationFiles = {
>> -	std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml",
>> -	std::filesystem::path("/etc/libcamera/configuration.yaml"),
>> -};
>> -}
>> -
>>   LOG_DEFINE_CATEGORY(Configuration)
>>     /**
>> @@ -74,6 +67,25 @@ bool GlobalConfiguration::loadFile(const std::filesystem::path &fileName)
>>     bool GlobalConfiguration::load()
>>   {
>> +	const std::vector<std::filesystem::path> globalConfigurationDirectories = {
>> +		std::filesystem::path(LIBCAMERA_SYSCONF_DIR),

Let's avoid cycling discussions:

> I would probably add `LIBCAMERA_DATA_DIR` after the above, so
> e.g. `/usr/share/libcamera/configuration.yaml`
> could be the configuration that libcamera ships by default. Although I suppose
> it might not be too useful until configuration file merging is implemented.

https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050991.html:

  At the moment, we don't need a default configuration in
  /usr/share/libcamera, maybe distributions could utilise it but they can
  simply patch libcamera if they need to change e.g. some path.
  /etc/libcamera is needed, for system-specific defaults.

Do you agree or disagree?

>> +		std::filesystem::path("/etc/libcamera"),
>
> I am not sure if we want any hard-coded paths. I believe removing this won't affect
> the vast majority, but e.g. if one wants a local installation with a custom prefix,
> it might be surprising that libcamera loads configuration from outside.

https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050992.html:

  With the default /usr/local prefix, LIBCAMERA_SYSCONF_DIR is
  /usr/local/etc, which makes sense.  Imagine somebody installs libcamera
  from the sources to /usr/local, the idea is that /etc/libcamera should
  still be looked up and have a preference.  Good or bad?

OK, makes sense, if libcamera is installed both from a package manager
and locally from the sources, they should have separate configurations.

> Regards,
> Barnabás Pőcze
>
>
>> +	};
>> +
>> +	const char *libcameraConfigName =
>> +		utils::secure_getenv("LIBCAMERA_CONFIG_NAME");
>> +	if (!libcameraConfigName)
>> +		libcameraConfigName = "";
>> +	std::filesystem::path configName(libcameraConfigName);
>> +
>> +	if (configName.is_absolute()) {
>> +		loadFile(configName);
>> +		return !!yamlConfiguration_;
>> +	}
>> +
>> +	if (configName.empty())
>> +		configName = std::filesystem::path("configuration.yaml");
>> +
>>   	std::filesystem::path userConfigurationDirectory;
>>   	const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
>>   	if (xdgConfigHome) {
>> @@ -87,15 +99,14 @@ bool GlobalConfiguration::load()
>>     	if (!userConfigurationDirectory.empty()) {
>>   		std::filesystem::path user_configuration_file =
>> -			userConfigurationDirectory / "libcamera" / "configuration.yaml";
>> +			userConfigurationDirectory / "libcamera" / configName;
>>   		if (loadFile(user_configuration_file))
>>   			return !!yamlConfiguration_;
>>   	}
>>   -	for (const auto &path : globalConfigurationFiles) {
>> -		if (loadFile(path))
>> +	for (const auto &path : globalConfigurationDirectories)
>> +		if (loadFile(path / configName))
>>   			return !!yamlConfiguration_;
>> -	}
>>     	yamlConfiguration_ = std::make_unique<YamlObject>();
>>   	return true;
Barnabás Pőcze June 30, 2025, 8:27 a.m. UTC | #3
Hi

2025. 06. 27. 23:32 keltezéssel, Milan Zamazal írta:
> Hi Barnabás,
> 
> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:
> 
>> Hi
>>
>> 2025. 06. 24. 10:36 keltezéssel, Milan Zamazal írta:
>>> To support easy switching of configurations, let's introduce
>>> LIBCAMERA_CONFIG_NAME environment variable, which denotes:
>>> - The path of the configuration file to load if it is an absolute path; or
>>> - the path of the configuration file to load, relative to the configuration
>>>     directories.
>>> If such a configuration file doesn't exist, no custom configuration is
>>> loaded.
>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>> ---
>>>    Documentation/runtime_configuration.rst |  8 ++++++
>>>    src/libcamera/global_configuration.cpp  | 33 ++++++++++++++++---------
>>>    2 files changed, 30 insertions(+), 11 deletions(-)
>>> diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst
>>> index de74fa732..5648db7d7 100644
>>> --- a/Documentation/runtime_configuration.rst
>>> +++ b/Documentation/runtime_configuration.rst
>>> @@ -19,6 +19,14 @@ order:
>>>    - LIBCAMERA_SYSCONF_DIR/configuration.yaml
>>>    - /etc/libcamera/configuration.yaml
>>>    +The default name of the configuration file, configuration.yaml, can be
>>> +overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable
>>> +can specify just an alternative configuration file name to be looked up
>>> +in the locations above, or it can contain a whole relative or absolute
>>> +path. If an absolute path is specified then it is the only location that
>>> +is used; if the given file doesn't exist then no configuration file is
>>> +read.
>>> +
>>>    The first configuration file found wins, contingent configuration files
>>>    in other locations are ignored.
>>>    diff --git a/src/libcamera/global_configuration.cpp b/src/libcamera/global_configuration.cpp
>>> index f7c69890c..2c3b6cf97 100644
>>> --- a/src/libcamera/global_configuration.cpp
>>> +++ b/src/libcamera/global_configuration.cpp
>>> @@ -23,13 +23,6 @@
>>>      namespace libcamera {
>>>    -namespace {
>>> -const std::vector<std::filesystem::path> globalConfigurationFiles = {
>>> -	std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml",
>>> -	std::filesystem::path("/etc/libcamera/configuration.yaml"),
>>> -};
>>> -}
>>> -
>>>    LOG_DEFINE_CATEGORY(Configuration)
>>>      /**
>>> @@ -74,6 +67,25 @@ bool GlobalConfiguration::loadFile(const std::filesystem::path &fileName)
>>>      bool GlobalConfiguration::load()
>>>    {
>>> +	const std::vector<std::filesystem::path> globalConfigurationDirectories = {
>>> +		std::filesystem::path(LIBCAMERA_SYSCONF_DIR),
> 
> Let's avoid cycling discussions:
> 
>> I would probably add `LIBCAMERA_DATA_DIR` after the above, so
>> e.g. `/usr/share/libcamera/configuration.yaml`
>> could be the configuration that libcamera ships by default. Although I suppose
>> it might not be too useful until configuration file merging is implemented.
> 
> https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050991.html:
> 
>    At the moment, we don't need a default configuration in
>    /usr/share/libcamera, maybe distributions could utilise it but they can
>    simply patch libcamera if they need to change e.g. some path.
>    /etc/libcamera is needed, for system-specific defaults.
> 
> Do you agree or disagree?

Oops, sorry, I forgot about the earlier conversation. I agree with the above paragraph
except I don't necessarily believe that patching libcamera should be "the way" (or maybe
I misunderstand what you mean by that). I still think that in the future libcamera will
probably want to ship some kind of default configuration file, and I think that should go
to $LIBCAMERA_DATA_DIR. Since no such configuration file is introduced here, I think it's
fine to just omit LIBCAMERA_DATA_DIR for now; but I feel like it might be forgotten when
a default configuration file is added / configuration file merging is implemented. So if
there are no objections to the above "future plans", then my preference is adding it,
even if it is not really used at the moment.


> 
>>> +		std::filesystem::path("/etc/libcamera"),
>>
>> I am not sure if we want any hard-coded paths. I believe removing this won't affect
>> the vast majority, but e.g. if one wants a local installation with a custom prefix,
>> it might be surprising that libcamera loads configuration from outside.
> 
> https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050992.html:
> 
>    With the default /usr/local prefix, LIBCAMERA_SYSCONF_DIR is
>    /usr/local/etc, which makes sense.  Imagine somebody installs libcamera
>    from the sources to /usr/local, the idea is that /etc/libcamera should
>    still be looked up and have a preference.  Good or bad?
> 
> OK, makes sense, if libcamera is installed both from a package manager
> and locally from the sources, they should have separate configurations.

Especially if one is a development version for testing or similar, maybe they need
different options, etc. After thinking more, I believe both (having hard-coded
/etc/libcamera and not) can be reasonable choices. But in the end my preference
is not having hard-coded /etc/libcamera.


Regards,
Barnabás Pőcze

> 
>> Regards,
>> Barnabás Pőcze
>>
>>
>>> +	};
>>> +
>>> +	const char *libcameraConfigName =
>>> +		utils::secure_getenv("LIBCAMERA_CONFIG_NAME");
>>> +	if (!libcameraConfigName)
>>> +		libcameraConfigName = "";
>>> +	std::filesystem::path configName(libcameraConfigName);
>>> +
>>> +	if (configName.is_absolute()) {
>>> +		loadFile(configName);
>>> +		return !!yamlConfiguration_;
>>> +	}
>>> +
>>> +	if (configName.empty())
>>> +		configName = std::filesystem::path("configuration.yaml");
>>> +
>>>    	std::filesystem::path userConfigurationDirectory;
>>>    	const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
>>>    	if (xdgConfigHome) {
>>> @@ -87,15 +99,14 @@ bool GlobalConfiguration::load()
>>>      	if (!userConfigurationDirectory.empty()) {
>>>    		std::filesystem::path user_configuration_file =
>>> -			userConfigurationDirectory / "libcamera" / "configuration.yaml";
>>> +			userConfigurationDirectory / "libcamera" / configName;
>>>    		if (loadFile(user_configuration_file))
>>>    			return !!yamlConfiguration_;
>>>    	}
>>>    -	for (const auto &path : globalConfigurationFiles) {
>>> -		if (loadFile(path))
>>> +	for (const auto &path : globalConfigurationDirectories)
>>> +		if (loadFile(path / configName))
>>>    			return !!yamlConfiguration_;
>>> -	}
>>>      	yamlConfiguration_ = std::make_unique<YamlObject>();
>>>    	return true;
>
Milan Zamazal June 30, 2025, 9:48 a.m. UTC | #4
Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:

> Hi
>
> 2025. 06. 27. 23:32 keltezéssel, Milan Zamazal írta:
>> Hi Barnabás,
>> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:
>> 
>>> Hi
>>>
>>> 2025. 06. 24. 10:36 keltezéssel, Milan Zamazal írta:
>>>> To support easy switching of configurations, let's introduce
>>>> LIBCAMERA_CONFIG_NAME environment variable, which denotes:
>>>> - The path of the configuration file to load if it is an absolute path; or
>>>> - the path of the configuration file to load, relative to the configuration
>>>>     directories.
>>>> If such a configuration file doesn't exist, no custom configuration is
>>>> loaded.
>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>> ---
>>>>    Documentation/runtime_configuration.rst |  8 ++++++
>>>>    src/libcamera/global_configuration.cpp  | 33 ++++++++++++++++---------
>>>>    2 files changed, 30 insertions(+), 11 deletions(-)
>>>> diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst
>>>> index de74fa732..5648db7d7 100644
>>>> --- a/Documentation/runtime_configuration.rst
>>>> +++ b/Documentation/runtime_configuration.rst
>>>> @@ -19,6 +19,14 @@ order:
>>>>    - LIBCAMERA_SYSCONF_DIR/configuration.yaml
>>>>    - /etc/libcamera/configuration.yaml
>>>>    +The default name of the configuration file, configuration.yaml, can be
>>>> +overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable
>>>> +can specify just an alternative configuration file name to be looked up
>>>> +in the locations above, or it can contain a whole relative or absolute
>>>> +path. If an absolute path is specified then it is the only location that
>>>> +is used; if the given file doesn't exist then no configuration file is
>>>> +read.
>>>> +
>>>>    The first configuration file found wins, contingent configuration files
>>>>    in other locations are ignored.
>>>>    diff --git a/src/libcamera/global_configuration.cpp b/src/libcamera/global_configuration.cpp
>>>> index f7c69890c..2c3b6cf97 100644
>>>> --- a/src/libcamera/global_configuration.cpp
>>>> +++ b/src/libcamera/global_configuration.cpp
>>>> @@ -23,13 +23,6 @@
>>>>      namespace libcamera {
>>>>    -namespace {
>>>> -const std::vector<std::filesystem::path> globalConfigurationFiles = {
>>>> -	std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml",
>>>> -	std::filesystem::path("/etc/libcamera/configuration.yaml"),
>>>> -};
>>>> -}
>>>> -
>>>>    LOG_DEFINE_CATEGORY(Configuration)
>>>>      /**
>>>> @@ -74,6 +67,25 @@ bool GlobalConfiguration::loadFile(const std::filesystem::path &fileName)
>>>>      bool GlobalConfiguration::load()
>>>>    {
>>>> +	const std::vector<std::filesystem::path> globalConfigurationDirectories = {
>>>> +		std::filesystem::path(LIBCAMERA_SYSCONF_DIR),
>> Let's avoid cycling discussions:
>> 
>>> I would probably add `LIBCAMERA_DATA_DIR` after the above, so
>>> e.g. `/usr/share/libcamera/configuration.yaml`
>>> could be the configuration that libcamera ships by default. Although I suppose
>>> it might not be too useful until configuration file merging is implemented.
>> https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050991.html:
>>    At the moment, we don't need a default configuration in
>>    /usr/share/libcamera, maybe distributions could utilise it but they can
>>    simply patch libcamera if they need to change e.g. some path.
>>    /etc/libcamera is needed, for system-specific defaults.
>> Do you agree or disagree?
>
> Oops, sorry, I forgot about the earlier conversation. I agree with the above paragraph
> except I don't necessarily believe that patching libcamera should be "the way" (or maybe
> I misunderstand what you mean by that). 

I primarily meant when a distribution uses non-standard paths generally
(think about e.g. NixOS) or perhaps in this specific case.

> I still think that in the future libcamera will probably want to ship
> some kind of default configuration file, and I think that should go to
> $LIBCAMERA_DATA_DIR. Since no such configuration file is introduced
> here, I think it's fine to just omit LIBCAMERA_DATA_DIR for now; but I
> feel like it might be forgotten when a default configuration file is
> added / configuration file merging is implemented. So if there are no
> objections to the above "future plans", then my preference is adding
> it, even if it is not really used at the moment.

There have been no objections so far (and I don't really object either)
so I can change it this way.

>>>> +		std::filesystem::path("/etc/libcamera"),
>>>
>>> I am not sure if we want any hard-coded paths. I believe removing this won't affect
>>> the vast majority, but e.g. if one wants a local installation with a custom prefix,
>>> it might be surprising that libcamera loads configuration from outside.
>> https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050992.html:
>>    With the default /usr/local prefix, LIBCAMERA_SYSCONF_DIR is
>>    /usr/local/etc, which makes sense.  Imagine somebody installs libcamera
>>    from the sources to /usr/local, the idea is that /etc/libcamera should
>>    still be looked up and have a preference.  Good or bad?
>> OK, makes sense, if libcamera is installed both from a package manager
>> and locally from the sources, they should have separate configurations.
>
> Especially if one is a development version for testing or similar, maybe they need
> different options, etc. After thinking more, I believe both (having hard-coded
> /etc/libcamera and not) can be reasonable choices. But in the end my preference
> is not having hard-coded /etc/libcamera.

I can remove it.  It's easy to add later if needed.

> Regards,
> Barnabás Pőcze
>
>> 
>>> Regards,
>>> Barnabás Pőcze
>>>
>>>
>>>> +	};
>>>> +
>>>> +	const char *libcameraConfigName =
>>>> +		utils::secure_getenv("LIBCAMERA_CONFIG_NAME");
>>>> +	if (!libcameraConfigName)
>>>> +		libcameraConfigName = "";
>>>> +	std::filesystem::path configName(libcameraConfigName);
>>>> +
>>>> +	if (configName.is_absolute()) {
>>>> +		loadFile(configName);
>>>> +		return !!yamlConfiguration_;
>>>> +	}
>>>> +
>>>> +	if (configName.empty())
>>>> +		configName = std::filesystem::path("configuration.yaml");
>>>> +
>>>>    	std::filesystem::path userConfigurationDirectory;
>>>>    	const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
>>>>    	if (xdgConfigHome) {
>>>> @@ -87,15 +99,14 @@ bool GlobalConfiguration::load()
>>>>      	if (!userConfigurationDirectory.empty()) {
>>>>    		std::filesystem::path user_configuration_file =
>>>> -			userConfigurationDirectory / "libcamera" / "configuration.yaml";
>>>> +			userConfigurationDirectory / "libcamera" / configName;
>>>>    		if (loadFile(user_configuration_file))
>>>>    			return !!yamlConfiguration_;
>>>>    	}
>>>>    -	for (const auto &path : globalConfigurationFiles) {
>>>> -		if (loadFile(path))
>>>> +	for (const auto &path : globalConfigurationDirectories)
>>>> +		if (loadFile(path / configName))
>>>>    			return !!yamlConfiguration_;
>>>> -	}
>>>>      	yamlConfiguration_ = std::make_unique<YamlObject>();
>>>>    	return true;
>>

Patch
diff mbox series

diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst
index de74fa732..5648db7d7 100644
--- a/Documentation/runtime_configuration.rst
+++ b/Documentation/runtime_configuration.rst
@@ -19,6 +19,14 @@  order:
 - LIBCAMERA_SYSCONF_DIR/configuration.yaml
 - /etc/libcamera/configuration.yaml
 
+The default name of the configuration file, configuration.yaml, can be
+overridden in LIBCAMERA_CONFIG_NAME environment variable. The variable
+can specify just an alternative configuration file name to be looked up
+in the locations above, or it can contain a whole relative or absolute
+path. If an absolute path is specified then it is the only location that
+is used; if the given file doesn't exist then no configuration file is
+read.
+
 The first configuration file found wins, contingent configuration files
 in other locations are ignored.
 
diff --git a/src/libcamera/global_configuration.cpp b/src/libcamera/global_configuration.cpp
index f7c69890c..2c3b6cf97 100644
--- a/src/libcamera/global_configuration.cpp
+++ b/src/libcamera/global_configuration.cpp
@@ -23,13 +23,6 @@ 
 
 namespace libcamera {
 
-namespace {
-const std::vector<std::filesystem::path> globalConfigurationFiles = {
-	std::filesystem::path(LIBCAMERA_SYSCONF_DIR) / "configuration.yaml",
-	std::filesystem::path("/etc/libcamera/configuration.yaml"),
-};
-}
-
 LOG_DEFINE_CATEGORY(Configuration)
 
 /**
@@ -74,6 +67,25 @@  bool GlobalConfiguration::loadFile(const std::filesystem::path &fileName)
 
 bool GlobalConfiguration::load()
 {
+	const std::vector<std::filesystem::path> globalConfigurationDirectories = {
+		std::filesystem::path(LIBCAMERA_SYSCONF_DIR),
+		std::filesystem::path("/etc/libcamera"),
+	};
+
+	const char *libcameraConfigName =
+		utils::secure_getenv("LIBCAMERA_CONFIG_NAME");
+	if (!libcameraConfigName)
+		libcameraConfigName = "";
+	std::filesystem::path configName(libcameraConfigName);
+
+	if (configName.is_absolute()) {
+		loadFile(configName);
+		return !!yamlConfiguration_;
+	}
+
+	if (configName.empty())
+		configName = std::filesystem::path("configuration.yaml");
+
 	std::filesystem::path userConfigurationDirectory;
 	const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
 	if (xdgConfigHome) {
@@ -87,15 +99,14 @@  bool GlobalConfiguration::load()
 
 	if (!userConfigurationDirectory.empty()) {
 		std::filesystem::path user_configuration_file =
-			userConfigurationDirectory / "libcamera" / "configuration.yaml";
+			userConfigurationDirectory / "libcamera" / configName;
 		if (loadFile(user_configuration_file))
 			return !!yamlConfiguration_;
 	}
 
-	for (const auto &path : globalConfigurationFiles) {
-		if (loadFile(path))
+	for (const auto &path : globalConfigurationDirectories)
+		if (loadFile(path / configName))
 			return !!yamlConfiguration_;
-	}
 
 	yamlConfiguration_ = std::make_unique<YamlObject>();
 	return true;