I am using CentOS -7 and it has latest Salt installed(salt 2017.7.2 (Nitrogen). I want to execute a certain script in all the salt-minions connected from salt-master and provide me the exit status from the salt-minions so that I can determine the salt states would be declared pass or fail.
Below are the contents of init.sls contents. Can anyone help me in this regard please? If you provide me some example code that would really help.
Regards
Pradeep
Note: There i tried to post code but stackoverflow is giving errors for improper indentation.
First attempt
https://docs.saltstack.com/en/latest/ref/states/all/salt.states.cmd.html#salt.states.cmd.script
Then I tried jinja way after googling around a bit:
Second Attempt
https://groups.google.com/forum/#!topic/salt-users/IJo6Z8Hro2w
Rendering SLS 'base:abcd' failed: Problem running salt function in Jinja template: Unable to run command '['/root/scripts/test.sh']' with the context '{'timeout': None, 'with_communicate': True, 'shell': False, 'bg': False, 'stderr': -2, 'env': {'LANG': 'en_US.UTF-8', 'LC_NUMERIC': 'C', 'NOTIFY_SOCKET': '/run/systemd/notify', 'LC_MESSAGES': 'C', 'LC_IDENTIFICATION': 'C', 'LC_MONETARY': 'C', 'LC_COLLATE': 'C', 'LC_CTYPE': 'C', 'LC_ADDRESS': 'C', 'LC_MEASUREMENT': 'C', 'LC_TELEPHONE': 'C', 'LC_PAPER': 'C', 'LC_NAME': 'C', 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:/sbin', 'LC_TIME': 'C'}, 'stdout': -1, 'close_fds': True, 'stdin': None, 'cwd': '/root'}', reason: command not found; line 1
Here is how I run scripts on my SaltStack install:
run_my_script.sh:
cmd.script:
- name: my_script.sh
- source: salt://scripts/my_script.sh
You can then just check the exit status of the state.
Related
I have the next visualization of the error:
File "/home/tinmar/.local/lib/python3.10/site-packages/jsonschema/validators.py", line 353, in validate
raise error
jsonschema.exceptions.ValidationError: Additional properties are not allowed ('**logo**' was unexpected)
Failed validating 'additionalProperties' in schema['properties']['integrations']['items']:
{'additionalProperties': False,
'properties': {'external-doc-url': {'description': 'URL to external '
'documentation for '
'the integration.',
'type': 'string'},
'how-to-guide': {'description': 'List of paths to '
'how-to-guide for the '
'integration. The path '
'must start with '
"'/docs/'",
'items': {'type': 'string'},
'type': 'array'},
'integration-name': {'description': 'Name of the '
'integration.',
'type': 'string'},
'tags': {'description': 'List of tags describing the '
"integration. While we're "
'using RST, only one tag is '
'supported per integration.',
'items': {'enum': ['apache',
'aws',
'azure',
'gcp',
'gmp',
'google',
'protocol',
'service',
'software',
'yandex'],
'type': 'string'},
'maxItems': 1,
'minItems': 1,
'type': 'array'}},
'required': ['integration-name', 'external-doc-url', 'tags'],
'type': 'object'}
On instance['integrations'][0]:
{'external-doc-url': 'https://www.sqlite.org/index.html',
'how-to-guide': ['/docs/apache-airflow-providers-sqlite/operators.rst'],
'integration-name': 'SQLite',
**'logo': '/integration-logos/sql**,
'tags': ['software']}
I really don't know what the hell is happen here, I tried almost every solution I can find in the internet but nothing was usefull...
By the way, before this error, I have other one:
'''
ModuleNotFoundError: No module named 'wtforms.compat'
'''
Error that was solved by this code
pip install wtforms==2.3.3
pip install marsmallow==3.0.0
I think that maybe the first error was the cause of all, but I'm not sure about it and I don't know how can be possible
This errors came when I try to uninstall airflow 2.5.0 in order to downgrade to airflow 2.0.0. I mean, this was the cause of the other two errors, I think so...
I also try to uninstall and reinstall WSL2, this threw me some errors but I solve it, I don't think this was the problem because before I trying this, the other errors already pop out.
I expect a local airflow env in Ubuntu with WSL2
I will appreciate if someone have any idea on how to solve it, thank you before it :)
I'm following the first example (copy/paste) of custom config file (lint-staged.config.js) for lint-staged packaged from its github README without success. I get error Command failed with exit code 1. always.
I tried this...
I have tried three things, for each case I had my lint-staged.config.js in the root directory.
package.json: result is error Command failed with exit code 1.
"lint-staged": {
"packages/**/*.{ts,tsx}": [
"yarn lint-staged --config ./lint-staged.config.js"
]
},
husky/pre-commit: result is error Command failed with exit code 1.
npx lint-staged --config ../lint-staged.config.js
cmd line: result is error Command failed with exit code 1.
yarn lint-staged --config lint-staged.config.js
The problem
Im just looking for run a custom config file.
The problem is that the execution fails, the error message its related to the command but the command itself its correct as lint-staged [options] (yarn/npx lint-staged -h) then to provide a custom config file it would as lint-staged [--config [path]] but it fails (I even provide all kind of quotes for path).
The issue is that when the module doesn't provide an explicit positive answer to the validation it will always return error Command failed with exit code 1 meaning that the validation has fail.
To properly work as expected it should, in my case:
first, the module had to have a return.
Secondly it should be in form of string array.
Third, the first string of the array had to be terminal-like response as '0' or 'true' of 'false'.
Then, the next following strings could be a message or messages like 'error some A' and 'error some B' and 'error some C' and so on...
For example: ['0', 'error some A', 'error some B', 'error some C']
const path = require("path");
module.exports = (absolutePaths) => {
const cwd = process.cwd();
const relativePaths = absolutePaths.map((file) => path.relative(cwd, file));
console.log("query", relativePaths)
return ['0', 'error some A', 'error some B', 'error some C']
};
This runs ok, but as Andrey Mikhaylov said in this post to run something like
"lint-staged": {
"packages/**/*.{ts,tsx}": [
"yarn lint-staged --config ./lint-staged.config.js"
]
},
If the lint returns an error, It will blow away the staged files causing a regression that will drop the commit completely, which means that all the work will be lost.
I fix this not intended/desired behaviour running the same command yarn lint-staged --config ./lint-staged.config.js but from husky at the pre-commit file as
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged --config ./lint-staged.config.js`
I want to create a message for terminal errors.
But my code does not work! :(
local return_code=""
local code="%?"
if [ "$code" = "130" ]; then
return_code="%F{red}TERMINATED BY USER ↵%f"
elif [ "$code" = "0" ]; then
return_code=""
else
return_code="%F{red}${code} ↵%f" # <= always return
fi
Or I used another method
local code=$? # always return zero
if [ $code -eq 130 ]; then
...
I found the answer in the comments and thank you
local e001="%(1?.(!) GENERAL ERROR%f ↵."
local e002="%(2?.(!) MISUSE OF SHELL BUILTINS%f ↵."
local e126="%(126?.(!) COMMAND INVOKED CANNOT EXECUTE%f ↵."
local e127="%(127?.(!) COMMAND NOT FOUND%f ↵."
local e128="%(128?.(!) INVALID ARGUMENT TO EXIT%f ↵."
local e130="%(130?.(!) TERMINATED BY USER%f ↵."
local e255="%(255?.(!) EXIT STATUS OUT OF RANGE%f ↵."
local return_code="%F{red}${e001}${e002}${e126}${e127}${e128}${e130}${e255}%(?..%?%f ↵)"
There was no need for conditions
My ansible-playbook is running some long running task with async tag and also utilizes "creates:" condition, so it is run only once on the server. When I was writing the playbook yesterday, I am pretty sure, the task was skipped when the log set in "creates:" tag existed.
It shows changed now though, everytime I run it.
I am confused as I do not think I did change anything and I'd like to set up my registered varaible correctly as unchanged, when the condition is true.
Output of ansible-play (debug section shows the task is changed: true):
TASK [singleserver : Install Assure1 SingleServer role] *********************************************************************************************************************************
changed: [crassure1]
TASK [singleserver : Debug] *************************************************************************************************************************************************************
ok: [crassure1] => {
"msg": {
"ansible_job_id": "637594935242.28556",
"changed": true,
"failed": false,
"finished": 0,
"results_file": "/root/.ansible_async/637594935242.28556",
"started": 1
}
}
But if I check the actual results file on the target maschine, it correctly resolved condition and did not actually execute the shell script, so the task should be unchanged (shows message the task is skipped as the log exists):
[root#crassure1 assure1]# cat "/root/.ansible_async/637594935242.28556"
{"invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": true, "strip_empty_ends": true, "_raw_params": "/opt/install/install_command.sh", "removes": null, "argv": null, "creates": "/opt/assure1/logs/SetupWizard.log", "chdir": null, "stdin_add_newline": true, "stdin": null}}, "cmd": "/opt/install/install_command.sh", "changed": false, "rc": 0, "stdout": "skipped, since /opt/assure1/logs/SetupWizard.log exists"}[root#crassure1 assure1]# Connection reset by 172.24.36.123 port 22
My playbook section looks like this:
- name: Install Assure1 SingleServer role
shell:
#cmd: "/opt/assure1/bin/SetupWizard -a --Depot /opt/install/:a1-local --First --WebFQDN crassure1.tspdata.local --Roles All"
cmd: "/opt/install/install_command.sh"
async: 7200
poll: 0
register: Assure1InstallWait
args:
creates: /opt/assure1/logs/SetupWizard.log
- name: Debug
debug:
msg: "{{ Assure1InstallWait }}"
- name: Check on Installation status every 15 minutes
async_status:
jid: "{{ Assure1InstallWait.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
delay: 900
when: Assure1InstallWait is changed
Is there something I am missing, or is that some kind of a bug?
I am limited by Ansible version available in configured trusted repo, so I am using ansible 2.9.25
Q: "The module shell shows changed every time I run it"
A: In async mode the task can't be skipped immediately. First, the module shell must find out whether the file /opt/assure1/logs/SetupWizard.log exists at the remote host or not. Then, if the file exists the module will decide to skip the execution of the command. But, you run the task asynchronously. In this case, Ansible starts the module and returns without waiting for the module to complete. That's what the registered variable Assure1InstallWait says. The task started but didn't finish yet.
"msg": {
"ansible_job_id": "637594935242.28556",
"changed": true,
"failed": false,
"finished": 0,
"results_file": "/root/.ansible_async/637594935242.28556",
"started": 1
}
The decision to set such a task changed is correct, I think because the execution on the remote host is going on.
Print the registered result of the module async. You'll see, that the command was skipped because the file exists (you've printed the async file at the remote instead). Here the attribute changed is set false because now we know the command didn't execute
job_result:
...
attempts: 1
changed: false
failed: false
finished: 1
msg: Did not run command since '/tmp/SetupWizard.log' exists
rc: 0
...
I am trying to download the table data from http://www.footywire.com/afl/footy/ft_match_statistics?mid=5634
but run into problems when I try and obtain the soup from BeautifulSoup
I am trying
url='http://www.footywire.com/afl/footy/ft_match_statistics?mid=5634'
soup=BeautifulSoup(url)
but just get back the header, or nothing at all.
I've also tried using different a different parser (html5lib), and also reading the page through urllib2, but still not getting any of the body of the page. I'm pretty useless at web interaction so maybe there is something fundamental I am missing, but it seems to work on other websites.
Any help would be much appreciated in pulling this data. Why am I not getting the expected source?
Hello fellow Aussie :)
I'd use requests and lxml if I were you. I think that website is checking for cookies and a few headers. Requests' session class stores cookies and will let you pass headers too. lxml will let you use xpath here which I think will be less painful than BeautifulSoup's interface.
See below:
>>> import lxml.html
>>> import requests
>>> session = requests.session()
>>> response = session.get("http://www.footywire.com/afl/footy/ft_match_statistics?mid=5634", headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Referer":"http://www.footywire.com/afl/footy/ft_match_statistics?mid=5634","Cache-Control":"max-age=0"})
>>> tree = lxml.html.fromstring(response.text)
>>> rows = tree.xpath("//table//table//table//table//table//table//tr")
>>> for row in rows:
... row.xpath(".//td//text()")
...
[u'\xa0\xa0', 'Sydney Match Statistics (Sorted by Disposals)', 'Coach: ', 'John Longmire', u'\xa0\xa0']
['Player', 'K', 'HB', 'D', 'M', 'G', 'B', 'T', 'HO', 'I50', 'FF', 'FA', 'DT', 'SC']
['Josh Kennedy', '20', '17', '37', '2', '1', '1', '1', '0', '3', '1', '0', '112', '126']
['Jarrad McVeigh', '23', '11', '34', '1', '0', '0', '2', '0', '5', '1', '1', '100', '116']
... cont...
The xpath query could be a bit brittle, but you get the idea :)