Skip to content

Commit d1b9169

Browse files
authored
Merge pull request #67 from seanwevans/claude/project-cleanup-testing-7e97st
Refactor pg_os into single SQL file and improve documentation
2 parents b8e4d9d + 9f6411b commit d1b9169

26 files changed

Lines changed: 256 additions & 1711 deletions

.github/workflows/test.yml

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
11
name: CI
2+
23
on:
34
push:
45
pull_request:
6+
57
jobs:
68
test:
79
runs-on: ubuntu-latest
810
steps:
911
- uses: actions/checkout@v4
1012

11-
- name: Install PostgreSQL and headers
13+
- name: Install PostgreSQL and development headers
1214
run: |
1315
sudo apt-get update
14-
# Install the server, contrib modules and the development headers
15-
sudo apt-get install -y postgresql postgresql-contrib libpq-dev postgresql-server-dev-16
16+
# Server, contrib modules, client library and the PGXS build headers
17+
sudo apt-get install -y postgresql postgresql-contrib libpq-dev postgresql-server-dev-all
1618
1719
- name: Start PostgreSQL
1820
run: |
19-
# Determine the installed major version and start the cluster
20-
sudo pg_ctlcluster $(pg_config --version | awk '{print $2}' | cut -d. -f1) main start
21+
# Determine the installed major version and start the default cluster
22+
PG_MAJOR=$(pg_config --version | awk '{print $2}' | cut -d. -f1)
23+
echo "PG_MAJOR=$PG_MAJOR" >> "$GITHUB_ENV"
24+
sudo pg_ctlcluster "$PG_MAJOR" main start
25+
26+
- name: Create a superuser role for the runner
27+
run: |
28+
# pg_regress connects over the local socket as the current OS user via
29+
# peer authentication, so that user needs a matching superuser role.
30+
sudo -u postgres createuser --superuser "$(whoami)"
31+
sudo -u postgres createdb "$(whoami)"
32+
33+
- name: Build and install the extension
34+
run: |
35+
make
36+
sudo make install
37+
38+
- name: Run regression tests
39+
run: make installcheck
40+
41+
- name: Show regression diffs on failure
42+
if: failure()
43+
run: cat tmp_pg_os_regress/regression.diffs || true

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
# Regression test outputs
1414
/results/
1515
/tmp_check/
16+
/tmp_pg_os_regress/
17+
regression.diffs
18+
regression.out
1619

1720
# Backup and temp files
1821
*~

Makefile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
EXTENSION = pg_os
22
DATA = pg_os--1.0.sql
33
PG_CONFIG ?= pg_config
4-
REGRESS = pg_os_basic create_user lock_file create_process allocate_memory load_unload_module modules check_permission free_all_memory_for_process file_versioning locks_security create_file create_process
4+
REGRESS = pg_os_basic \
5+
create_user \
6+
check_permission \
7+
create_process \
8+
allocate_memory \
9+
allocate_page \
10+
free_all_memory_for_process \
11+
create_file \
12+
file_versioning \
13+
lock_file \
14+
load_unload_module \
15+
modules \
16+
locks_security
517
REGRESS_OPTS = --outputdir=$(CURDIR)/tmp_pg_os_regress
618
PGXS := $(shell $(PG_CONFIG) --pgxs)
719
include $(PGXS)

README.md

Lines changed: 116 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -3,148 +3,148 @@
33

44

55
## Overview
6-
`pg_os` is a PostgreSQL extension that provides operating system-level functionality directly within the database environment. By leveraging SQL procedures and functions, `pg_os` enables users to interact with system processes, manage memory, handle inter-process communication (IPC), schedule tasks, and enforce security policies at the OS level.
6+
`pg_os` is a PostgreSQL extension that models operating-system concepts entirely
7+
inside the database. Tables stand in for kernel objects (processes, threads,
8+
memory segments, files, mutexes, semaphores, devices, …) and PL/pgSQL functions
9+
play the role of system calls that operate on them under a small permission
10+
model.
711

8-
The extension bridges the gap between the database and the underlying OS, allowing administrators to gain deep insights into system performance and control resource usage efficiently.
12+
It is a teaching/experimentation toy rather than a way to control the host OS:
13+
everything happens in SQL, so you can poke at schedulers, page allocation, file
14+
permissions, IPC and locking without leaving `psql`.
915

1016
## Features
11-
- **Process Management** – Monitor and control OS-level processes directly from PostgreSQL.
12-
- **File System Operations** – Interact with the file system to read, write, and manipulate files.
13-
- **Memory Management** – Analyze and manage memory allocations.
14-
- **IPC (Inter-Process Communication)** – Facilitate communication between processes.
15-
- **Scheduler** – Schedule jobs and tasks within PostgreSQL.
16-
- **Locks** – Manage and analyze system and database locks.
17-
- **Security** – Handle user roles and permissions at the OS level.
18-
- **Network Monitoring** – Monitor and manage network interfaces and traffic.
19-
- **Power Management** – Access and control power states of the system.
20-
- **I/O Operations** – Track and manage input/output processes.
21-
- **Signal Management** – Send and receive system signals.
22-
- **Garbage Collection** – Monitor and optimize system garbage collection processes.
23-
- **Module Management** – Inspect and control system modules.
17+
- **Users, roles & permissions** – a minimal RBAC layer that gates the other subsystems.
18+
- **Process management** – create, start, execute, prioritise and terminate simulated processes.
19+
- **Scheduler** – priority / round-robin / SJF process scheduling and a simple thread scheduler.
20+
- **Memory management** – allocate and free memory segments, and allocate paged virtual addresses per thread.
21+
- **Filesystem** – a hierarchical file table with permissions, locking and content versioning.
22+
- **IPC** – named channels and a per-user mailbox.
23+
- **Locks** – mutexes and counting semaphores exposed through `SECURITY DEFINER` helpers.
24+
- **Signals** – send and handle `SIGTERM` / `SIGSTOP` / `SIGCONT`.
25+
- **Garbage collection** – free memory for terminated processes and reap stale ones.
26+
- **Devices & I/O, networking, modules, power** – small simulated subsystems for completeness.
2427

2528
## Requirements
26-
- PostgreSQL 12+
27-
- `plpgsql` extension installed (required)
28-
- Extension is not relocatable and will install into the database's default schema
29-
- Sufficient OS-level permissions for system interaction
29+
- PostgreSQL 12 or newer
30+
- `plpgsql` (bundled with PostgreSQL; declared as a dependency)
31+
- The PGXS build headers (`postgresql-server-dev-*`) to build and install
3032

3133
## Installation
3234
1. Clone the repository:
3335
```bash
34-
git clone https://github.com/your-repo/pg_os.git
36+
git clone https://github.com/seanwevans/pg_os.git
37+
cd pg_os
3538
```
36-
2. Build and install the extension using PGXS:
39+
2. Build and install with PGXS:
3740
```bash
38-
cd pg_os
3941
make
4042
sudo make install
4143
```
42-
3. Connect to your PostgreSQL instance:
44+
To build against a specific PostgreSQL install, point `PG_CONFIG` at it:
4345
```bash
44-
psql -U postgres -d your_database
46+
make PG_CONFIG=/usr/lib/postgresql/16/bin/pg_config
4547
```
46-
4. Install the extension:
48+
3. Create the extension in your database. You may install it into a dedicated
49+
schema if you prefer:
4750
```sql
48-
CREATE EXTENSION pg_os;
51+
CREATE EXTENSION pg_os; -- into the current schema
52+
-- or
53+
CREATE EXTENSION pg_os WITH SCHEMA os; -- into schema "os"
4954
```
55+
Creating the extension also ensures a `pgos_admin` role exists; it owns the
56+
`SECURITY DEFINER` locking helpers (see [Security model](#security-model)).
5057

5158
## Usage
52-
### 1. Process Management
53-
```sql
54-
SELECT * FROM os_processes();
55-
```
56-
- Lists all current OS processes and their statuses.
59+
The functions are intentionally small. A typical session looks like this:
5760

58-
### 2. File System Operations
5961
```sql
60-
SELECT * FROM fs_list('/var/log');
62+
CREATE EXTENSION pg_os;
63+
64+
-- 1. Set up a user, a role, and grant it some permissions
65+
SELECT create_user('alice') AS alice_id; -- => 1
66+
SELECT create_role('operator') AS role_id; -- => 1
67+
SELECT assign_role_to_user(1, 1);
68+
SELECT grant_permission_to_role(1, 'process', 'execute');
69+
SELECT grant_permission_to_role(1, 'memory', 'allocate');
70+
SELECT grant_permission_to_role(1, 'file', 'write');
71+
72+
-- 2. Create and inspect a process (create_process is a PROCEDURE)
73+
CALL create_process('worker', 1, 5); -- name, owner_id, priority
74+
SELECT name, state, priority FROM processes;
75+
76+
-- 3. Allocate memory to the process
77+
INSERT INTO memory_segments (size) VALUES (4096);
78+
SELECT allocate_memory(1, 1, 1024); -- user_id, process_id, size
79+
SELECT process_id, segment_id FROM process_memory;
80+
81+
-- 4. Create, write and read a file (with automatic versioning)
82+
SELECT create_file(1, 'notes.txt', NULL, FALSE) AS file_id; -- => 1
83+
SELECT write_file(1, 1, 'hello');
84+
SELECT write_file(1, 1, 'hello world');
85+
SELECT read_file(1, 1); -- => 'hello world'
86+
SELECT version_number, contents FROM file_versions WHERE file_id = 1 ORDER BY version_number;
87+
88+
-- 5. Concurrency primitives (callable by unprivileged roles, see below)
89+
SELECT create_semaphore('jobs', 1, 1);
90+
SELECT acquire_semaphore(1, 'jobs');
91+
SELECT release_semaphore(1, 'jobs');
6192
```
62-
- Retrieves the contents of a directory.
6393

64-
### 3. Memory Management
65-
```sql
66-
SELECT * FROM os_memory_usage();
94+
Permissions are enforced with `check_permission(user_id, resource_type, action)`,
95+
where `resource_type` is one of `process`, `file`, `resource`, `memory` and
96+
`action` is one of `read`, `write`, `execute`, `allocate`, `delete`. Calls that
97+
require a permission the user lacks raise an exception.
98+
99+
### Selected functions by subsystem
100+
| Subsystem | Functions |
101+
|-----------|-----------|
102+
| Users/roles | `create_user`, `create_role`, `assign_role_to_user`, `grant_permission_to_role`, `check_permission` |
103+
| Processes | `create_process`, `start_process`, `execute_process`, `terminate_process`, `set_process_priority`, `pause_all_processes`, `resume_all_waiting_processes`, `list_processes_by_state`, `process_count_by_state` |
104+
| Scheduler | `schedule_processes`, `schedule_threads` |
105+
| Memory | `allocate_memory`, `free_memory`, `allocate_page`, `free_all_memory_for_process` |
106+
| Filesystem | `create_file`, `read_file`, `write_file`, `change_file_permissions`, `lock_file`, `unlock_file`, `version_file` |
107+
| IPC | `register_channel`, `write_channel`, `read_channel`, `send_mail`, `check_mail` |
108+
| Locks | `create_mutex`, `lock_mutex`, `unlock_mutex`, `create_semaphore`, `acquire_semaphore`, `release_semaphore` |
109+
| Signals | `send_signal`, `handle_signals` |
110+
| GC | `cleanup_terminated_processes`, `free_all_memory_for_process` |
111+
| I/O / Net / Modules / Power | `enqueue_io_request`, `process_device_queue`, `send_packet`, `load_module`, `unload_module`, `set_power_state` |
112+
113+
## Security model
114+
Most functions run with the privileges of the caller. The mutex and semaphore
115+
helpers (`create_mutex`, `lock_mutex`, `unlock_mutex`, `create_semaphore`,
116+
`acquire_semaphore`, `release_semaphore`) are `SECURITY DEFINER` and owned by the
117+
`pgos_admin` role, with `EXECUTE` granted to `PUBLIC`. This lets an otherwise
118+
unprivileged role manipulate locks and semaphores through the controlled API
119+
without being granted direct access to the underlying tables. Their
120+
`search_path` is pinned to the extension's schema (`@extschema@`) plus `pg_temp`
121+
to avoid search-path injection.
122+
123+
## Testing
124+
The extension ships a PGXS regression suite under `sql/` (inputs) and
125+
`expected/` (expected output). With a running PostgreSQL cluster and a superuser
126+
role for your OS user:
127+
128+
```bash
129+
make
130+
sudo make install
131+
make installcheck
67132
```
68-
- Displays memory consumption statistics.
69133

70-
### 4. IPC (Inter-Process Communication)
71-
```sql
72-
SELECT ipc_signal(12345, 'SIGTERM');
73-
```
74-
- Sends a termination signal to the process with PID 12345.
134+
`make installcheck` creates a throwaway `contrib_regression` database, installs
135+
the extension and runs every test listed in `REGRESS` in the `Makefile`. The same
136+
flow runs on every push/PR via the GitHub Actions workflow in
137+
`.github/workflows/test.yml`.
75138

76-
### 5. Locks
77-
```sql
78-
SELECT * FROM os_locks();
79-
```
80-
- Lists all current locks on system resources.
81-
82-
### 6. Scheduler
83-
```sql
84-
SELECT * FROM os_schedule_job('backup', '0 3 * * *', 'pg_dump your_database > backup.sql');
85-
```
86-
- Schedules a nightly backup at 3 AM.
87-
88-
### 7. Network Monitoring
89-
```sql
90-
SELECT * FROM os_network_interfaces();
91-
```
92-
- Lists all network interfaces and their statuses.
93-
94-
### 8. Power Management
95-
```sql
96-
SELECT os_power_state('suspend');
97-
```
98-
- Suspends the system.
99-
100-
### 9. I/O Operations
101-
```sql
102-
SELECT * FROM os_io_stats();
103-
```
104-
- Displays current I/O statistics.
105-
106-
### 10. Signal Management
107-
```sql
108-
SELECT os_send_signal(12345, 'SIGHUP');
109-
```
110-
- Sends a hang-up signal to the process with PID 12345.
111-
112-
### 11. Garbage Collection
113-
```sql
114-
SELECT * FROM os_gc_status();
115-
```
116-
- Monitors garbage collection processes.
117-
118-
### 12. Module Management
119-
```sql
120-
SELECT * FROM os_modules();
121-
```
122-
- Lists all loaded system modules.
123-
124-
### 13. Users, Roles, and Permissions
125-
```sql
126-
SELECT * FROM os_users_roles_permissions();
127-
```
128-
- Displays user roles and permissions.
129-
130-
## Source Files
131-
- `audit.sql` – Handles audit logging and tracking.
132-
- `fs.sql` – Implements file system operations.
133-
- `ipc.sql` – Facilitates inter-process communication.
134-
- `locks.sql` – Manages lock operations.
135-
- `memory.sql` – Provides memory management utilities.
136-
- `os.sql` – Core OS interaction functions.
137-
- `processes.sql` – Monitors and manages system processes.
138-
- `scheduler.sql` – Implements job scheduling.
139-
- `usersrolespermissions.sql` – Manages users, roles, and permissions.
140-
- `network.sql` – Handles network monitoring and management.
141-
- `power.sql` – Implements power management functions.
142-
- `io.sql` – Tracks I/O operations.
143-
- `signals.sql` – Manages system signals.
144-
- `gc.sql` – Monitors and controls garbage collection.
145-
- `modules.sql` – Manages system modules.
146-
- `pg_os--1.0.sql` – Extension script combining all modules.
147-
- `pg_os.control` – Extension control file.
139+
## Project layout
140+
- `pg_os--1.0.sql` – the extension install script (tables, functions, indexes). Single source of truth.
141+
- `pg_os.control` – extension control file.
142+
- `Makefile` – PGXS build/test configuration.
143+
- `sql/` – regression test inputs (plus `fs_constraints_migration.sql`, a one-off migration that tightens the `files` constraints on older installs).
144+
- `expected/` – expected regression output.
148145

149146
## Contributing
150-
Contributions are welcome! Please open an issue or submit a pull request with any improvements or bug fixes.
147+
Contributions are welcome. Please keep `pg_os--1.0.sql` and the regression tests
148+
in sync: add or update a test under `sql/` and its `expected/` output for any
149+
behavioural change, and make sure `make installcheck` passes before opening a
150+
pull request.

0 commit comments

Comments
 (0)