Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shell kwarg #13

Merged
merged 2 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/build_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Run Build Tests
on:
push:
branches:
- master
pull_request:
branches:
- dev
workflow_dispatch:

jobs:
build_tests:
strategy:
max-parallel: 2
matrix:
python-version: [3.8, 3.9, "3.10", "3.11" ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install Build Tools
run: |
python -m pip install build wheel
- name: Install System Dependencies
run: |
sudo apt-get update
sudo apt install python3-dev swig libssl-dev
- name: Build Source Packages
run: |
python setup.py sdist
- name: Build Distribution Packages
run: |
python setup.py bdist_wheel
- name: Install skill
run: |
pip install .
66 changes: 66 additions & 0 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Run UnitTests
on:
pull_request:
branches:
- dev
paths-ignore:
- 'version.py'
- 'examples/**'
- '.github/**'
- '.gitignore'
- 'LICENSE'
- 'CHANGELOG.md'
- 'MANIFEST.in'
- 'README.md'
- 'scripts/**'
push:
branches:
- master
paths-ignore:
- 'version.py'
- 'examples/**'
- '.github/**'
- '.gitignore'
- 'LICENSE'
- 'CHANGELOG.md'
- 'MANIFEST.in'
- 'README.md'
- 'scripts/**'
workflow_dispatch:

jobs:
unit_tests:
strategy:
matrix:
python-version: [3.9, "3.10" ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install System Dependencies
run: |
sudo apt-get update
sudo apt install python3-dev
python -m pip install build wheel
- name: Install core repo
run: |
pip install .
- name: Install test dependencies
run: |
pip install pytest pytest-timeout pytest-cov
- name: Install System Dependencies
run: |
sudo apt-get update
- name: Install ovos dependencies
run: |
pip install ovos-plugin-manager
- name: Run unittests
run: |
pytest --cov=ovos-skill-cmd --cov-report xml test
- name: Upload coverage
env:
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
uses: codecov/codecov-action@v2
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
recursive-include locale *
include *.txt
59 changes: 54 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# Commands Skill

A Simple OVOS skill for running shell scripts and other commands. The commands will run quietly without any confirmation from OVOS.
A simple OVOS skill for running shell scripts and other commands. The commands execute quietly without requiring confirmation from OVOS.

## Features

- Run shell scripts or commands by speaking human-readable phrases.
- Configure aliases for easy-to-remember commands.
- Optionally run commands under a specific user's privileges.

## Usage

*Hey Mycroft, launch command echo TEST*
Trigger commands using phrases like:

*Hey Mycroft, run script generate report*
- **"Hey Mycroft, launch command echo TEST"**
- **"Hey Mycroft, run script generate report"**

## Configuration

The skill can be configured to run scripts from easily pronounceable human utterances, such as "generate report" by adding the following to the skill `settings.json`
The skill can be configured to map spoken phrases to scripts or commands in the `settings.json` file. For example:

```json
{
Expand All @@ -20,4 +27,46 @@ The skill can be configured to run scripts from easily pronounceable human utter
}
```

The configuration above will launch `/home/forslund/scripts/generate_report.sh` when "run script generate report" is said by the user.
### Example:
- User says: **"Run script generate report"**
- The skill executes: `/home/forslund/scripts/generate_report.sh`

### Additional Settings:

- **`user`** *(optional)*: Specify a username to run commands under their privileges. Example:
```json
{
"user": "ovos"
}
```

- **`shell`** *(optional)*: Determines whether commands are executed via a shell. Defaults to `true`. Example:
```json
{
"shell": false
}
```

### Full Configuration Example:
```json
{
"user": "ovos",
"alias": {
"generate report": "/home/forslund/scripts/generate_report.sh",
"update system": "sudo apt update && sudo apt upgrade -y",
"reboot device": "sudo reboot"
},
"shell": true
}
```

## Security Notes

1. **Shell Commands**:
- By default, commands are executed via the shell, which allows complex operations but may expose security risks. If your commands don’t require shell features, set `shell` to `false`.

2. **User Permissions**:
- Commands can run under a specific user by configuring the `user` field. Ensure that the user has appropriate permissions to execute the commands.

3. **Validation**:
- Avoid configuring dangerous commands like `rm -rf` without additional safeguards.
9 changes: 5 additions & 4 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ def initialize(self):
def run(self, message):
script = message.data.get('Script')
script = self.alias.get(script, script)
args = script.split(' ')
shell = self.settings.get('shell', True)
args = script.split(' ') if shell else script
try:
LOG.info(f'Running {args}')
if self.uid and self.gid:
subprocess.Popen(args, preexec_fn=set_user(self.uid, self.gid))
subprocess.Popen(args, preexec_fn=set_user(self.uid, self.gid), shell=shell)
else:
LOG.info(f'Running {args}')
subprocess.Popen(args)
subprocess.Popen(args, shell=shell)
except Exception:
LOG.exception('Could not run script ' + script)
19 changes: 0 additions & 19 deletions scripts/bump_alpha.py

This file was deleted.

21 changes: 0 additions & 21 deletions scripts/bump_build.py

This file was deleted.

27 changes: 0 additions & 27 deletions scripts/bump_major.py

This file was deleted.

24 changes: 0 additions & 24 deletions scripts/bump_minor.py

This file was deleted.

53 changes: 0 additions & 53 deletions scripts/prepare_translations.py

This file was deleted.

13 changes: 0 additions & 13 deletions scripts/remove_alpha.py

This file was deleted.

4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# Define package information
SKILL_CLAZZ = "CmdSkill" # Make sure it matches __init__.py class name
URL = "https://github.com/OVOSHatchery/ovos-skill-cmd"
URL = "https://github.com/OpenVoiceOS/ovos-skill-cmd"
AUTHOR = "forslund"
EMAIL = ""
LICENSE = "Apache2.0"
Expand Down Expand Up @@ -37,7 +37,7 @@ def get_requirements(requirements_filename: str = "requirements.txt"):

# Function to find resource files
def find_resource_files():
resource_base_dirs = ("locale", "ui")
resource_base_dirs = ("locale")
base_dir = abspath(dirname(__file__))
package_data = ["*.json"]
for res in resource_base_dirs:
Expand Down
Loading
Loading