New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix value of nginx-proxy tmpfs size #151
Fix value of nginx-proxy tmpfs size #151
Conversation
Use an int conversion in the computation of the value of matrix_nginx_proxy_tmp_directory_size_mb, to have the integer value multiplied by 50 instead of having the string repeated 50 times.
I wonder.. In what situation would a string value end up in Someone explicitly messing up the data type like this: I guess that would be pretty rare, but.. it doesn't hurt to have such defensive casting just in case. We currently have a chain like this:
If someone incorrectly sets Perhaps we need a cast there ( |
With the current master and the default settings,
I also wonder why this happens. It’s not clear to me when a value is considered as an integer or as a string.
But this is not the problem, as this value is correctly multiplied by 3 in
Strange, isn’t it? I’m probably missing something here… |
Helps with #151 (Github Pull Request), but only for Ansible >= 2.7 and when Jinja >= 2.10 is in use. For other version combinations we still need the workaround proposed in the pull rqeuest.
It looks like all variables have their type determined at YAML parsing time. An integer literal is considered an integer. Example: # matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb = 25
matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 25 A variable defined in terms of another one using a jinja2 template ends up being considered a string. Example: # matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb = "75"
matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb: "{{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb * 3 }}" Note how the computation happens between The resulting value, however, is put in a string, because And finally, where our problem lies, is when the such an "is it a integer or a string?" variable is used for a numeric computation: # Due to matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb being a string ("75"),
# this becomes a computation between a string and a number (that is, string repetition).
matrix_nginx_proxy_tmp_directory_size_mb: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb * 50 }}" This issue is described in ansible/ansible#15249 and fixed in ansible/ansible#32738 There's this Jinja2 thing called Native Python Types, which when enabled will produce the proper types for variables coming from templates. To enable it in Ansible (>= 2.7 required; Jinja 2.10 also required), one needs to either use Documentation for this setting is here. This fixes the issue for me (Ansible 2.7.10), but won't fix the issue for people on older versions. I'm also hoping that people having Ansible 2.7+ also have a recent version of Jinja2 (>= 2.10). Thank you! 👍 |
This reverts commit 3387035. Enabling `jinja2_native` does help with the issue it is trying to address - #151 (Github Pull Request), but it introduces a regression when generating templates. An example is `roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2`, which yields a strange resulting value of: ``` location /.well-known/acme-challenge { resolver 127.0.0.11 valid=5s; set $backend "matrix-certbot:8080"; proxy_pass http://$backend; resolver 127.0.0.11 valid=5s; set $backend "matrix-certbot:8080"; proxy_pass http://$backend; } ``` For whatever reason (still to be investigated), the `if` block's contents seem to have been outputted twice. Reverting until this is resolved. Until then, #151 would rely on the workaround and not on `jinja2_native`.
I've reverted the For the time being, we rely on your workaround only. |
Wow, thanks for the detailed explanation! I digged a little more into this, and it seems that the problem comes from the fact that Ansible is doing some type guessing when it can easily (as explained in ansible/ansible#9362 (comment)), but this breaks as soon as an extra reference level is added, or if an operation is done on the value. Here is a test case:
- hosts: all
gather_facts: False
vars_files:
- test_vars.yaml
tasks:
- debug:
var: test_var_1
- debug:
var: test_var_2
- debug:
var: test_var_3
- debug:
var: test_var_4
- debug:
var: test_var_5
- debug:
var: test_var_6
- debug:
var: test_var_7
- debug:
var: test_var_8
test_var_1: 42
test_var_2: "{{ test_var_1 }}"
test_var_3: "{{ test_var_1 * 1 }}"
test_var_4: "{{ test_var_2 }}"
test_var_5: "{{ test_var_1 * 2 }}"
test_var_6: "{{ test_var_2 * 2 }}"
test_var_7: "{{ test_var_3 * 2 }}"
test_var_8: "{{ test_var_4 * 2 }}" Run with:
Output:
Notice how |
I’m not sure whether my last explanation is clear enough. I was wondering why the first multiply works correctly: matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb: "{{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb * 3 }}" even though matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: "{{ matrix_synapse_max_upload_size_mb }}" which looks like it would make the variable a string. It is similar to |
As discussed in #151 (Github Pull Request), it's a good idea to not selectively apply casting, but to do it in all cases involving arithmetic operations.
I agree! This casting thing is a huge gotcha that doesn't even seem mentioned on the Ansible documentation (based on what I was able to find, at least). Nasty indeed.. Because Ansible isn't our friend and people may even define variables incorrectly (e.g. |
Good! I think this is indeed good practice to shield ourselves against unexpected (and hard to detect) edge cases. Thanks! I opened an issue in Ansible: ansible/ansible#55891 but it was closed directly, so there is apparently no plan to change this default behavior. |
Thanks for opening an issue there! It's unfortunate that they won't pursue a better (on-by-default) solution. I'd still like to investigate enabling |
Use an int conversion in the computation of the value of
matrix_nginx_proxy_tmp_directory_size_mb
, to have the integer valuemultiplied by 50 instead of having the string repeated 50 times.