hydra - structured config group/package override via yaml - fb-hydra

I'm not very successfully trying to figure out how to achieve an override of a group/package with and via a yaml file. Trying to explain my problem using the example (files and folder structre) from the hydra documentation https://hydra.cc/docs/tutorials/structured_config/schema/.
yaml.config as:
defaults:
- base_config # --> reference to dataclass
- db: base_mysql # --> reference to dataclass
- _self_ debug: true
gives the expected (print when running the myapp.py):
db:
driver: mysql
host: localhost
port: 3306
user: ???
password: ???
Using the yaml file instead instead of the base_mysql dataclass is also fine thus the yaml.config as:
defaults:
- base_config
- db: mysql # --> reads db/mysql.yaml
- _self_
debug: true
prints again as expected
db:
driver: mysql
host: localhost
port: 3306
user: omry
password: secret
Overriding individual fields is as well fine, e.g. with config.yaml like
defaults:
- base_config
- db: mysql
- _self_
debug: true
db:
password: UpdatedPassword
What I'm to able to figure out is how to override the full db group with a/via another yaml file - defining the structure via a dataclass and then override/set the values like:
defaults:
- base_config
- db: base_mysql # --> reference to dataclass to define the structure
- _self_
debug: true
db: mysql # --> mysql.yaml
throws the following error:
In 'config': Validation error while composing config:
Merge error: str is not a subclass of MySQLConfig. value: mysql
full_key:
object_type=Config
Searching the internet/stackoverflow already showed me that moving the self to the first position will get rid of the error - but then the composition order is "wrong".
Keeping the order as it is and using the mysql.yaml for an override works well - when done via commandline (python myapp.py db=mysql when the line "db:mysql" is not present), but for my usecase it much more convinient to handle it all via the yaml file(s).
Somehow I assume that the same functionality is available via CLI and files/code and that I just did not mange to figure out how it works.
(hydra version 1.1 in a conda environment with python 3.9)
Thank you very much in advance for any help that you can provide.

If understand correctly, you want to use the defaults list in your primary yaml file to merge together the base_mysql config with the mysql config. This will do the trick:
defaults:
- base_config
- db: [base_mysql, mysql]
- _self_
debug: true
Passing a list [base_mysql, mysql] of config names causes those configs base_mysql and mysql to be merged together. This is documented here -- see the "CONFIG_NAMES" alternative for specifying an option in the defaults list.
Note that passing the CLI override db=mysql (as in python myapp.py db=mysql) results in modification of the defaults list; the resulting defaults list will be the same as if you had used the following in your yaml file:
defaults:
- base_config
- db: mysql
- _self_
debug: true
You can pass a list [base_mysql, mysql] of config names at the CLI like this:
python my_app.py 'db=[base_mysql, mysql]'

Related

Cloudbuild template and env file

I'm on Symfony but It's not very important. I have a .env file and I would like to use his variables in cloudbuild.yaml. There is no way to avoid duplication 😭 ?
Moreover, I read this article and I saw that author use Yaml merge feature with gitlab hidden key, its very useful when the file is big. I try to use this but cloud build not like, it seems to be impossible to use custom key like in gitlab-ci.yaml. Any Idea ?
UPDATE
In build we need to have env variables and generic config file to avoid to change a lot of value manually. So I would like to use hidden keys in cloudbuild.yaml because I need to use Yaml merge feature for avoid code duplication.
This is my cloudbuild.yaml example without optimisation :
steps:
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', 'gcr.io/$PROJECT_ID/image-pgsql', '-f', 'docker/postgresql/Dockerfile', '.']
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', 'gcr.io/$PROJECT_ID/image-nginx', '--build-arg', 'VERSION=1.15.3', '-f', 'docker/nginx/Dockerfile', '.']
But I would like to have this, or something like that :
.build-template: &buildTemplate
args: ['build', '-t', 'gcr.io/$PROJECT_ID/${IMAGE_NAME}', '--build-arg', 'VERSION=${VERSION}', '-f', '${DOCKER_PATH}', '.']
steps:
- name: 'gcr.io/cloud-builders/docker'
<<: *buildTemplate
env: ['IMAGE_NAME=pgsql', 'VERSION=12', 'DOCKER_PATH=docker/postgresql/Dockerfile']
- name: 'gcr.io/cloud-builders/docker'
<<: *buildTemplate
env: ['IMAGE_NAME=nginx', 'VERSION=1.15.3', 'DOCKER_PATH=docker/nginx/Dockerfile']
I get this when I try to run cloud-build-local --dryrun=false . =>
Error loading config file: unknown field ".build-template" in cloudbuild.Build
Unfortunately, Google Cloud Build doesn't have this feature of hidden keys in Cloud build. I have create a Feature Request in Public Issue Tracker on your behalf where you can track all the updates related to the feature request of hidden keys in Cloud Build.
You have to follow the cloudbuild.yaml schema, which is documented here. Since a build would be directly triggered from that yaml file, it is not possible to add other fields and do some sort of pre-processing to merge different files together.
The only options that are on the table as we speak:
Use global environment variables:
options:
env: [string, string, ...]
steps: [...]
Use step-specific environment variables:
steps:
- name: string
env: [string, string, ...]
Use substitution (with allow-loose):
substitutions:
_SUB_VALUE: world
options:
substitution_option: 'ALLOW_LOOSE'
steps:
- name: 'ubuntu'
args: ['echo', 'hello ${_SUB_VALUE}']
Source your [environment].env file in a build step:
steps:
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
source ${BRANCH_NAME}.env
echo $${_MY_VARIABLE_1}
echo $${_MY_VARIABLE_2}
...

OS::Heat::SoftwareDeployment is staying stuck in CREATE_IN_PROGRESS status

I am trying customise new instances created within openstack mikata, using HEAT templates. Using OS::Nova::Server with a script in user_data works fine.
Next the idea is to do additional steps via OS::Heat::SoftwareConfig.
The config is:
type: OS::Nova::Server
....
user_data_format: SOFTWARE_CONFIG
user_data:
str_replace:
template:
get_file: vm_init1.sh
config1:
type: OS::Heat::SoftwareConfig
depends_on: vm
properties:
group: script
config: |
#!/bin/bash
echo "Running $0 OS::Heat::SoftwareConfig look in /var/tmp/test_script.log" | tee /var/tmp/test_script.log
deploy:
type: OS::Heat::SoftwareDeployment
properties:
config:
get_resource: config1
server:
get_resource: vm
The instance is setup nicely (the script vm_init1.sh above runs fine) and one can login, but he "config1" example above is never executed.
Analysis
- The base image is Ubuntu 16.04, created with disk-image-create and including "vm ubuntu os-collect-config os-refresh-config os-apply-config heat-config heat-config-script"
- From "openstack stack resource list $vm" one see that deployment never fisnihe, with OS::Heat::SoftwareDeployment status=CREATE_IN_PROGRESS
- "openstack stack resource show $vm config1" shows resource_status=CREATE_COMPLETE
- Within the vm, /var/log/cloud-init-output.log shows the output of the script vm_init1.sh, but no trace of the 'config1' script. The log os-apply-config.log is empty, is that normal?
How does one troubleshoot OS::Heat::SoftwareDeployment configs?
(I have read https://docs.openstack.org/developer/heat/template_guide/software_deployment.html#software-deployment-resources)

How do I implement a 'pillar.example' from a SaltStack Formula?

If this explanation exists somewhere, I've spent 3 months trying to find it, and failed. I come from a Puppet background, however for various reasons I really want to try replacing it with Salt.
I've gotten a basic setup and I can code my own states and see them work without any issues. The documentation on this is pretty clear. Where I'm stuck is attempting to implement a community salt formula. I can include the formula with it's basic setup and they work fine, however I cannot figure out how to override the defaults from my pillar data. This seems to be where the Salt documentation is weakest.
The documentation states that you should check the pillar.example for how to configure the formula. The pillar.example gives the configuration part clearly, however nether the documentation or the pillar.example tell you how to include this into your pillar data.
In my case I'm trying to use the snmp-formula. I've got a basic setup for my salt file structure, which you can see from my file roots:
file_roots:
base:
- /srv/salt/base
- /srv/formulas/snmp-formula
Inside base I have two pillars:
base/
top.sls
common.sls
top.sls is very simple:
base:
'*':
- common
common.sls has all common config:
include:
- snmp
- snmp.conf
- snmp.trap
- snmp.conftrap
tcpdump:
pkg.latest:
- name: tcpdump
telnet:
pkg.latest:
- name: telnet
htop:
pkg.latest:
- name: htop
snmp:
conf:
location: 'Office'
syscontact: 'Example.com Admin <admin#example.com>'
logconnects: false
# vacm com2sec's (map communities into security names)
com2sec:
- name: mynetwork
source: 192.168.0.13/31
community: public
# vacm group's (map security names to group names)
groups:
- name: MyROGroup
version: v1
secname: mynetwork
- name: MyROGroup
version: v1c
secname: mynetwork
# vacm views (map mib trees to views)
views:
- name: all
type: included
oid: '.1'
# vacm access (map groups to views with access restrictions)
access:
- name: MyROGroup
context: '""'
match: any
level: noauth
prefix: exact
read: all
write: none
notify: none
# v3 users for read-write
rwusers:
- username: 'nagios'
passphrase: 'myv3password'
view: all
In common.sls I've included the snmp-formula and then followed the pillar.example from the formula to customize the configuration. However when I run a test with this I get the following error:
Data failed to compile:
----------
Detected conflicting IDs, SLS IDs need to be globally unique.
The conflicting ID is 'snmp' and is found in SLS 'base:common' and SLS 'base:snmp'
I'm not sure how to proceed with this. It seems like I would have to actually modify the community formula directly to achieve what I want, which seems like the wrong idea. I want to be able to keep the community formula up to date with it's repository and coming from the Puppet perspective, I should be overriding a modules defaults as I need, not modifying the modules directly.
Can someone please make the missing connection for me? How do I implement the pillar.example?
The Salt formula in question is here:
https://github.com/saltstack-formulas/snmp-formula
I have finally figured this out, and it was a problem with a fundamental misunderstanding of the differences between 'file_roots' and 'pillar_roots' as well as 'pillars' vs 'states'. I don't feel that the documentation is very clear in the Getting Started guide about these so I'll explain it, but first the answer.
ANSWER:
To implement the above pillar.example, simply create a dedicated snmp.sls file in your 'base' environment in your pillar data:
/srv/pillar/snmp.sls:
snmp:
conf:
location: 'Office'
syscontact: 'Example.com Admin <admin#example.com>'
logconnects: false
# vacm com2sec's (map communities into security names)
com2sec:
- name: mynetwork
source: 192.168.0.13/31
community: public
# vacm group's (map security names to group names)
groups:
- name: MyROGroup
version: v1
secname: mynetwork
- name: MyROGroup
version: v1c
secname: mynetwork
# vacm views (map mib trees to views)
views:
- name: all
type: included
oid: '.1'
mask: 80
# vacm access (map groups to views with access restrictions)
access:
- name: MyROGroup
context: '""'
match: any
level: noauth
prefix: exact
read: all
write: none
notify: none
# v3 users for read-write
rwusers:
- username: 'nagios'
passphrase: 'myv3password'
view: all
Your pillar_root must also include a top.sls (not to be confused with the top.sls in your file_roots for your states) like this:
/srv/pillar/top.sls
base:
'*':
- snmp
IMPORTANT: This directory and this top.sls for pillar data cannot exist or be included by your file_roots! This is where I was going wrong. For a complete picture, this is the the config I now have:
/etc/salt/master: (snippet)
file_roots:
base:
- /srv/salt/base
- /srv/formulas/snmp-formula
pillar_roots:
base:
- /srv/pillar
Inside /srv/salt/base I have a top.sls which includes a common.sls
for the 'base' environment. This is where the snmp-formula and it's states are included.
/srv/salt/base/top.sls:
base/
top.sls
common.sls
/srv/salt/base/common.sls:
include:
- snmp
- snmp.conf
- snmp.trap
- snmp.conftrap
tcpdump:
pkg.latest:
- name: tcpdump
telnet:
pkg.latest:
- name: telnet
htop:
pkg.latest:
- name: htop
Now the snmp parameter in the pillar data does not conflict with ID of the snmp state from the formula included by the state data.

Symfony2 test parameters

Is there a way to configure test parameters with Symfony2?
I tried importing parameters_test.yml from the config_test.yml file but the variables still come from the parameters.yml file which is imported by config.yml which is imported by config_dev.yml which is imported by config_test.yml.
Basically I want to setup different variables in a test parameter file so I can access the values and also use them in the config files. If I hardcode the variables directly into config_test.yml I don't have access to them.
The variable I'm interested in particular is database_name or doctrine->dbal->dbname.
Thanks
Of course ensure your two first lines your config_test.yml are:
imports:
- { resource: config_dev.yml }
- { resource: parameters_test.yml }
In config_test.yml simple write this configuration:
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver_test%
host: %database_host_test%
port: %database_port_test%
dbname: %database_name_test%
user: %database_user_test%
password: %database_password_test%

Symfony2 configure DB storage sessions

UPDATE: problem solved, see the comments (many issues, the versions differences was but one of them).
I'm trying to configure sessions in Symfony2 in config.yml file. I have the following configuration:
session:
default_locale: %locale%
lifetime: 7200
auto_start: true
storage_id: session.storage.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
pdo:
class: PDO
arguments:
- "mysql:dbname=%database_name%"
- %database_user%
- %database_password%
session.storage.pdo:
class: Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
It's based on Symfony2's cookbook http://symfony.com/doc/2.0/cookbook/configuration/pdo_session_storage.html
I've created exactly the same table as in the given link.
However, it doesn't work. I get some "blank" error (no error message, but "PDO Exception" and "Error Exception"). I admit I have no much knowledge on configuring the Symfony2 or any info (that's why I'm using cookbook). I lost a lot of time and see no much documentation about it in the internet, not mentioning the fact that internet is quite silent about this case (having session storaged to DB table in Symfony2).
My NetBeans is "shouting" sth about the last line:
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
"ScannerException while scanning for the next token we had this found character #(64) that cannot start any token".
UPDATE:
Hmm now I'm not sure if it's about the configuration. I can see that Symfony2's cookbook (use... ) example doesn't match actually the file structure in the Symfony2's bundle. In a word, there is no such file-path, but after putting the real one it still doesn't work.
I had the same problem as you with Symfony 2.5. Turns out my solution was to disable session.auto_start in php.ini. The PdoSessionStorage will not take over if the session is being started before PDO has the opportunity to take control of it. I had overlooked this at first because I was modifying the wrong one (I had two copies of php.ini). To check if this is the problem on yours, run this command:
echo ini_get('session.auto_start');
If that returns a '1' or a 'true', then be sure to set this in your php.ini:
session.auto_start = 0
So for reference, here is my setup with Symfony 2.5 to make this work:
config.yml
framework:
session:
handler_id: session.handler.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["#pdo", "%pdo.db_options%"]
pdo:
class: PDO
arguments:
dsn: "mysql:host=%database_host%;port=%database_port%;dbname=%database_name%"
user: "%database_user%"
password: "%database_password%"
calls:
- [setAttribute, [3, 2]] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION

Resources