File Operations¶
fscm provides powerful functions for managing files, directories, and permissions.
Creating and Updating Files¶
The file() function is the primary way to manage file contents:
import fscm
# Create a file with string content
fscm.file("/etc/myapp.conf", "setting=value\n")
# Create with specific permissions
fscm.file(
"/etc/myapp.conf",
"setting=value\n",
mode="0644",
owner="root:root"
)
# Create from bytes
fscm.file("/etc/binary.dat", b"\x00\x01\x02\x03")
# Create from another file (Path object)
from pathlib import Path
fscm.file("/etc/config", Path("local/config.template"))
Parameters¶
| Parameter | Type | Description |
|---|---|---|
path |
str/Path | Destination path |
content |
str/bytes/Path | File contents |
mode |
str | Permissions (e.g., "0644") |
owner |
str | Owner (e.g., "root:root") |
sudo |
bool | Use sudo for writing |
encoding |
str | Text encoding (default: utf-8) |
Idempotency¶
file() only writes if the content differs:
# First call: creates file
fscm.file("/etc/config", "content") # FileAdd change
# Second call: no change needed
fscm.file("/etc/config", "content") # No change recorded
Using Templates¶
For dynamic content, use Jinja2 templates:
import fscm
# Template file: templates/nginx.conf.j2
# server {
# listen {{ port }};
# server_name {{ domain }};
# root {{ root_dir }};
# }
content = fscm.template(
"templates/nginx.conf.j2",
port=80,
domain="example.com",
root_dir="/var/www/html"
)
fscm.file("/etc/nginx/sites-available/mysite", content)
Template Variables¶
Pass any Python objects as template variables:
servers = [
{"name": "web1", "ip": "10.0.0.1"},
{"name": "web2", "ip": "10.0.0.2"},
]
content = fscm.template("servers.j2", servers=servers)
Template (servers.j2):
Creating Directories¶
import fscm
# Create a directory
fscm.mkdir("/var/www/myapp")
# With permissions and ownership
fscm.mkdir(
"/var/www/myapp",
mode="0755",
owner="www-data:www-data"
)
# Create parent directories (like mkdir -p)
fscm.mkdir("/var/www/myapp/static/images") # Creates all parents
Changing Permissions¶
import fscm
# Change mode
fscm.chmod("/var/www/myapp", "0755")
# Recursive
fscm.chmod("/var/www/myapp", "0755", flags="-R")
# Make executable
fscm.make_executable("/usr/local/bin/myscript")
Changing Ownership¶
import fscm
# Change owner
fscm.chown("/var/www/myapp", "www-data")
# Change owner and group
fscm.chown("/var/www/myapp", "www-data:www-data")
# Recursive
fscm.chown("/var/www/myapp", "www-data:www-data", flags="-R")
Line-in-File Operations¶
Modify specific lines in configuration files:
import fscm
# Ensure a line exists
fscm.lineinfile(
"/etc/ssh/sshd_config",
line="PermitRootLogin no",
regexp=r"^#?PermitRootLogin"
)
# Add a line if pattern not found
fscm.lineinfile(
"/etc/hosts",
line="10.0.0.5 myserver",
regexp=r"myserver$"
)
# Remove a line
fscm.lineinfile(
"/etc/hosts",
regexp=r"^.*oldserver.*$",
state="absent"
)
Parameters¶
| Parameter | Type | Description |
|---|---|---|
path |
str | File to modify |
line |
str | Line content to ensure |
regexp |
str | Pattern to match existing line |
state |
str | "present" or "absent" |
sudo |
bool | Use sudo |
Working with Paths¶
The p() function provides a convenient path helper:
import fscm
# Create a path helper
path = fscm.p("/var/www/myapp")
# Chain operations
path.mkdir().chmod("0755").chown("www-data")
# Access underlying Path
print(path.path) # PosixPath('/var/www/myapp')
# Use Path methods
if path.exists():
content = path.read_text()
With Prefix¶
import fscm
# All paths relative to prefix
fscm.settings.prefix = "/opt/myapp"
path = fscm.p("config/app.conf") # /opt/myapp/config/app.conf
File Backups¶
fscm automatically backs up files before modification:
import fscm
# Configure backup location
fscm.settings.backup_dir = "/var/backups/fscm"
# Set size threshold (skip large files)
fscm.settings.backup_threshold = 1024 * 1024 # 1MB
# Disable backups
fscm.settings.backup_threshold = None
# Manual backup
fscm.backup_file("/etc/nginx/nginx.conf")
Backup location:
Downloading Files¶
Download files with checksum verification:
import fscm
# Download with SHA256 verification
fscm.download_and_check_sha(
url="https://example.com/package.tar.gz",
dest="/tmp/package.tar.gz",
sha256="abc123..."
)
Removing Files¶
import fscm
# Remove a file
fscm.run("rm /path/to/file")
# Remove directory
fscm.run("rm -rf /path/to/dir")
# Using PathHelper
path = fscm.p("/path/to/file")
path.rm() # Remove file
path.rm("-rf") # Remove directory recursively
Example: Complete File Setup¶
import fscm
from fscm import file, mkdir, chmod, chown, template
def setup_webapp():
# Create directory structure
mkdir("/var/www/myapp", mode="0755")
mkdir("/var/www/myapp/static", mode="0755")
mkdir("/var/www/myapp/logs", mode="0755")
# Deploy application config
file(
"/var/www/myapp/config.py",
template("config.py.j2", debug=False, db_host="localhost"),
mode="0640",
owner="www-data:www-data"
)
# Deploy nginx config
file(
"/etc/nginx/sites-available/myapp",
template("nginx.conf.j2", domain="example.com"),
mode="0644"
)
# Enable site
fscm.run("ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/")
# Set ownership recursively
chown("/var/www/myapp", "www-data:www-data", flags="-R")
return fscm.CHANGELIST
Next Steps¶
- Command Execution — Running shell commands
- Remote Execution — Managing remote hosts