golden hour
/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules
⬆️ Go Up
Upload
File/Folder
Size
Actions
__init__.py
35 B
Del
OK
__pycache__
-
Del
OK
acme.py
12.74 KB
Del
OK
aix_group.py
4.12 KB
Del
OK
aix_shadow.py
1.93 KB
Del
OK
aixpkg.py
24.15 KB
Del
OK
aliases.py
5.07 KB
Del
OK
alternatives.py
5.71 KB
Del
OK
ansiblegate.py
19.51 KB
Del
OK
apache.py
12.47 KB
Del
OK
apcups.py
2.15 KB
Del
OK
apf.py
3.09 KB
Del
OK
apkpkg.py
16 KB
Del
OK
aptly.py
15.28 KB
Del
OK
aptpkg.py
116.64 KB
Del
OK
archive.py
48.63 KB
Del
OK
arista_pyeapi.py
22.06 KB
Del
OK
artifactory.py
24.78 KB
Del
OK
at.py
10.72 KB
Del
OK
at_solaris.py
8.51 KB
Del
OK
augeas_cfg.py
13.93 KB
Del
OK
aws_sqs.py
6.55 KB
Del
OK
azurearm_compute.py
20.8 KB
Del
OK
azurearm_dns.py
15.8 KB
Del
OK
azurearm_network.py
82.99 KB
Del
OK
azurearm_resource.py
35.75 KB
Del
OK
bamboohr.py
7.36 KB
Del
OK
baredoc.py
11.13 KB
Del
OK
bcache.py
28.97 KB
Del
OK
beacons.py
27.82 KB
Del
OK
bigip.py
69.11 KB
Del
OK
bluez_bluetooth.py
6.76 KB
Del
OK
boto3_elasticache.py
37.34 KB
Del
OK
boto3_elasticsearch.py
53.17 KB
Del
OK
boto3_route53.py
39.82 KB
Del
OK
boto3_sns.py
12.93 KB
Del
OK
boto_apigateway.py
61.86 KB
Del
OK
boto_asg.py
35.69 KB
Del
OK
boto_cfn.py
7.95 KB
Del
OK
boto_cloudfront.py
12.75 KB
Del
OK
boto_cloudtrail.py
14.45 KB
Del
OK
boto_cloudwatch.py
10.99 KB
Del
OK
boto_cloudwatch_event.py
9.48 KB
Del
OK
boto_cognitoidentity.py
14.63 KB
Del
OK
boto_datapipeline.py
6.94 KB
Del
OK
boto_dynamodb.py
14.98 KB
Del
OK
boto_ec2.py
79.27 KB
Del
OK
boto_efs.py
14.05 KB
Del
OK
boto_elasticache.py
23.69 KB
Del
OK
boto_elasticsearch_domain.py
15.85 KB
Del
OK
boto_elb.py
35.53 KB
Del
OK
boto_elbv2.py
10.78 KB
Del
OK
boto_iam.py
75.62 KB
Del
OK
boto_iot.py
26.2 KB
Del
OK
boto_kinesis.py
19.62 KB
Del
OK
boto_kms.py
17.29 KB
Del
OK
boto_lambda.py
35.05 KB
Del
OK
boto_rds.py
34.92 KB
Del
OK
boto_route53.py
32.55 KB
Del
OK
boto_s3.py
4.24 KB
Del
OK
boto_s3_bucket.py
31.8 KB
Del
OK
boto_secgroup.py
25.22 KB
Del
OK
boto_sns.py
7.22 KB
Del
OK
boto_sqs.py
6.43 KB
Del
OK
boto_ssm.py
3.63 KB
Del
OK
boto_vpc.py
113.08 KB
Del
OK
bower.py
5.85 KB
Del
OK
bridge.py
10.81 KB
Del
OK
bsd_shadow.py
6.25 KB
Del
OK
btrfs.py
33.66 KB
Del
OK
cabal.py
3.79 KB
Del
OK
capirca_acl.py
40.04 KB
Del
OK
cassandra_cql.py
54.16 KB
Del
OK
cassandra_mod.py
4.3 KB
Del
OK
celery.py
3.33 KB
Del
OK
ceph.py
15.82 KB
Del
OK
chassis.py
1.52 KB
Del
OK
chef.py
4.66 KB
Del
OK
chocolatey.py
41.55 KB
Del
OK
chronos.py
2.89 KB
Del
OK
chroot.py
11.73 KB
Del
OK
cimc.py
23.02 KB
Del
OK
ciscoconfparse_mod.py
14.79 KB
Del
OK
cisconso.py
3.83 KB
Del
OK
cloud.py
9.39 KB
Del
OK
cmdmod.py
163.73 KB
Del
OK
composer.py
10.31 KB
Del
OK
config.py
16.98 KB
Del
OK
consul.py
69.3 KB
Del
OK
container_resource.py
12.94 KB
Del
OK
cp.py
31.98 KB
Del
OK
cpan.py
5.54 KB
Del
OK
cron.py
28.09 KB
Del
OK
cryptdev.py
10.08 KB
Del
OK
csf.py
16.04 KB
Del
OK
cyg.py
8.32 KB
Del
OK
daemontools.py
5.41 KB
Del
OK
data.py
3.85 KB
Del
OK
datadog_api.py
7.76 KB
Del
OK
ddns.py
7.12 KB
Del
OK
deb_apache.py
7.41 KB
Del
OK
deb_postgres.py
4.18 KB
Del
OK
debconfmod.py
4.06 KB
Del
OK
debian_ip.py
64.91 KB
Del
OK
debian_service.py
6.55 KB
Del
OK
debuild_pkgbuild.py
34.68 KB
Del
OK
defaults.py
6.55 KB
Del
OK
devinfo.py
9.07 KB
Del
OK
devmap.py
627 B
Del
OK
dig.py
8.75 KB
Del
OK
disk.py
30.82 KB
Del
OK
djangomod.py
7.53 KB
Del
OK
dnsmasq.py
5.71 KB
Del
OK
dnsutil.py
11.51 KB
Del
OK
dockercompose.py
32.62 KB
Del
OK
dockermod.py
224.85 KB
Del
OK
dpkg_lowpkg.py
12.94 KB
Del
OK
drac.py
10.97 KB
Del
OK
dracr.py
38.53 KB
Del
OK
drbd.py
7.19 KB
Del
OK
dummyproxy_pkg.py
2.46 KB
Del
OK
dummyproxy_service.py
2.91 KB
Del
OK
ebuildpkg.py
38.74 KB
Del
OK
eix.py
1.58 KB
Del
OK
elasticsearch.py
51.44 KB
Del
OK
environ.py
8.96 KB
Del
OK
eselect.py
4.99 KB
Del
OK
esxcluster.py
1.66 KB
Del
OK
esxdatacenter.py
1.68 KB
Del
OK
esxi.py
2.79 KB
Del
OK
esxvm.py
1.63 KB
Del
OK
etcd_mod.py
8.56 KB
Del
OK
ethtool.py
11.12 KB
Del
OK
event.py
7.67 KB
Del
OK
extfs.py
8.78 KB
Del
OK
file.py
232.18 KB
Del
OK
firewalld.py
20.51 KB
Del
OK
freebsd_sysctl.py
4.99 KB
Del
OK
freebsd_update.py
6.19 KB
Del
OK
freebsdjail.py
7.16 KB
Del
OK
freebsdkmod.py
6.17 KB
Del
OK
freebsdpkg.py
17.04 KB
Del
OK
freebsdports.py
13.13 KB
Del
OK
freebsdservice.py
12.53 KB
Del
OK
freezer.py
10.2 KB
Del
OK
gcp_addon.py
4.07 KB
Del
OK
gem.py
10.6 KB
Del
OK
genesis.py
21.75 KB
Del
OK
gentoo_service.py
9.18 KB
Del
OK
gentoolkitmod.py
8.39 KB
Del
OK
git.py
172.01 KB
Del
OK
github.py
53.19 KB
Del
OK
glanceng.py
4.69 KB
Del
OK
glassfish.py
19.49 KB
Del
OK
glusterfs.py
19.55 KB
Del
OK
gnomedesktop.py
6.85 KB
Del
OK
google_chat.py
1.52 KB
Del
OK
gpg.py
39.09 KB
Del
OK
grafana4.py
30.27 KB
Del
OK
grains.py
21.81 KB
Del
OK
groupadd.py
11.87 KB
Del
OK
grub_legacy.py
3.08 KB
Del
OK
guestfs.py
2.37 KB
Del
OK
hadoop.py
3.76 KB
Del
OK
haproxyconn.py
10.17 KB
Del
OK
hashutil.py
6.77 KB
Del
OK
heat.py
25.25 KB
Del
OK
helm.py
39.27 KB
Del
OK
hg.py
7.16 KB
Del
OK
highstate_doc.py
22.76 KB
Del
OK
hosts.py
10.47 KB
Del
OK
http.py
3.76 KB
Del
OK
icinga2.py
4.46 KB
Del
OK
idem.py
1.75 KB
Del
OK
ifttt.py
2.28 KB
Del
OK
ilo.py
15.98 KB
Del
OK
incron.py
7.68 KB
Del
OK
influxdb08mod.py
15.07 KB
Del
OK
influxdbmod.py
16.13 KB
Del
OK
infoblox.py
17.53 KB
Del
OK
ini_manage.py
14.63 KB
Del
OK
inspectlib
-
Del
OK
inspector.py
8.19 KB
Del
OK
introspect.py
4.02 KB
Del
OK
iosconfig.py
14.78 KB
Del
OK
ipmi.py
25.47 KB
Del
OK
ipset.py
17.97 KB
Del
OK
iptables.py
57.44 KB
Del
OK
iwtools.py
3.99 KB
Del
OK
jboss7.py
20.51 KB
Del
OK
jboss7_cli.py
15.23 KB
Del
OK
jenkinsmod.py
11.9 KB
Del
OK
jinja.py
2.66 KB
Del
OK
jira_mod.py
7.07 KB
Del
OK
junos.py
73.96 KB
Del
OK
k8s.py
24.87 KB
Del
OK
kapacitor.py
5.37 KB
Del
OK
kerberos.py
5.42 KB
Del
OK
kernelpkg_linux_apt.py
6.71 KB
Del
OK
kernelpkg_linux_yum.py
7.26 KB
Del
OK
key.py
1007 B
Del
OK
keyboard.py
2.64 KB
Del
OK
keystone.py
43.14 KB
Del
OK
keystoneng.py
21.82 KB
Del
OK
keystore.py
7.18 KB
Del
OK
kmod.py
7.65 KB
Del
OK
kubeadm.py
34.64 KB
Del
OK
kubernetesmod.py
46.77 KB
Del
OK
launchctl_service.py
9.69 KB
Del
OK
layman.py
4.22 KB
Del
OK
ldap3.py
18.81 KB
Del
OK
ldapmod.py
5.9 KB
Del
OK
libcloud_compute.py
23.48 KB
Del
OK
libcloud_dns.py
9.73 KB
Del
OK
libcloud_loadbalancer.py
13.14 KB
Del
OK
libcloud_storage.py
12.16 KB
Del
OK
linux_acl.py
7.7 KB
Del
OK
linux_ip.py
5.55 KB
Del
OK
linux_lvm.py
17.86 KB
Del
OK
linux_service.py
4.64 KB
Del
OK
linux_shadow.py
12.96 KB
Del
OK
linux_sysctl.py
7.5 KB
Del
OK
localemod.py
11.84 KB
Del
OK
locate.py
2.58 KB
Del
OK
logadm.py
9.44 KB
Del
OK
logmod.py
1.25 KB
Del
OK
logrotate.py
7.72 KB
Del
OK
lvs.py
11.54 KB
Del
OK
lxc.py
147.27 KB
Del
OK
lxd.py
90.07 KB
Del
OK
mac_assistive.py
11.37 KB
Del
OK
mac_brew_pkg.py
19.91 KB
Del
OK
mac_desktop.py
2.77 KB
Del
OK
mac_group.py
6.62 KB
Del
OK
mac_keychain.py
6.39 KB
Del
OK
mac_pkgutil.py
2.84 KB
Del
OK
mac_portspkg.py
11.36 KB
Del
OK
mac_power.py
13.29 KB
Del
OK
mac_service.py
19.64 KB
Del
OK
mac_shadow.py
14.23 KB
Del
OK
mac_softwareupdate.py
14.52 KB
Del
OK
mac_sysctl.py
5.13 KB
Del
OK
mac_system.py
15.07 KB
Del
OK
mac_timezone.py
8.34 KB
Del
OK
mac_user.py
16.41 KB
Del
OK
mac_xattr.py
6.27 KB
Del
OK
macdefaults.py
2.33 KB
Del
OK
macpackage.py
6.66 KB
Del
OK
makeconf.py
17.31 KB
Del
OK
mandrill.py
6.31 KB
Del
OK
marathon.py
5.36 KB
Del
OK
match.py
13 KB
Del
OK
mattermost.py
3.4 KB
Del
OK
mdadm_raid.py
9.86 KB
Del
OK
mdata.py
3.38 KB
Del
OK
memcached.py
6.13 KB
Del
OK
mine.py
18.84 KB
Del
OK
minion.py
7.68 KB
Del
OK
mod_random.py
7.18 KB
Del
OK
modjk.py
12.48 KB
Del
OK
mongodb.py
29.75 KB
Del
OK
monit.py
5.51 KB
Del
OK
moosefs.py
3.87 KB
Del
OK
mount.py
58.44 KB
Del
OK
mssql.py
14.64 KB
Del
OK
msteams.py
2.11 KB
Del
OK
munin.py
2.4 KB
Del
OK
mysql.py
90.66 KB
Del
OK
nacl.py
9.72 KB
Del
OK
nagios.py
6.53 KB
Del
OK
nagios_rpc.py
5.09 KB
Del
OK
namecheap_domains.py
12.84 KB
Del
OK
namecheap_domains_dns.py
5.93 KB
Del
OK
namecheap_domains_ns.py
4.51 KB
Del
OK
namecheap_ssl.py
25.69 KB
Del
OK
namecheap_users.py
2.4 KB
Del
OK
napalm_bgp.py
9.72 KB
Del
OK
napalm_formula.py
11.33 KB
Del
OK
napalm_mod.py
61.37 KB
Del
OK
napalm_netacl.py
28.59 KB
Del
OK
napalm_network.py
93.22 KB
Del
OK
napalm_ntp.py
10.22 KB
Del
OK
napalm_probes.py
13.25 KB
Del
OK
napalm_route.py
5.09 KB
Del
OK
napalm_snmp.py
7.05 KB
Del
OK
napalm_users.py
6.49 KB
Del
OK
napalm_yang_mod.py
20.28 KB
Del
OK
netaddress.py
1.6 KB
Del
OK
netbox.py
32.22 KB
Del
OK
netbsd_sysctl.py
3.92 KB
Del
OK
netbsdservice.py
6.43 KB
Del
OK
netmiko_mod.py
19.61 KB
Del
OK
netscaler.py
27.02 KB
Del
OK
network.py
63.42 KB
Del
OK
neutron.py
44.92 KB
Del
OK
neutronng.py
15.02 KB
Del
OK
nexus.py
22.95 KB
Del
OK
nfs3.py
3.9 KB
Del
OK
nftables.py
33.58 KB
Del
OK
nginx.py
3.83 KB
Del
OK
nilrt_ip.py
36.18 KB
Del
OK
nix.py
8.03 KB
Del
OK
nova.py
19.6 KB
Del
OK
npm.py
10.4 KB
Del
OK
nspawn.py
41.35 KB
Del
OK
nxos.py
24.65 KB
Del
OK
nxos_api.py
14.72 KB
Del
OK
nxos_upgrade.py
14.74 KB
Del
OK
omapi.py
3.6 KB
Del
OK
openbsd_sysctl.py
3.74 KB
Del
OK
openbsdpkg.py
10.97 KB
Del
OK
openbsdrcctl_service.py
6.33 KB
Del
OK
openbsdservice.py
8.31 KB
Del
OK
openscap.py
2.81 KB
Del
OK
openstack_config.py
3.21 KB
Del
OK
openstack_mng.py
2.71 KB
Del
OK
openvswitch.py
17.19 KB
Del
OK
opkg.py
49.67 KB
Del
OK
opsgenie.py
3.29 KB
Del
OK
oracle.py
5.82 KB
Del
OK
osquery.py
24.93 KB
Del
OK
out.py
2.53 KB
Del
OK
pacmanpkg.py
31.92 KB
Del
OK
pagerduty.py
4.7 KB
Del
OK
pagerduty_util.py
13.48 KB
Del
OK
pam.py
2.01 KB
Del
OK
panos.py
61.05 KB
Del
OK
parallels.py
19.85 KB
Del
OK
parted_partition.py
21.53 KB
Del
OK
pcs.py
14.11 KB
Del
OK
pdbedit.py
10.79 KB
Del
OK
pecl.py
3.79 KB
Del
OK
peeringdb.py
8.39 KB
Del
OK
pf.py
9.51 KB
Del
OK
philips_hue.py
1.55 KB
Del
OK
pillar.py
21.37 KB
Del
OK
pip.py
53.42 KB
Del
OK
pkg_resource.py
12.3 KB
Del
OK
pkgin.py
17.29 KB
Del
OK
pkgng.py
61.07 KB
Del
OK
pkgutil.py
9.85 KB
Del
OK
portage_config.py
22.73 KB
Del
OK
postfix.py
16.24 KB
Del
OK
postgres.py
88.24 KB
Del
OK
poudriere.py
7.85 KB
Del
OK
powerpath.py
2.57 KB
Del
OK
proxy.py
11.49 KB
Del
OK
ps.py
20.89 KB
Del
OK
publish.py
10.25 KB
Del
OK
puppet.py
10.9 KB
Del
OK
purefa.py
33.59 KB
Del
OK
purefb.py
13.69 KB
Del
OK
pushbullet.py
1.88 KB
Del
OK
pushover_notify.py
3.48 KB
Del
OK
pw_group.py
4.62 KB
Del
OK
pw_user.py
12.47 KB
Del
OK
pyenv.py
6.93 KB
Del
OK
qemu_img.py
1.53 KB
Del
OK
qemu_nbd.py
3.28 KB
Del
OK
quota.py
6.43 KB
Del
OK
rabbitmq.py
38.4 KB
Del
OK
rallydev.py
6.09 KB
Del
OK
random_org.py
23.76 KB
Del
OK
rbac_solaris.py
16.05 KB
Del
OK
rbenv.py
10.75 KB
Del
OK
rdp.py
6.08 KB
Del
OK
rebootmgr.py
7.68 KB
Del
OK
redismod.py
16.36 KB
Del
OK
reg.py
16.36 KB
Del
OK
rest_pkg.py
2.26 KB
Del
OK
rest_sample_utils.py
558 B
Del
OK
rest_service.py
3.63 KB
Del
OK
restartcheck.py
24.1 KB
Del
OK
restconf.py
3.15 KB
Del
OK
ret.py
1.27 KB
Del
OK
rh_ip.py
38.55 KB
Del
OK
rh_service.py
16.61 KB
Del
OK
riak.py
5.19 KB
Del
OK
rpm_lowpkg.py
27.67 KB
Del
OK
rpmbuild_pkgbuild.py
24.53 KB
Del
OK
rsync.py
8.04 KB
Del
OK
runit.py
17.17 KB
Del
OK
rvm.py
11.1 KB
Del
OK
s3.py
9.93 KB
Del
OK
s6.py
3.62 KB
Del
OK
salt_proxy.py
4.48 KB
Del
OK
salt_version.py
4.58 KB
Del
OK
saltcheck.py
46.66 KB
Del
OK
saltcloudmod.py
954 B
Del
OK
saltutil.py
57.49 KB
Del
OK
schedule.py
50.81 KB
Del
OK
scp_mod.py
6.22 KB
Del
OK
scsi.py
2.66 KB
Del
OK
sdb.py
2.48 KB
Del
OK
seed.py
8.87 KB
Del
OK
selinux.py
24.2 KB
Del
OK
sensehat.py
7.79 KB
Del
OK
sensors.py
1.3 KB
Del
OK
serverdensity_device.py
8.1 KB
Del
OK
servicenow.py
4.36 KB
Del
OK
slack_notify.py
7.83 KB
Del
OK
slackware_service.py
6.84 KB
Del
OK
slsutil.py
19.04 KB
Del
OK
smartos_imgadm.py
12.04 KB
Del
OK
smartos_nictagadm.py
6.46 KB
Del
OK
smartos_virt.py
5.21 KB
Del
OK
smartos_vmadm.py
26.2 KB
Del
OK
smbios.py
10.05 KB
Del
OK
smf_service.py
8.52 KB
Del
OK
smtp.py
5.41 KB
Del
OK
snapper.py
27.14 KB
Del
OK
solaris_fmadm.py
11.2 KB
Del
OK
solaris_group.py
2.8 KB
Del
OK
solaris_shadow.py
7.98 KB
Del
OK
solaris_system.py
3.72 KB
Del
OK
solaris_user.py
11.06 KB
Del
OK
solarisipspkg.py
18.68 KB
Del
OK
solarispkg.py
15.4 KB
Del
OK
solr.py
45.54 KB
Del
OK
solrcloud.py
14.63 KB
Del
OK
splunk.py
8.14 KB
Del
OK
splunk_search.py
8.76 KB
Del
OK
sqlite3.py
2.54 KB
Del
OK
ssh.py
43.89 KB
Del
OK
ssh_pkg.py
1.08 KB
Del
OK
ssh_service.py
3.39 KB
Del
OK
state.py
82.34 KB
Del
OK
status.py
57.79 KB
Del
OK
statuspage.py
14.67 KB
Del
OK
supervisord.py
11.15 KB
Del
OK
suse_apache.py
2.45 KB
Del
OK
suse_ip.py
35.72 KB
Del
OK
svn.py
10.75 KB
Del
OK
swarm.py
13.5 KB
Del
OK
swift.py
5.53 KB
Del
OK
sysbench.py
6.62 KB
Del
OK
sysfs.py
6.61 KB
Del
OK
syslog_ng.py
31.52 KB
Del
OK
sysmod.py
22.59 KB
Del
OK
sysrc.py
3.38 KB
Del
OK
system.py
19.28 KB
Del
OK
system_profiler.py
3.54 KB
Del
OK
systemd_service.py
46.29 KB
Del
OK
telegram.py
3.28 KB
Del
OK
telemetry.py
12.87 KB
Del
OK
temp.py
831 B
Del
OK
test.py
15.4 KB
Del
OK
test_virtual.py
237 B
Del
OK
testinframod.py
9.92 KB
Del
OK
textfsm_mod.py
16.22 KB
Del
OK
timezone.py
19.98 KB
Del
OK
tls.py
58.63 KB
Del
OK
tomcat.py
18.59 KB
Del
OK
trafficserver.py
10.44 KB
Del
OK
transactional_update.py
35.83 KB
Del
OK
travisci.py
2.05 KB
Del
OK
tuned.py
2.34 KB
Del
OK
twilio_notify.py
2.95 KB
Del
OK
udev.py
3.72 KB
Del
OK
upstart_service.py
16.92 KB
Del
OK
uptime.py
3.23 KB
Del
OK
useradd.py
22.63 KB
Del
OK
uwsgi.py
996 B
Del
OK
vagrant.py
20.4 KB
Del
OK
varnish.py
3.08 KB
Del
OK
vault.py
15.61 KB
Del
OK
vbox_guest.py
10.55 KB
Del
OK
vboxmanage.py
14.71 KB
Del
OK
vcenter.py
1.61 KB
Del
OK
victorops.py
6.54 KB
Del
OK
virt.py
287.71 KB
Del
OK
virtualenv_mod.py
15.09 KB
Del
OK
vmctl.py
9.56 KB
Del
OK
vsphere.py
380.41 KB
Del
OK
webutil.py
3.66 KB
Del
OK
win_auditpol.py
4.74 KB
Del
OK
win_autoruns.py
2.29 KB
Del
OK
win_certutil.py
4.55 KB
Del
OK
win_dacl.py
32.27 KB
Del
OK
win_disk.py
1.8 KB
Del
OK
win_dism.py
20.7 KB
Del
OK
win_dns_client.py
4.19 KB
Del
OK
win_dsc.py
27.54 KB
Del
OK
win_event.py
22.32 KB
Del
OK
win_file.py
64.39 KB
Del
OK
win_firewall.py
20.15 KB
Del
OK
win_groupadd.py
11.27 KB
Del
OK
win_iis.py
68.78 KB
Del
OK
win_ip.py
11.43 KB
Del
OK
win_lgpo.py
491.76 KB
Del
OK
win_lgpo_reg.py
17.9 KB
Del
OK
win_license.py
2.72 KB
Del
OK
win_network.py
13.9 KB
Del
OK
win_ntp.py
1.8 KB
Del
OK
win_path.py
11.12 KB
Del
OK
win_pkg.py
86.43 KB
Del
OK
win_pki.py
15.8 KB
Del
OK
win_powercfg.py
9.85 KB
Del
OK
win_psget.py
8.97 KB
Del
OK
win_servermanager.py
14.21 KB
Del
OK
win_service.py
32.96 KB
Del
OK
win_shadow.py
3.03 KB
Del
OK
win_shortcut.py
16.49 KB
Del
OK
win_smtp_server.py
17.67 KB
Del
OK
win_snmp.py
13.38 KB
Del
OK
win_status.py
16.94 KB
Del
OK
win_system.py
40.61 KB
Del
OK
win_task.py
79.17 KB
Del
OK
win_timezone.py
13.3 KB
Del
OK
win_useradd.py
27.39 KB
Del
OK
win_wua.py
38.29 KB
Del
OK
win_wusa.py
5.88 KB
Del
OK
winrepo.py
6.09 KB
Del
OK
wordpress.py
4.71 KB
Del
OK
x509.py
63.1 KB
Del
OK
x509_v2.py
74.15 KB
Del
OK
xapi_virt.py
24.07 KB
Del
OK
xbpspkg.py
15.84 KB
Del
OK
xfs.py
15.35 KB
Del
OK
xml.py
2.14 KB
Del
OK
xmpp.py
5.28 KB
Del
OK
yaml.py
1.94 KB
Del
OK
yumpkg.py
116.5 KB
Del
OK
zabbix.py
97.55 KB
Del
OK
zcbuildout.py
28.16 KB
Del
OK
zenoss.py
5.64 KB
Del
OK
zfs.py
34.44 KB
Del
OK
zk_concurrency.py
11.16 KB
Del
OK
znc.py
2.26 KB
Del
OK
zoneadm.py
15.05 KB
Del
OK
zonecfg.py
21.85 KB
Del
OK
zookeeper.py
14.72 KB
Del
OK
zpool.py
44.02 KB
Del
OK
zypperpkg.py
94.87 KB
Del
OK
Edit: cmdmod.py
""" A module for shelling out. Keep in mind that this module is insecure, in that it can give whomever has access to the master root execution access to all salt minions. """ import base64 import fnmatch import functools import glob import logging import os import re import shutil import subprocess import sys import tempfile import time import traceback import salt.grains.extra import salt.utils.args import salt.utils.data import salt.utils.files import salt.utils.json import salt.utils.path import salt.utils.pkg import salt.utils.platform import salt.utils.powershell import salt.utils.stringutils import salt.utils.templates import salt.utils.timed_subprocess import salt.utils.url import salt.utils.user import salt.utils.versions import salt.utils.vt import salt.utils.win_chcp import salt.utils.win_dacl import salt.utils.win_reg from salt._logging import LOG_LEVELS from salt.exceptions import ( CommandExecutionError, SaltInvocationError, TimedProcTimeoutError, ) # Only available on POSIX systems, nonfatal on windows try: import grp import pwd except ImportError: pass if salt.utils.platform.is_windows(): from salt.utils.win_functions import escape_argument as _cmd_quote from salt.utils.win_runas import runas as win_runas HAS_WIN_RUNAS = True else: import shlex _cmd_quote = shlex.quote HAS_WIN_RUNAS = False __proxyenabled__ = ["*"] # Define the module's virtual name __virtualname__ = "cmd" log = logging.getLogger(__name__) DEFAULT_SHELL = salt.grains.extra.shell()["shell"] # Overwriting the cmd python module makes debugging modules with pdb a bit # harder so lets do it this way instead. def __virtual__(): return __virtualname__ def _log_cmd(cmd): if isinstance(cmd, (tuple, list)): return cmd[0].strip() else: return str(cmd).split()[0].strip() def _check_cb(cb_): """ If the callback is None or is not callable, return a lambda that returns the value passed. """ if cb_ is not None: if hasattr(cb_, "__call__"): return cb_ else: log.error("log_callback is not callable, ignoring") return lambda x: x def _python_shell_default(python_shell, __pub_jid): """ Set python_shell default based on remote execution and __opts__['cmd_safe'] """ try: # Default to python_shell=True when run directly from remote execution # system. Cross-module calls won't have a jid. if __pub_jid and python_shell is None: return True elif __opts__.get("cmd_safe", True) is False and python_shell is None: # Override-switch for python_shell return True except NameError: pass return python_shell def _chroot_pids(chroot): pids = [] for root in glob.glob("/proc/[0-9]*/root"): try: link = os.path.realpath(root) if link.startswith(chroot): pids.append(int(os.path.basename(os.path.dirname(root)))) except OSError: pass return pids def _render_cmd(cmd, cwd, template, saltenv=None, pillarenv=None, pillar_override=None): """ If template is a valid template engine, process the cmd and cwd through that engine. """ if saltenv is None: try: saltenv = __opts__.get("saltenv", "base") except NameError: saltenv = "base" if not template: return (cmd, cwd) # render the path as a template using path_template_engine as the engine if template not in salt.utils.templates.TEMPLATE_REGISTRY: raise CommandExecutionError( "Attempted to render file paths with unavailable engine {}".format(template) ) kwargs = {} kwargs["salt"] = __salt__ if pillarenv is not None or pillar_override is not None: pillarenv = pillarenv or __opts__["pillarenv"] kwargs["pillar"] = _gather_pillar(pillarenv, pillar_override) else: kwargs["pillar"] = __pillar__ kwargs["grains"] = __grains__ kwargs["opts"] = __opts__ kwargs["saltenv"] = saltenv def _render(contents): # write out path to temp file tmp_path_fn = salt.utils.files.mkstemp() with salt.utils.files.fopen(tmp_path_fn, "w+") as fp_: fp_.write(salt.utils.stringutils.to_str(contents)) data = salt.utils.templates.TEMPLATE_REGISTRY[template]( tmp_path_fn, to_str=True, **kwargs ) salt.utils.files.safe_rm(tmp_path_fn) if not data["result"]: # Failed to render the template raise CommandExecutionError( "Failed to execute cmd with error: {}".format(data["data"]) ) else: return data["data"] cmd = _render(cmd) cwd = _render(cwd) return (cmd, cwd) def _check_loglevel(level="info"): """ Retrieve the level code for use in logging.Logger.log(). """ try: level = level.lower() if level == "quiet": return None else: return LOG_LEVELS[level] except (AttributeError, KeyError): log.error( "Invalid output_loglevel '%s'. Valid levels are: %s. Falling " "back to 'info'.", level, ", ".join(sorted(LOG_LEVELS, reverse=True)), ) return LOG_LEVELS["info"] def _parse_env(env): if not env: env = {} if isinstance(env, list): env = salt.utils.data.repack_dictlist(env) if not isinstance(env, dict): env = {} return env def _gather_pillar(pillarenv, pillar_override): """ Whenever a state run starts, gather the pillar data fresh """ pillar = salt.pillar.get_pillar( __opts__, __grains__.value(), __opts__["id"], __opts__["saltenv"], pillar_override=pillar_override, pillarenv=pillarenv, ) ret = pillar.compile_pillar() if pillar_override and isinstance(pillar_override, dict): ret.update(pillar_override) return ret def _check_avail(cmd): """ Check to see if the given command can be run """ if isinstance(cmd, list): cmd = " ".join([str(x) if not isinstance(x, str) else x for x in cmd]) bret = True wret = False if __salt__["config.get"]("cmd_blacklist_glob"): blist = __salt__["config.get"]("cmd_blacklist_glob", []) for comp in blist: if fnmatch.fnmatch(cmd, comp): # BAD! you are blacklisted bret = False if __salt__["config.get"]("cmd_whitelist_glob", []): blist = __salt__["config.get"]("cmd_whitelist_glob", []) for comp in blist: if fnmatch.fnmatch(cmd, comp): # GOOD! You are whitelisted wret = True break else: # If no whitelist set then alls good! wret = True return bret and wret def _prep_powershell_cmd(shell, cmd, stack, encoded_cmd): """ Prep cmd when shell is powershell """ # If this is running on Windows wrap # the shell in quotes in case there are # spaces in the paths. if salt.utils.platform.is_windows(): shell = '"{}"'.format(shell) # extract_stack() returns a list of tuples. # The last item in the list [-1] is the current method. # The third item[2] in each tuple is the name of that method. if stack[-2][2] == "script": cmd = ( "{} -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command {}".format( shell, cmd ) ) elif encoded_cmd: cmd = "{} -NonInteractive -NoProfile -EncodedCommand {}".format(shell, cmd) else: cmd = '{} -NonInteractive -NoProfile -Command "{}"'.format(shell, cmd) return cmd def _run( cmd, cwd=None, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, output_encoding=None, output_loglevel="debug", log_callback=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=False, env=None, clean_env=False, prepend_path=None, rstrip=True, template=None, umask=None, timeout=None, with_communicate=True, reset_system_locale=True, ignore_retcode=False, saltenv=None, pillarenv=None, pillar_override=None, use_vt=False, password=None, bg=False, encoded_cmd=False, success_retcodes=None, success_stdout=None, success_stderr=None, windows_codepage=65001, **kwargs ): """ Do the DRY thing and only call subprocess.Popen() once """ if "pillar" in kwargs and not pillar_override: pillar_override = kwargs["pillar"] if output_loglevel != "quiet" and _is_valid_shell(shell) is False: log.warning( "Attempt to run a shell command with what may be an invalid shell! " "Check to ensure that the shell <%s> is valid for this user.", shell, ) output_loglevel = _check_loglevel(output_loglevel) log_callback = _check_cb(log_callback) use_sudo = False if runas is None and "__context__" in globals(): runas = __context__.get("runas") if password is None and "__context__" in globals(): password = __context__.get("runas_password") # Set the default working directory to the home directory of the user # salt-minion is running as. Defaults to home directory of user under which # the minion is running. if not cwd: cwd = os.path.expanduser("~{}".format("" if not runas else runas)) # make sure we can access the cwd # when run from sudo or another environment where the euid is # changed ~ will expand to the home of the original uid and # the euid might not have access to it. See issue #1844 if not os.access(cwd, os.R_OK): cwd = "/" if salt.utils.platform.is_windows(): cwd = os.path.abspath(os.sep) else: # Handle edge cases where numeric/other input is entered, and would be # yaml-ified into non-string types cwd = str(cwd) if bg: ignore_retcode = True use_vt = False change_windows_codepage = False if not salt.utils.platform.is_windows(): if not os.path.isfile(shell) or not os.access(shell, os.X_OK): msg = "The shell {} is not available".format(shell) raise CommandExecutionError(msg) elif use_vt: # Memozation so not much overhead raise CommandExecutionError("VT not available on windows") else: if windows_codepage: if not isinstance(windows_codepage, int): windows_codepage = int(windows_codepage) previous_windows_codepage = salt.utils.win_chcp.get_codepage_id() if windows_codepage != previous_windows_codepage: change_windows_codepage = True # The powershell binary is "powershell" # The powershell core binary is "pwsh" # you can also pass a path here as long as the binary name is one of the two if any(word in shell.lower().strip() for word in ["powershell", "pwsh"]): # Strip whitespace if isinstance(cmd, str): cmd = cmd.strip() elif isinstance(cmd, list): cmd = " ".join(cmd).strip() cmd = cmd.replace('"', '\\"') # If we were called by script(), then fakeout the Windows # shell to run a Powershell script. # Else just run a Powershell command. stack = traceback.extract_stack(limit=2) cmd = _prep_powershell_cmd(shell, cmd, stack, encoded_cmd) # munge the cmd and cwd through the template (cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv, pillarenv, pillar_override) ret = {} # If the pub jid is here then this is a remote ex or salt call command and needs to be # checked if blacklisted if "__pub_jid" in kwargs: if not _check_avail(cmd): raise CommandExecutionError( 'The shell command "{}" is not permitted'.format(cmd) ) env = _parse_env(env) for bad_env_key in (x for x, y in env.items() if y is None): log.error( "Environment variable '%s' passed without a value. " "Setting value to an empty string", bad_env_key, ) env[bad_env_key] = "" if output_loglevel is not None: # Always log the shell commands at INFO unless quiet logging is # requested. The command output is what will be controlled by the # 'loglevel' parameter. msg = "Executing command {}{}{} {}{}in directory '{}'{}".format( "'" if not isinstance(cmd, list) else "", _log_cmd(cmd), "'" if not isinstance(cmd, list) else "", "as user '{}' ".format(runas) if runas else "", "in group '{}' ".format(group) if group else "", cwd, ". Executing command in the background, no output will be logged." if bg else "", ) log.info(log_callback(msg)) if runas and salt.utils.platform.is_windows(): if not HAS_WIN_RUNAS: msg = "missing salt/utils/win_runas.py" raise CommandExecutionError(msg) if isinstance(cmd, (list, tuple)): cmd = " ".join(cmd) return win_runas(cmd, runas, password, cwd) if runas and salt.utils.platform.is_darwin(): # We need to insert the user simulation into the command itself and not # just run it from the environment on macOS as that method doesn't work # properly when run as root for certain commands. if isinstance(cmd, (list, tuple)): cmd = " ".join(map(_cmd_quote, cmd)) # Ensure directory is correct before running command cmd = "cd -- {dir} && {{ {cmd}\n }}".format(dir=_cmd_quote(cwd), cmd=cmd) # Ensure environment is correct for a newly logged-in user by running # the command under bash as a login shell try: # Do not rely on populated __salt__ dict (ie avoid __salt__['user.info']) user_shell = [x for x in pwd.getpwall() if x.pw_name == runas][0].pw_shell if re.search("bash$", user_shell): cmd = "{shell} -l -c {cmd}".format( shell=user_shell, cmd=_cmd_quote(cmd) ) except (AttributeError, IndexError): pass # Ensure the login is simulated correctly (note: su runs sh, not bash, # which causes the environment to be initialised incorrectly, which is # fixed by the previous line of code) cmd = "su -l {} -c {}".format(_cmd_quote(runas), _cmd_quote(cmd)) # Set runas to None, because if you try to run `su -l` after changing # user, su will prompt for the password of the user and cause salt to # hang. runas = None if runas: # Save the original command before munging it try: pwd.getpwnam(runas) except KeyError: raise CommandExecutionError("User '{}' is not available".format(runas)) if group: if salt.utils.platform.is_windows(): msg = "group is not currently available on Windows" raise SaltInvocationError(msg) if not which_bin(["sudo"]): msg = "group argument requires sudo but not found" raise CommandExecutionError(msg) try: grp.getgrnam(group) except KeyError: raise CommandExecutionError("Group '{}' is not available".format(runas)) else: use_sudo = True if runas or group: try: # Getting the environment for the runas user # Use markers to thwart any stdout noise # There must be a better way to do this. import uuid marker = "<<<" + str(uuid.uuid4()) + ">>>" marker_b = marker.encode(__salt_system_encoding__) py_code = ( "import sys, os, itertools; sys.stdout.write('{0}'); " "sys.stdout.write('\\0'.join(itertools.chain(*os.environ.items()))); " "sys.stdout.write('{0}');".format(marker) ) if use_sudo: env_cmd = ["sudo"] # runas is optional if use_sudo is set. if runas: env_cmd.extend(["-u", runas]) if group: env_cmd.extend(["-g", group]) if shell != DEFAULT_SHELL: env_cmd.extend(["-s", "--", shell, "-c"]) else: env_cmd.extend(["-i", "--"]) elif __grains__["os"] in ["FreeBSD"]: env_cmd = [ "su", "-", runas, "-c", ] elif __grains__["os_family"] in ["Solaris"]: env_cmd = ["su", "-", runas, "-c"] elif __grains__["os_family"] in ["AIX"]: env_cmd = ["su", "-", runas, "-c"] else: env_cmd = ["su", "-s", shell, "-", runas, "-c"] if not salt.utils.pkg.check_bundled(): if __grains__["os"] in ["FreeBSD"]: env_cmd.extend(["{} -c {}".format(shell, sys.executable)]) else: env_cmd.extend([sys.executable]) else: with tempfile.NamedTemporaryFile("w", delete=False) as fp: if __grains__["os"] in ["FreeBSD"]: env_cmd.extend( [ "{} -c {} python {}".format( shell, sys.executable, fp.name ) ] ) else: env_cmd.extend(["{} python {}".format(sys.executable, fp.name)]) fp.write(py_code) shutil.chown(fp.name, runas) msg = "env command: {}".format(env_cmd) log.debug(log_callback(msg)) env_bytes, env_encoded_err = subprocess.Popen( env_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE, ).communicate(salt.utils.stringutils.to_bytes(py_code)) if salt.utils.pkg.check_bundled(): os.remove(fp.name) marker_count = env_bytes.count(marker_b) if marker_count == 0: # Possibly PAM prevented the login log.error( "Environment could not be retrieved for user '%s': " "stderr=%r stdout=%r", runas, env_encoded_err, env_bytes, ) # Ensure that we get an empty env_runas dict below since we # were not able to get the environment. env_bytes = b"" elif marker_count != 2: raise CommandExecutionError( "Environment could not be retrieved for user '{}'", info={"stderr": repr(env_encoded_err), "stdout": repr(env_bytes)}, ) else: # Strip the marker env_bytes = env_bytes.split(marker_b)[1] env_runas = dict(list(zip(*[iter(env_bytes.split(b"\0"))] * 2))) env_runas = { salt.utils.stringutils.to_str(k): salt.utils.stringutils.to_str(v) for k, v in env_runas.items() } env_runas.update(env) # Fix platforms like Solaris that don't set a USER env var in the # user's default environment as obtained above. if env_runas.get("USER") != runas: env_runas["USER"] = runas # Fix some corner cases where shelling out to get the user's # environment returns the wrong home directory. runas_home = os.path.expanduser("~{}".format(runas)) if env_runas.get("HOME") != runas_home: env_runas["HOME"] = runas_home env = env_runas except ValueError as exc: log.exception("Error raised retrieving environment for user %s", runas) raise CommandExecutionError( "Environment could not be retrieved for user '{}': {}".format( runas, exc ) ) if reset_system_locale is True: if not salt.utils.platform.is_windows(): # Default to C! # Salt only knows how to parse English words # Don't override if the user has passed LC_ALL env.setdefault("LC_CTYPE", "C") env.setdefault("LC_NUMERIC", "C") env.setdefault("LC_TIME", "C") env.setdefault("LC_COLLATE", "C") env.setdefault("LC_MONETARY", "C") env.setdefault("LC_MESSAGES", "C") env.setdefault("LC_PAPER", "C") env.setdefault("LC_NAME", "C") env.setdefault("LC_ADDRESS", "C") env.setdefault("LC_TELEPHONE", "C") env.setdefault("LC_MEASUREMENT", "C") env.setdefault("LC_IDENTIFICATION", "C") env.setdefault("LANGUAGE", "C") if clean_env: run_env = env else: if salt.utils.platform.is_windows(): import nt run_env = nt.environ.copy() else: run_env = os.environ.copy() run_env.update(env) if prepend_path: run_env["PATH"] = ":".join((prepend_path, run_env["PATH"])) if "NOTIFY_SOCKET" not in env: run_env.pop("NOTIFY_SOCKET", None) if python_shell is None: python_shell = False new_kwargs = { "cwd": cwd, "shell": python_shell, "env": run_env, "stdin": str(stdin) if stdin is not None else stdin, "stdout": stdout, "stderr": stderr, "with_communicate": with_communicate, "timeout": timeout, "bg": bg, } if "stdin_raw_newlines" in kwargs: new_kwargs["stdin_raw_newlines"] = kwargs["stdin_raw_newlines"] if umask is not None: _umask = str(umask).lstrip("0") if _umask == "": msg = "Zero umask is not allowed." raise CommandExecutionError(msg) try: _umask = int(_umask, 8) except ValueError: raise CommandExecutionError("Invalid umask: '{}'".format(umask)) else: _umask = None if runas or group or umask: new_kwargs["preexec_fn"] = functools.partial( salt.utils.user.chugid_and_umask, runas, _umask, group ) if not salt.utils.platform.is_windows(): # close_fds is not supported on Windows platforms if you redirect # stdin/stdout/stderr if new_kwargs["shell"] is True: new_kwargs["executable"] = shell if salt.utils.platform.is_freebsd() and sys.version_info < (3, 9): # https://bugs.python.org/issue38061 new_kwargs["close_fds"] = False else: new_kwargs["close_fds"] = True if not os.path.isabs(cwd) or not os.path.isdir(cwd): raise CommandExecutionError( "Specified cwd '{}' either not absolute or does not exist".format(cwd) ) if ( python_shell is not True and not salt.utils.platform.is_windows() and not isinstance(cmd, list) ): cmd = salt.utils.args.shlex_split(cmd) if success_retcodes is None: success_retcodes = [0] else: try: success_retcodes = [ int(i) for i in salt.utils.args.split_input(success_retcodes) ] except ValueError: raise SaltInvocationError("success_retcodes must be a list of integers") if success_stdout is None: success_stdout = [] else: success_stdout = salt.utils.args.split_input(success_stdout) if success_stderr is None: success_stderr = [] else: success_stderr = salt.utils.args.split_input(success_stderr) if not use_vt: # This is where the magic happens try: if change_windows_codepage: salt.utils.win_chcp.set_codepage_id(windows_codepage) try: proc = salt.utils.timed_subprocess.TimedProc(cmd, **new_kwargs) except OSError as exc: msg = "Unable to run command '{}' with the context '{}', reason: {}".format( cmd if output_loglevel is not None else "REDACTED", new_kwargs, exc, ) raise CommandExecutionError(msg) try: proc.run() except TimedProcTimeoutError as exc: ret["stdout"] = str(exc) ret["stderr"] = "" ret["retcode"] = None ret["pid"] = proc.process.pid # ok return code for timeouts? ret["retcode"] = 1 return ret finally: if change_windows_codepage: salt.utils.win_chcp.set_codepage_id(previous_windows_codepage) if output_loglevel != "quiet" and output_encoding is not None: log.debug( "Decoding output from command %s using %s encoding", cmd, output_encoding, ) try: out = salt.utils.stringutils.to_unicode( proc.stdout, encoding=output_encoding ) except TypeError: # stdout is None out = "" except UnicodeDecodeError: out = salt.utils.stringutils.to_unicode( proc.stdout, encoding=output_encoding, errors="replace" ) if output_loglevel != "quiet": log.error( "Failed to decode stdout from command %s, non-decodable " "characters have been replaced", _log_cmd(cmd), ) try: err = salt.utils.stringutils.to_unicode( proc.stderr, encoding=output_encoding ) except TypeError: # stderr is None err = "" except UnicodeDecodeError: err = salt.utils.stringutils.to_unicode( proc.stderr, encoding=output_encoding, errors="replace" ) if output_loglevel != "quiet": log.error( "Failed to decode stderr from command %s, non-decodable " "characters have been replaced", _log_cmd(cmd), ) if rstrip: if out is not None: out = out.rstrip() if err is not None: err = err.rstrip() ret["pid"] = proc.process.pid ret["retcode"] = proc.process.returncode if ret["retcode"] in success_retcodes: ret["retcode"] = 0 ret["stdout"] = out ret["stderr"] = err if any( [stdo in ret["stdout"] for stdo in success_stdout] + [stde in ret["stderr"] for stde in success_stderr] ): ret["retcode"] = 0 else: formatted_timeout = "" if timeout: formatted_timeout = " (timeout: {}s)".format(timeout) if output_loglevel is not None: msg = "Running {} in VT{}".format(cmd, formatted_timeout) log.debug(log_callback(msg)) stdout, stderr = "", "" now = time.time() if timeout: will_timeout = now + timeout else: will_timeout = -1 try: proc = salt.utils.vt.Terminal( cmd, shell=True, log_stdout=True, log_stderr=True, cwd=cwd, preexec_fn=new_kwargs.get("preexec_fn", None), env=run_env, log_stdin_level=output_loglevel, log_stdout_level=output_loglevel, log_stderr_level=output_loglevel, stream_stdout=True, stream_stderr=True, ) ret["pid"] = proc.pid stdout = "" stderr = "" while proc.has_unread_data: try: try: time.sleep(0.5) try: cstdout, cstderr = proc.recv() except OSError: cstdout, cstderr = "", "" if cstdout: stdout += cstdout if cstderr: stderr += cstderr if timeout and (time.time() > will_timeout): ret["stderr"] = "SALT: Timeout after {}s\n{}".format( timeout, stderr ) ret["retcode"] = None break except KeyboardInterrupt: ret["stderr"] = "SALT: User break\n{}".format(stderr) ret["retcode"] = 1 break except salt.utils.vt.TerminalException as exc: log.error("VT: %s", exc, exc_info_on_loglevel=logging.DEBUG) ret = {"retcode": 1, "pid": "2"} break # only set stdout on success as we already mangled in other # cases ret["stdout"] = stdout if not proc.isalive(): # Process terminated, i.e., not canceled by the user or by # the timeout ret["stderr"] = stderr ret["retcode"] = proc.exitstatus if ret["retcode"] in success_retcodes: ret["retcode"] = 0 if any( [stdo in ret["stdout"] for stdo in success_stdout] + [stde in ret["stderr"] for stde in success_stderr] ): ret["retcode"] = 0 ret["pid"] = proc.pid finally: proc.close(terminate=True, kill=True) try: if ignore_retcode: __context__["retcode"] = 0 else: __context__["retcode"] = ret["retcode"] except NameError: # Ignore the context error during grain generation pass # Log the output if output_loglevel is not None: if not ignore_retcode and ret["retcode"] != 0: if output_loglevel < LOG_LEVELS["error"]: output_loglevel = LOG_LEVELS["error"] msg = "Command '{}' failed with return code: {}".format( _log_cmd(cmd), ret["retcode"] ) log.error(log_callback(msg)) if ret["stdout"]: log.log(output_loglevel, "stdout: %s", log_callback(ret["stdout"])) if ret["stderr"]: log.log(output_loglevel, "stderr: %s", log_callback(ret["stderr"])) if ret["retcode"]: log.log(output_loglevel, "retcode: %s", ret["retcode"]) return ret def _run_quiet( cmd, cwd=None, stdin=None, output_encoding=None, runas=None, shell=DEFAULT_SHELL, python_shell=False, env=None, template=None, umask=None, timeout=None, reset_system_locale=True, saltenv=None, pillarenv=None, pillar_override=None, success_retcodes=None, success_stdout=None, success_stderr=None, ignore_retcode=None, ): """ Helper for running commands quietly for minion startup """ return _run( cmd, runas=runas, cwd=cwd, stdin=stdin, stderr=subprocess.STDOUT, output_encoding=output_encoding, output_loglevel="quiet", log_callback=None, shell=shell, python_shell=python_shell, env=env, template=template, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, pillarenv=pillarenv, pillar_override=pillar_override, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, ignore_retcode=ignore_retcode, )["stdout"] def _run_all_quiet( cmd, cwd=None, stdin=None, runas=None, shell=DEFAULT_SHELL, python_shell=False, env=None, template=None, umask=None, timeout=None, reset_system_locale=True, saltenv=None, pillarenv=None, pillar_override=None, output_encoding=None, success_retcodes=None, success_stdout=None, success_stderr=None, ignore_retcode=None, ): """ Helper for running commands quietly for minion startup. Returns a dict of return data. output_loglevel argument is ignored. This is here for when we alias cmd.run_all directly to _run_all_quiet in certain chicken-and-egg situations where modules need to work both before and after the __salt__ dictionary is populated (cf dracr.py) """ return _run( cmd, runas=runas, cwd=cwd, stdin=stdin, shell=shell, python_shell=python_shell, env=env, output_encoding=output_encoding, output_loglevel="quiet", log_callback=None, template=template, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, pillarenv=pillarenv, pillar_override=pillar_override, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, ignore_retcode=ignore_retcode, ) def run( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, bg=False, password=None, encoded_cmd=False, raise_err=False, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): r""" Execute the passed command and return the output as a string :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. .. warning:: For versions 2018.3.3 and above on macosx while using runas, on linux while using run, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.run 'echo '\''h=\"baz\"'\''' runas=macuser :param str group: Group to run command as. Not currently supported on Windows. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If ``False``, let python handle the positional arguments. Set to ``True`` to use shell features, such as pipes or redirection. :param bool bg: If ``True``, run command in background and do not await or deliver its results .. versionadded:: 2016.3.0 :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param bool encoded_cmd: Specify if the supplied command is encoded. Only applies to shell 'powershell' and 'pwsh'. .. versionadded:: 2018.3.0 Older versions of powershell seem to return raw xml data in the return. To avoid raw xml data in the return, prepend your command with the following before encoding: `$ProgressPreference='SilentlyContinue'; <your command>` The following powershell code block will encode the `Write-Output` command so that it will not have the raw xml data in the return: .. code-block:: powershell # target string $Command = '$ProgressPreference="SilentlyContinue"; Write-Output "hello"' # Convert to Base64 encoded string $Encoded = [convert]::ToBase64String([System.Text.encoding]::Unicode.GetBytes($command)) Write-Output $Encoded :param bool raise_err: If ``True`` and the command has a nonzero exit code, a CommandExecutionError exception will be raised. .. warning:: This function does not process commands through a shell unless the python_shell flag is set to True. This means that any shell-specific functionality such as 'echo' or the use of pipes, redirection or &&, should either be migrated to cmd.shell or have the python_shell=True flag set here. The use of python_shell=True means that the shell will accept _any_ input including potentially malicious commands such as 'good_command;rm -rf /'. Be absolutely certain that you have sanitized your input prior to using python_shell=True :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 :param int windows_codepage: 65001 Only applies to Windows: the minion uses `C:\Windows\System32\chcp.com` to verify or set the code page before the command `cmd` is executed. Code page 65001 corresponds with UTF-8 and allows international localization of Windows. .. versionadded:: 3002 CLI Example: .. code-block:: bash salt '*' cmd.run "ls -l | awk '/foo/{print \\$2}'" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.run template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" Specify an alternate shell with the shell parameter: .. code-block:: bash salt '*' cmd.run "Get-ChildItem C:\\ " shell='powershell' A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.run "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' If an equal sign (``=``) appears in an argument to a Salt command it is interpreted as a keyword argument in the format ``key=val``. That processing can be bypassed in order to pass an equal sign through to the remote shell command by manually specifying the kwarg: .. code-block:: bash salt '*' cmd.run cmd='sed -e s/=/:/g' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) ret = _run( cmd, runas=runas, group=group, shell=shell, python_shell=python_shell, cwd=cwd, stdin=stdin, stderr=subprocess.STDOUT, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, bg=bg, password=password, encoded_cmd=encoded_cmd, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) log_callback = _check_cb(log_callback) lvl = _check_loglevel(output_loglevel) if lvl is not None: if not ignore_retcode and ret["retcode"] != 0: if lvl < LOG_LEVELS["error"]: lvl = LOG_LEVELS["error"] msg = "Command '{}' failed with return code: {}".format( _log_cmd(cmd), ret["retcode"] ) log.error(log_callback(msg)) if raise_err: raise CommandExecutionError( log_callback(ret["stdout"] if not hide_output else "") ) log.log(lvl, "output: %s", log_callback(ret["stdout"])) return ret["stdout"] if not hide_output else "" def shell( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, bg=False, password=None, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute the passed command and return the output as a string. .. versionadded:: 2015.5.0 :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.shell 'echo '\\''h=\\"baz\\"'\\''' runas=macuser :param str group: Group to run command as. Not currently supported on Windows. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param int shell: Shell to execute under. Defaults to the system default shell. :param bool bg: If True, run command in background and do not await or deliver its results :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.shell 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. .. warning:: This passes the cmd argument directly to the shell without any further processing! Be absolutely sure that you have properly sanitized the command passed to this function and do not use untrusted inputs. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.shell "ls -l | awk '/foo/{print \\$2}'" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.shell template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" Specify an alternate shell with the shell parameter: .. code-block:: bash salt '*' cmd.shell "Get-ChildItem C:\\ " shell='powershell' A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.shell "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' If an equal sign (``=``) appears in an argument to a Salt command it is interpreted as a keyword argument in the format ``key=val``. That processing can be bypassed in order to pass an equal sign through to the remote shell command by manually specifying the kwarg: .. code-block:: bash salt '*' cmd.shell cmd='sed -e s/=/:/g' """ if "python_shell" in kwargs: python_shell = kwargs.pop("python_shell") else: python_shell = True return run( cmd, cwd=cwd, stdin=stdin, runas=runas, group=group, shell=shell, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, hide_output=hide_output, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, python_shell=python_shell, bg=bg, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) def run_stdout( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute a command, and only return the standard out :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.run_stdout 'echo '\\''h=\\"baz\\"'\\''' runas=macuser :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run_stdout 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.run_stdout "ls -l | awk '/foo/{print \\$2}'" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.run_stdout template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.run_stdout "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) ret = _run( cmd, runas=runas, group=group, cwd=cwd, stdin=stdin, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) return ret["stdout"] if not hide_output else "" def run_stderr( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute a command and only return the standard error :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.run_stderr 'echo '\\''h=\\"baz\\"'\\''' runas=macuser :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run_stderr 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.run_stderr "ls -l | awk '/foo/{print \\$2}'" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.run_stderr template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.run_stderr "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) ret = _run( cmd, runas=runas, group=group, cwd=cwd, stdin=stdin, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, use_vt=use_vt, saltenv=saltenv, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) return ret["stderr"] if not hide_output else "" def run_all( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, redirect_stderr=False, password=None, encoded_cmd=False, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute the passed command and return a dict of return data :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.run_all 'echo '\\''h=\\"baz\\"'\\''' runas=macuser :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run_all 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param bool encoded_cmd: Specify if the supplied command is encoded. Only applies to shell 'powershell' and 'pwsh'. .. versionadded:: 2018.3.0 Older versions of powershell seem to return raw xml data in the return. To avoid raw xml data in the return, prepend your command with the following before encoding: `$ProgressPreference='SilentlyContinue'; <your command>` The following powershell code block will encode the `Write-Output` command so that it will not have the raw xml data in the return: .. code-block:: powershell # target string $Command = '$ProgressPreference="SilentlyContinue"; Write-Output "hello"' # Convert to Base64 encoded string $Encoded = [convert]::ToBase64String([System.Text.encoding]::Unicode.GetBytes($command)) Write-Output $Encoded :param bool redirect_stderr: If set to ``True``, then stderr will be redirected to stdout. This is helpful for cases where obtaining both the retcode and output is desired, but it is not desired to have the output separated into both stdout and stderr. .. versionadded:: 2015.8.2 :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param bool bg: If ``True``, run command in background and do not await or deliver its results .. versionadded:: 2016.3.6 :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.run_all "ls -l | awk '/foo/{print \\$2}'" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.run_all template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.run_all "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) stderr = subprocess.STDOUT if redirect_stderr else subprocess.PIPE ret = _run( cmd, runas=runas, group=group, cwd=cwd, stdin=stdin, stderr=stderr, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, password=password, encoded_cmd=encoded_cmd, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) if hide_output: ret["stdout"] = ret["stderr"] = "" return ret def retcode( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute a shell command and return the command's return code. :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.retcode 'echo '\\''h=\\"baz\\"'\\''' runas=macuser :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run command as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.retcode 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :rtype: int :rtype: None :returns: Return Code as an int or None if there was an exception. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.retcode "file /bin/bash" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.retcode template=jinja "file {{grains.pythonpath[0]}}/python" A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.retcode "grep f" stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) ret = _run( cmd, runas=runas, group=group, cwd=cwd, stdin=stdin, stderr=subprocess.STDOUT, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, template=template, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) return ret["retcode"] def _retcode_quiet( cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=False, env=None, clean_env=False, template=None, umask=None, output_encoding=None, log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Helper for running commands quietly for minion startup. Returns same as the retcode() function. """ return retcode( cmd, cwd=cwd, stdin=stdin, runas=runas, group=group, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, template=template, umask=umask, output_encoding=output_encoding, output_loglevel="quiet", log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) def script( source, args=None, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, template=None, umask=None, output_encoding=None, output_loglevel="debug", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, saltenv=None, use_vt=False, bg=False, password=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. The script will be executed directly, so it can be written in any available programming language. :param str source: The location of the script to download. If the file is located on the master in the directory named spam, and is called eggs, the source string is salt://spam/eggs :param str args: String of command line args to pass to the script. Only used if no args are specified as part of the `name` argument. To pass a string containing spaces in YAML, you will need to doubly-quote it: .. code-block:: bash salt myminion cmd.script salt://foo.sh "arg1 'arg two' arg3" :param str cwd: The directory from which to execute the command. Defaults to the directory returned from Python's tempfile.mkstemp. :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. note:: For Window's users, specifically Server users, it may be necessary to specify your runas user using the User Logon Name instead of the legacy logon name. Traditionally, logons would be in the following format. ``Domain/user`` In the event this causes issues when executing scripts, use the UPN format which looks like the following. ``user@domain.local`` More information <https://github.com/saltstack/salt/issues/55080> :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run script as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param bool bg: If True, run script in background and do not await or deliver its results :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.script 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: If the command has not terminated after timeout seconds, send the subprocess sigterm, and if sigterm is ignored, follow up with sigkill :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.script salt://scripts/runme.sh salt '*' cmd.script salt://scripts/runme.sh 'arg1 arg2 "arg 3"' salt '*' cmd.script salt://scripts/windows_task.ps1 args=' -Input c:\\tmp\\infile.txt' shell='powershell' .. code-block:: bash salt '*' cmd.script salt://scripts/runme.sh stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ if saltenv is None: try: saltenv = __opts__.get("saltenv", "base") except NameError: saltenv = "base" python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) def _cleanup_tempfile(path): try: __salt__["file.remove"](path) except (SaltInvocationError, CommandExecutionError) as exc: log.error( "cmd.script: Unable to clean tempfile '%s': %s", path, exc, exc_info_on_loglevel=logging.DEBUG, ) if "__env__" in kwargs: # "env" is not supported; Use "saltenv". kwargs.pop("__env__") win_cwd = False if salt.utils.platform.is_windows() and runas and cwd is None: # Create a temp working directory cwd = tempfile.mkdtemp(dir=__opts__["cachedir"]) win_cwd = True salt.utils.win_dacl.set_permissions( obj_name=cwd, principal=runas, permissions="full_control" ) path = salt.utils.files.mkstemp( dir=cwd, suffix=os.path.splitext(salt.utils.url.split_env(source)[0])[1] ) if template: if "pillarenv" in kwargs or "pillar" in kwargs: pillarenv = kwargs.get("pillarenv", __opts__.get("pillarenv")) kwargs["pillar"] = _gather_pillar(pillarenv, kwargs.get("pillar")) fn_ = __salt__["cp.get_template"](source, path, template, saltenv, **kwargs) if not fn_: _cleanup_tempfile(path) # If a temp working directory was created (Windows), let's remove that if win_cwd: _cleanup_tempfile(cwd) return { "pid": 0, "retcode": 1, "stdout": "", "stderr": "", "cache_error": True, } else: fn_ = __salt__["cp.cache_file"](source, saltenv) if not fn_: _cleanup_tempfile(path) # If a temp working directory was created (Windows), let's remove that if win_cwd: _cleanup_tempfile(cwd) return { "pid": 0, "retcode": 1, "stdout": "", "stderr": "", "cache_error": True, } shutil.copyfile(fn_, path) if not salt.utils.platform.is_windows(): os.chmod(path, 320) os.chown(path, __salt__["file.user_to_uid"](runas), -1) if salt.utils.platform.is_windows() and shell.lower() != "powershell": cmd_path = _cmd_quote(path, escape=False) else: cmd_path = _cmd_quote(path) ret = _run( cmd_path + " " + str(args) if args else cmd_path, cwd=cwd, stdin=stdin, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, runas=runas, group=group, shell=shell, python_shell=python_shell, env=env, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, use_vt=use_vt, bg=bg, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) _cleanup_tempfile(path) # If a temp working directory was created (Windows), let's remove that if win_cwd: _cleanup_tempfile(cwd) if hide_output: ret["stdout"] = ret["stderr"] = "" return ret def script_retcode( source, args=None, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, template="jinja", umask=None, timeout=None, reset_system_locale=True, saltenv=None, output_encoding=None, output_loglevel="debug", log_callback=None, use_vt=False, password=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. The script will be executed directly, so it can be written in any available programming language. The script can also be formatted as a template, the default is jinja. Only evaluate the script return code and do not block for terminal output :param str source: The location of the script to download. If the file is located on the master in the directory named spam, and is called eggs, the source string is salt://spam/eggs :param str args: String of command line args to pass to the script. Only used if no args are specified as part of the `name` argument. To pass a string containing spaces in YAML, you will need to doubly-quote it: "arg1 'arg two' arg3" :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str group: Group to run script as. Not currently supported on Windows. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.script_retcode 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param int timeout: If the command has not terminated after timeout seconds, send the subprocess sigterm, and if sigterm is ignored, follow up with sigkill :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.script_retcode salt://scripts/runme.sh salt '*' cmd.script_retcode salt://scripts/runme.sh 'arg1 arg2 "arg 3"' salt '*' cmd.script_retcode salt://scripts/windows_task.ps1 args=' -Input c:\\tmp\\infile.txt' shell='powershell' A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. .. code-block:: bash salt '*' cmd.script_retcode salt://scripts/runme.sh stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' """ if "__env__" in kwargs: # "env" is not supported; Use "saltenv". kwargs.pop("__env__") return script( source=source, args=args, cwd=cwd, stdin=stdin, runas=runas, group=group, shell=shell, python_shell=python_shell, env=env, template=template, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, use_vt=use_vt, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs )["retcode"] def which(cmd): """ Returns the path of an executable available on the minion, None otherwise CLI Example: .. code-block:: bash salt '*' cmd.which cat """ return salt.utils.path.which(cmd) def which_bin(cmds): """ Returns the first command found in a list of commands CLI Example: .. code-block:: bash salt '*' cmd.which_bin '[pip2, pip, pip-python]' """ return salt.utils.path.which_bin(cmds) def has_exec(cmd): """ Returns true if the executable is available on the minion, false otherwise CLI Example: .. code-block:: bash salt '*' cmd.has_exec cat """ return which(cmd) is not None def exec_code(lang, code, cwd=None, args=None, **kwargs): """ Pass in two strings, the first naming the executable language, aka - python2, python3, ruby, perl, lua, etc. the second string containing the code you wish to execute. The stdout will be returned. All parameters from :mod:`cmd.run_all <salt.modules.cmdmod.run_all>` except python_shell can be used. CLI Example: .. code-block:: bash salt '*' cmd.exec_code ruby 'puts "cheese"' salt '*' cmd.exec_code ruby 'puts "cheese"' args='["arg1", "arg2"]' env='{"FOO": "bar"}' """ return exec_code_all(lang, code, cwd, args, **kwargs)["stdout"] def exec_code_all(lang, code, cwd=None, args=None, **kwargs): """ Pass in two strings, the first naming the executable language, aka - python2, python3, ruby, perl, lua, etc. the second string containing the code you wish to execute. All cmd artifacts (stdout, stderr, retcode, pid) will be returned. All parameters from :mod:`cmd.run_all <salt.modules.cmdmod.run_all>` except python_shell can be used. CLI Example: .. code-block:: bash salt '*' cmd.exec_code_all ruby 'puts "cheese"' salt '*' cmd.exec_code_all ruby 'puts "cheese"' args='["arg1", "arg2"]' env='{"FOO": "bar"}' """ powershell = lang.lower().startswith("powershell") if powershell: codefile = salt.utils.files.mkstemp(suffix=".ps1") else: codefile = salt.utils.files.mkstemp() with salt.utils.files.fopen(codefile, "w+t", binary=False) as fp_: fp_.write(salt.utils.stringutils.to_str(code)) if powershell: cmd = [lang, "-File", codefile] else: cmd = [lang, codefile] if isinstance(args, str): cmd.append(args) elif isinstance(args, list): cmd += args def _cleanup_tempfile(path): try: __salt__["file.remove"](path) except (SaltInvocationError, CommandExecutionError) as exc: log.error( "cmd.exec_code_all: Unable to clean tempfile '%s': %s", path, exc, exc_info_on_loglevel=logging.DEBUG, ) runas = kwargs.get("runas") if runas is not None: if not salt.utils.platform.is_windows(): os.chown(codefile, __salt__["file.user_to_uid"](runas), -1) ret = run_all(cmd, cwd=cwd, python_shell=False, **kwargs) _cleanup_tempfile(codefile) return ret def tty(device, echo=""): """ Echo a string to a specific tty CLI Example: .. code-block:: bash salt '*' cmd.tty tty0 'This is a test' salt '*' cmd.tty pts3 'This is a test' """ if device.startswith("tty"): teletype = "/dev/{}".format(device) elif device.startswith("pts"): teletype = "/dev/{}".format(device.replace("pts", "pts/")) else: return {"Error": "The specified device is not a valid TTY"} try: with salt.utils.files.fopen(teletype, "wb") as tty_device: tty_device.write(salt.utils.stringutils.to_bytes(echo)) return {"Success": "Message was successfully echoed to {}".format(teletype)} except OSError: return {"Error": "Echoing to {} returned error".format(teletype)} def run_chroot( root, cmd, cwd=None, stdin=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=True, binds=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="quiet", log_callback=None, hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, bg=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ .. versionadded:: 2014.7.0 This function runs :mod:`cmd.run_all <salt.modules.cmdmod.run_all>` wrapped within a chroot, with dev and proc mounted in the chroot :param str root: Path to the root of the jail to use. :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input.: :param str runas: User to run script as. :param str group: Group to run script as. :param str shell: Shell to execute under. Defaults to the system default shell. :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :parar str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param list binds: List of directories that will be exported inside the chroot with the bind option. .. versionadded:: 3000 :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run_chroot 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param dict clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 CLI Example: .. code-block:: bash salt '*' cmd.run_chroot /var/lib/lxc/container_name/rootfs 'sh /tmp/bootstrap.sh' """ __salt__["mount.mount"](os.path.join(root, "dev"), "devtmpfs", fstype="devtmpfs") __salt__["mount.mount"](os.path.join(root, "proc"), "proc", fstype="proc") __salt__["mount.mount"](os.path.join(root, "sys"), "sysfs", fstype="sysfs") binds = binds if binds else [] for bind_exported in binds: bind_exported_to = os.path.relpath(bind_exported, os.path.sep) bind_exported_to = os.path.join(root, bind_exported_to) __salt__["mount.mount"](bind_exported_to, bind_exported, opts="default,bind") # Execute chroot routine sh_ = "/bin/sh" if os.path.isfile(os.path.join(root, "bin/bash")): sh_ = "/bin/bash" if isinstance(cmd, (list, tuple)): cmd = " ".join([str(i) for i in cmd]) # If runas and group are provided, we expect that the user lives # inside the chroot, not outside. if runas: userspec = "--userspec {}:{}".format(runas, group if group else "") else: userspec = "" cmd = "chroot {} {} {} -c {}".format(userspec, root, sh_, _cmd_quote(cmd)) run_func = __context__.pop("cmd.run_chroot.func", run_all) ret = run_func( cmd, cwd=cwd, stdin=stdin, shell=shell, python_shell=python_shell, env=env, clean_env=clean_env, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, pillarenv=kwargs.get("pillarenv"), pillar=kwargs.get("pillar"), use_vt=use_vt, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, bg=bg, ) # Kill processes running in the chroot for i in range(6): pids = _chroot_pids(root) if not pids: break for pid in pids: # use sig 15 (TERM) for first 3 attempts, then 9 (KILL) sig = 15 if i < 3 else 9 os.kill(pid, sig) if _chroot_pids(root): log.error( "Processes running in chroot could not be killed, " "filesystem will remain mounted" ) for bind_exported in binds: bind_exported_to = os.path.relpath(bind_exported, os.path.sep) bind_exported_to = os.path.join(root, bind_exported_to) __salt__["mount.umount"](bind_exported_to) __salt__["mount.umount"](os.path.join(root, "sys")) __salt__["mount.umount"](os.path.join(root, "proc")) __salt__["mount.umount"](os.path.join(root, "dev")) if hide_output: ret["stdout"] = ret["stderr"] = "" return ret def _is_valid_shell(shell): """ Attempts to search for valid shells on a system and see if a given shell is in the list """ if salt.utils.platform.is_windows(): return True # Don't even try this for Windows shells = "/etc/shells" available_shells = [] if os.path.exists(shells): try: with salt.utils.files.fopen(shells, "r") as shell_fp: lines = [ salt.utils.stringutils.to_unicode(x) for x in shell_fp.read().splitlines() ] for line in lines: if line.startswith("#"): continue else: available_shells.append(line) except OSError: return True else: # No known method of determining available shells return None if shell in available_shells: return True else: return False def shells(): """ Lists the valid shells on this system via the /etc/shells file .. versionadded:: 2015.5.0 CLI Example: .. code-block:: bash salt '*' cmd.shells """ shells_fn = "/etc/shells" ret = [] if os.path.exists(shells_fn): try: with salt.utils.files.fopen(shells_fn, "r") as shell_fp: lines = [ salt.utils.stringutils.to_unicode(x) for x in shell_fp.read().splitlines() ] for line in lines: line = line.strip() if line.startswith("#"): continue elif not line: continue else: ret.append(line) except OSError: log.error("File '%s' was not found", shells_fn) return ret def shell_info(shell, list_modules=False): """ .. versionadded:: 2016.11.0 Provides information about a shell or script languages which often use ``#!``. The values returned are dependent on the shell or scripting languages all return the ``installed``, ``path``, ``version``, ``version_raw`` Args: shell (str): Name of the shell. Support shells/script languages include bash, cmd, perl, php, powershell, python, ruby and zsh list_modules (bool): True to list modules available to the shell. Currently only lists powershell modules. Returns: dict: A dictionary of information about the shell .. code-block:: python {'version': '<2 or 3 numeric components dot-separated>', 'version_raw': '<full version string>', 'path': '<full path to binary>', 'installed': <True, False or None>, '<attribute>': '<attribute value>'} .. note:: - ``installed`` is always returned, if ``None`` or ``False`` also returns error and may also return ``stdout`` for diagnostics. - ``version`` is for use in determine if a shell/script language has a particular feature set, not for package management. - The shell must be within the executable search path. CLI Example: .. code-block:: bash salt '*' cmd.shell_info bash salt '*' cmd.shell_info powershell :codeauthor: Damon Atkins <https://github.com/damon-atkins> """ regex_shells = { "bash": [r"version (\d\S*)", "bash", "--version"], "bash-test-error": [ r"versioZ ([-\w.]+)", "bash", "--version", ], # used to test an error result "bash-test-env": [ r"(HOME=.*)", "bash", "-c", "declare", ], # used to test an error result "zsh": [r"^zsh (\d\S*)", "zsh", "--version"], "tcsh": [r"^tcsh (\d\S*)", "tcsh", "--version"], "cmd": [r"Version ([\d.]+)", "cmd.exe", "/C", "ver"], "powershell": [ r"PSVersion\s+(\d\S*)", "powershell", "-NonInteractive", "$PSVersionTable", ], "perl": [r"^(\d\S*)", "perl", "-e", 'printf "%vd\n", $^V;'], "python": [r"^Python (\d\S*)", "python", "-V"], "ruby": [r"^ruby (\d\S*)", "ruby", "-v"], "php": [r"^PHP (\d\S*)", "php", "-v"], } # Ensure ret['installed'] always as a value of True, False or None (not sure) ret = {"installed": False} if salt.utils.platform.is_windows() and shell == "powershell": pw_keys = salt.utils.win_reg.list_keys( hive="HKEY_LOCAL_MACHINE", key="Software\\Microsoft\\PowerShell" ) pw_keys.sort(key=int) if not pw_keys: return { "error": ( "Unable to locate 'powershell' Reason: Cannot be found in registry." ), "installed": False, } for reg_ver in pw_keys: install_data = salt.utils.win_reg.read_value( hive="HKEY_LOCAL_MACHINE", key="Software\\Microsoft\\PowerShell\\{}".format(reg_ver), vname="Install", ) if ( install_data.get("vtype") == "REG_DWORD" and install_data.get("vdata") == 1 ): details = salt.utils.win_reg.list_values( hive="HKEY_LOCAL_MACHINE", key="Software\\Microsoft\\PowerShell\\{}\\PowerShellEngine".format( reg_ver ), ) # reset data, want the newest version details only as powershell # is backwards compatible ret = {} # if all goes well this will become True ret["installed"] = None ret["path"] = which("powershell.exe") for attribute in details: if attribute["vname"].lower() == "(default)": continue elif attribute["vname"].lower() == "powershellversion": ret["psversion"] = attribute["vdata"] ret["version_raw"] = attribute["vdata"] elif attribute["vname"].lower() == "runtimeversion": ret["crlversion"] = attribute["vdata"] if ret["crlversion"][0].lower() == "v": ret["crlversion"] = ret["crlversion"][1::] elif attribute["vname"].lower() == "pscompatibleversion": # reg attribute does not end in s, the powershell # attribute does ret["pscompatibleversions"] = ( attribute["vdata"].replace(" ", "").split(",") ) else: # keys are lower case as python is case sensitive the # registry is not ret[attribute["vname"].lower()] = attribute["vdata"] else: if shell not in regex_shells: return { "error": ( "Salt does not know how to get the version number for {}".format( shell ) ), "installed": None, } shell_data = regex_shells[shell] pattern = shell_data.pop(0) # We need to make sure HOME set, so shells work correctly # salt-call will general have home set, the salt-minion service may not # We need to assume ports of unix shells to windows will look after # themselves in setting HOME as they do it in many different ways if salt.utils.platform.is_windows(): import nt newenv = nt.environ else: newenv = os.environ if ("HOME" not in newenv) and (not salt.utils.platform.is_windows()): newenv["HOME"] = os.path.expanduser("~") log.debug("HOME environment set to %s", newenv["HOME"]) try: proc = salt.utils.timed_subprocess.TimedProc( shell_data, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=10, env=newenv, ) except OSError as exc: return { "error": "Unable to run command '{}' Reason: {}".format( " ".join(shell_data), exc ), "installed": False, } try: proc.run() except TimedProcTimeoutError as exc: return { "error": "Unable to run command '{}' Reason: Timed out.".format( " ".join(shell_data) ), "installed": False, } ret["path"] = which(shell_data[0]) pattern_result = re.search(pattern, proc.stdout, flags=re.IGNORECASE) # only set version if we find it, so code later on can deal with it if pattern_result: ret["version_raw"] = pattern_result.group(1) if "version_raw" in ret: version_results = re.match(r"(\d[\d.]*)", ret["version_raw"]) if version_results: ret["installed"] = True ver_list = version_results.group(1).split(".")[:3] if len(ver_list) == 1: ver_list.append("0") ret["version"] = ".".join(ver_list[:3]) else: ret["installed"] = None # Have an unexpected result # Get a list of the PowerShell modules which are potentially available # to be imported if shell == "powershell" and ret["installed"] and list_modules: ret["modules"] = salt.utils.powershell.get_modules() if "version" not in ret: ret["error"] = ( "The version regex pattern for shell {}, could not " "find the version string".format(shell) ) ret["stdout"] = proc.stdout # include stdout so they can see the issue log.error(ret["error"]) return ret def powershell( cmd, cwd=None, stdin=None, runas=None, shell="powershell", env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", hide_output=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, depth=None, encode_cmd=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute the passed PowerShell command and return the output as a dictionary. Other ``cmd.*`` functions (besides ``cmd.powershell_all``) return the raw text output of the command. This function appends ``| ConvertTo-JSON`` to the command and then parses the JSON into a Python dictionary. If you want the raw textual result of your PowerShell command you should use ``cmd.run`` with the ``shell=powershell`` option. For example: .. code-block:: bash salt '*' cmd.run '$PSVersionTable.CLRVersion' shell=powershell salt '*' cmd.run 'Get-NetTCPConnection' shell=powershell .. versionadded:: 2016.3.0 .. warning:: This passes the cmd argument directly to PowerShell without any further processing! Be absolutely sure that you have properly sanitized the command passed to this function and do not use untrusted inputs. In addition to the normal ``cmd.run`` parameters, this command offers the ``depth`` parameter to change the Windows default depth for the ``ConvertTo-JSON`` powershell command. The Windows default is 2. If you need more depth, set that here. .. note:: For some commands, setting the depth to a value greater than 4 greatly increases the time it takes for the command to return and in many cases returns useless data. :param str cmd: The powershell command to run. :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str shell: Specify an alternate shell. Defaults to "powershell". Can also use "pwsh" for powershell core if present on the system :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.powershell 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param bool hide_output: If ``True``, suppress stdout and stderr in the return data. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param bool reset_system_locale: Resets the system locale :param str saltenv: The salt environment to use. Default is 'base' :param int depth: The number of levels of contained objects to be included. Default is 2. Values greater than 4 seem to greatly increase the time it takes for the command to complete for some commands. eg: ``dir`` .. versionadded:: 2016.3.4 :param bool encode_cmd: Encode the command before executing. Use in cases where characters may be dropped or incorrectly converted when executed. Default is False. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 :returns: :dict: A dictionary of data returned by the powershell command. CLI Example: .. code-block:: powershell salt '*' cmd.powershell "$PSVersionTable.CLRVersion" """ if shell not in ["powershell", "pwsh"]: raise CommandExecutionError( "Must specify a valid powershell binary. Must be 'powershell' or 'pwsh'" ) if "python_shell" in kwargs: python_shell = kwargs.pop("python_shell") else: python_shell = True # Append PowerShell Object formatting # ConvertTo-JSON is only available on PowerShell 3.0 and later psversion = shell_info("powershell")["psversion"] if salt.utils.versions.version_cmp(psversion, "2.0") == 1: cmd += " | ConvertTo-JSON" if depth is not None: cmd += " -Depth {}".format(depth) # Put the whole command inside a try / catch block # Some errors in PowerShell are not "Terminating Errors" and will not be # caught in a try/catch block. For example, the `Get-WmiObject` command will # often return a "Non Terminating Error". To fix this, make sure # `-ErrorAction Stop` is set in the powershell command cmd = "try {" + cmd + '} catch { "{}" }' if encode_cmd: # Convert the cmd to UTF-16LE without a BOM and base64 encode. # Just base64 encoding UTF-8 or including a BOM is not valid. log.debug("Encoding PowerShell command '%s'", cmd) cmd = "$ProgressPreference='SilentlyContinue'; {}".format(cmd) cmd_utf16 = cmd.encode("utf-16-le") cmd = base64.standard_b64encode(cmd_utf16) cmd = salt.utils.stringutils.to_str(cmd) encoded_cmd = True else: encoded_cmd = False # Retrieve the response, while overriding shell with 'powershell' response = run( cmd, cwd=cwd, stdin=stdin, runas=runas, shell=shell, env=env, clean_env=clean_env, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, hide_output=hide_output, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, python_shell=python_shell, password=password, encoded_cmd=encoded_cmd, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) # Sometimes Powershell returns an empty string, which isn't valid JSON if response == "": response = "{}" try: return salt.utils.json.loads(response) except Exception: # pylint: disable=broad-except log.error("Error converting PowerShell JSON return", exc_info=True) return {} def powershell_all( cmd, cwd=None, stdin=None, runas=None, shell="powershell", env=None, clean_env=False, template=None, rstrip=True, umask=None, output_encoding=None, output_loglevel="debug", quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, use_vt=False, password=None, depth=None, encode_cmd=False, force_list=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Execute the passed PowerShell command and return a dictionary with a result field representing the output of the command, as well as other fields showing us what the PowerShell invocation wrote to ``stderr``, the process id, and the exit code of the invocation. This function appends ``| ConvertTo-JSON`` to the command before actually invoking powershell. An unquoted empty string is not valid JSON, but it's very normal for the Powershell output to be exactly that. Therefore, we do not attempt to parse empty Powershell output (which would result in an exception). Instead we treat this as a special case and one of two things will happen: - If the value of the ``force_list`` parameter is ``True``, then the ``result`` field of the return dictionary will be an empty list. - If the value of the ``force_list`` parameter is ``False``, then the return dictionary **will not have a result key added to it**. We aren't setting ``result`` to ``None`` in this case, because ``None`` is the Python representation of "null" in JSON. (We likewise can't use ``False`` for the equivalent reason.) If Powershell's output is not an empty string and Python cannot parse its content, then a ``CommandExecutionError`` exception will be raised. If Powershell's output is not an empty string, Python is able to parse its content, and the type of the resulting Python object is other than ``list`` then one of two things will happen: - If the value of the ``force_list`` parameter is ``True``, then the ``result`` field will be a singleton list with the Python object as its sole member. - If the value of the ``force_list`` parameter is ``False``, then the value of ``result`` will be the unmodified Python object. If Powershell's output is not an empty string, Python is able to parse its content, and the type of the resulting Python object is ``list``, then the value of ``result`` will be the unmodified Python object. The ``force_list`` parameter has no effect in this case. .. note:: An example of why the ``force_list`` parameter is useful is as follows: The Powershell command ``dir x | Convert-ToJson`` results in - no output when x is an empty directory. - a dictionary object when x contains just one item. - a list of dictionary objects when x contains multiple items. By setting ``force_list`` to ``True`` we will always end up with a list of dictionary items, representing files, no matter how many files x contains. Conversely, if ``force_list`` is ``False``, we will end up with no ``result`` key in our return dictionary when x is an empty directory, and a dictionary object when x contains just one file. If you want a similar function but with a raw textual result instead of a Python dictionary, you should use ``cmd.run_all`` in combination with ``shell=powershell``. The remaining fields in the return dictionary are described in more detail in the ``Returns`` section. Example: .. code-block:: bash salt '*' cmd.run_all '$PSVersionTable.CLRVersion' shell=powershell salt '*' cmd.run_all 'Get-NetTCPConnection' shell=powershell .. versionadded:: 2018.3.0 .. warning:: This passes the cmd argument directly to PowerShell without any further processing! Be absolutely sure that you have properly sanitized the command passed to this function and do not use untrusted inputs. In addition to the normal ``cmd.run`` parameters, this command offers the ``depth`` parameter to change the Windows default depth for the ``ConvertTo-JSON`` powershell command. The Windows default is 2. If you need more depth, set that here. .. note:: For some commands, setting the depth to a value greater than 4 greatly increases the time it takes for the command to return and in many cases returns useless data. :param str cmd: The powershell command to run. :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str stdin: A string of standard input can be specified for the command to be run using the ``stdin`` parameter. This can be useful in cases where sensitive information must be read from standard input. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. :param str shell: Specify an alternate shell. Defaults to "powershell". Can also use "pwsh" for powershell core if present on the system :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.powershell_all 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param bool rstrip: Strip all whitespace off the end of output before it is returned. :param str umask: The umask (in octal) to use when running the command. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param int timeout: A timeout in seconds for the executed process to return. :param bool use_vt: Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. :param bool reset_system_locale: Resets the system locale :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param str saltenv: The salt environment to use. Default is 'base' :param int depth: The number of levels of contained objects to be included. Default is 2. Values greater than 4 seem to greatly increase the time it takes for the command to complete for some commands. eg: ``dir`` :param bool encode_cmd: Encode the command before executing. Use in cases where characters may be dropped or incorrectly converted when executed. Default is False. :param bool force_list: The purpose of this parameter is described in the preamble of this function's documentation. Default value is False. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 :return: A dictionary with the following entries: result For a complete description of this field, please refer to this function's preamble. **This key will not be added to the dictionary when force_list is False and Powershell's output is the empty string.** stderr What the PowerShell invocation wrote to ``stderr``. pid The process id of the PowerShell invocation retcode This is the exit code of the invocation of PowerShell. If the final execution status (in PowerShell) of our command (with ``| ConvertTo-JSON`` appended) is ``False`` this should be non-0. Likewise if PowerShell exited with ``$LASTEXITCODE`` set to some non-0 value, then ``retcode`` will end up with this value. :rtype: dict CLI Example: .. code-block:: bash salt '*' cmd.powershell_all "$PSVersionTable.CLRVersion" CLI Example: .. code-block:: bash salt '*' cmd.powershell_all "dir mydirectory" force_list=True """ if shell not in ["powershell", "pwsh"]: raise CommandExecutionError( "Must specify a valid powershell binary. Must be 'powershell' or 'pwsh'" ) if "python_shell" in kwargs: python_shell = kwargs.pop("python_shell") else: python_shell = True # Append PowerShell Object formatting cmd += " | ConvertTo-JSON" if depth is not None: cmd += " -Depth {}".format(depth) if encode_cmd: # Convert the cmd to UTF-16LE without a BOM and base64 encode. # Just base64 encoding UTF-8 or including a BOM is not valid. log.debug("Encoding PowerShell command '%s'", cmd) cmd = "$ProgressPreference='SilentlyContinue'; {}".format(cmd) cmd_utf16 = cmd.encode("utf-16-le") cmd = base64.standard_b64encode(cmd_utf16) cmd = salt.utils.stringutils.to_str(cmd) encoded_cmd = True else: encoded_cmd = False # Retrieve the response, while overriding shell with 'powershell' response = run_all( cmd, cwd=cwd, stdin=stdin, runas=runas, shell=shell, env=env, clean_env=clean_env, template=template, rstrip=rstrip, umask=umask, output_encoding=output_encoding, output_loglevel=output_loglevel, quiet=quiet, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, saltenv=saltenv, use_vt=use_vt, python_shell=python_shell, password=password, encoded_cmd=encoded_cmd, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) stdoutput = response["stdout"] # if stdoutput is the empty string and force_list is True we return an empty list # Otherwise we return response with no result key if not stdoutput: response.pop("stdout") if force_list: response["result"] = [] return response # If we fail to parse stdoutput we will raise an exception try: result = salt.utils.json.loads(stdoutput) except Exception: # pylint: disable=broad-except err_msg = "cmd.powershell_all " + "cannot parse the Powershell output." response["cmd"] = cmd raise CommandExecutionError(message=err_msg, info=response) response.pop("stdout") if type(result) is not list: if force_list: response["result"] = [result] else: response["result"] = result else: # result type is list so the force_list param has no effect response["result"] = result return response def run_bg( cmd, cwd=None, runas=None, group=None, shell=DEFAULT_SHELL, python_shell=None, env=None, clean_env=False, template=None, umask=None, timeout=None, output_encoding=None, output_loglevel="debug", log_callback=None, reset_system_locale=True, ignore_retcode=False, saltenv=None, password=None, prepend_path=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): r""" .. versionadded:: 2016.3.0 Execute the passed command in the background and return its PID .. note:: If the init system is systemd and the backgrounded task should run even if the salt-minion process is restarted, prepend ``systemd-run --scope`` to the command. This will reparent the process in its own scope separate from salt-minion, and will not be affected by restarting the minion service. :param str cmd: The command to run. ex: ``ls -lart /home`` :param str cwd: The directory from which to execute the command. Defaults to the home directory of the user specified by ``runas`` (or the user under which Salt is running if ``runas`` is not specified). :param str group: Group to run command as. Not currently supported on Windows. :param str shell: Shell to execute under. Defaults to the system default shell. :param str output_encoding: Control the encoding used to decode the command's output. .. note:: This should not need to be used in most cases. By default, Salt will try to use the encoding detected from the system locale, and will fall back to UTF-8 if this fails. This should only need to be used in cases where the output of the command is encoded in something other than the system locale or UTF-8. To see the encoding Salt has detected from the system locale, check the `locale` line in the output of :py:func:`test.versions_report <salt.modules.test.versions_report>`. .. versionadded:: 2018.3.0 :param str output_loglevel: Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. :param bool ignore_retcode: If the exit code of the command is nonzero, this is treated as an error condition, and the output from the command will be logged to the minion log. However, there are some cases where programs use the return code for signaling and a nonzero exit code doesn't necessarily mean failure. Pass this argument as ``True`` to skip logging the output if the command has a nonzero exit code. :param str runas: Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. warning:: For versions 2018.3.3 and above on macosx while using runas, to pass special characters to the command you need to escape the characters on the shell. Example: .. code-block:: bash cmd.run_bg 'echo '\''h=\"baz\"'\''' runas=macuser :param str password: Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. .. versionadded:: 2016.3.0 :param str shell: Specify an alternate shell. Defaults to the system's default shell. :param bool python_shell: If False, let python handle the positional arguments. Set to True to use shell features, such as pipes or redirection. :param dict env: Environment variables to be set prior to execution. .. note:: When passing environment variables on the CLI, they should be passed as the string representation of a dictionary. .. code-block:: bash salt myminion cmd.run_bg 'some command' env='{"FOO": "bar"}' .. note:: When using environment variables on Window's, case-sensitivity matters, i.e. Window's uses `Path` as opposed to `PATH` for other systems. :param bool clean_env: Attempt to clean out all other shell environment variables and set only those provided in the 'env' argument to this function. :param str prepend_path: $PATH segment to prepend (trailing ':' not necessary) to $PATH .. versionadded:: 2018.3.0 :param str template: If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported. :param str umask: The umask (in octal) to use when running the command. :param int timeout: A timeout in seconds for the executed process to return. .. warning:: This function does not process commands through a shell unless the ``python_shell`` argument is set to ``True``. This means that any shell-specific functionality such as 'echo' or the use of pipes, redirection or &&, should either be migrated to cmd.shell or have the python_shell=True flag set here. The use of ``python_shell=True`` means that the shell will accept _any_ input including potentially malicious commands such as 'good_command;rm -rf /'. Be absolutely certain that you have sanitized your input prior to using ``python_shell=True``. :param list success_retcodes: This parameter will allow a list of non-zero return codes that should be considered a success. If the return code returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 2019.2.0 :param list success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param list success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 :param bool stdin_raw_newlines: False If ``True``, Salt will not automatically convert the characters ``\\n`` present in the ``stdin`` value to newlines. .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' cmd.run_bg "fstrim-all" The template arg can be set to 'jinja' or another supported template engine to render the command arguments before execution. For example: .. code-block:: bash salt '*' cmd.run_bg template=jinja "ls -l /tmp/{{grains.id}} | awk '/foo/{print \\$2}'" Specify an alternate shell with the shell parameter: .. code-block:: bash salt '*' cmd.run_bg "Get-ChildItem C:\\ " shell='powershell' If an equal sign (``=``) appears in an argument to a Salt command it is interpreted as a keyword argument in the format ``key=val``. That processing can be bypassed in order to pass an equal sign through to the remote shell command by manually specifying the kwarg: .. code-block:: bash salt '*' cmd.run_bg cmd='ls -lR / | sed -e s/=/:/g > /tmp/dontwait' """ python_shell = _python_shell_default(python_shell, kwargs.get("__pub_jid", "")) res = _run( cmd, stdin=None, stderr=None, stdout=None, output_encoding=output_encoding, output_loglevel=output_loglevel, use_vt=None, bg=True, with_communicate=False, rstrip=False, runas=runas, group=group, shell=shell, python_shell=python_shell, cwd=cwd, env=env, clean_env=clean_env, prepend_path=prepend_path, template=template, umask=umask, log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, saltenv=saltenv, password=password, success_retcodes=success_retcodes, success_stdout=success_stdout, success_stderr=success_stderr, **kwargs ) return {"pid": res["pid"]}
Save