Quick Start¶
This guide walks you through writing your first fscm configuration.
Your First Script¶
Create a file called setup.py:
#!/usr/bin/env python3
"""Configure a basic web server."""
import fscm
from fscm import s, file, run, mkdir
def main():
# Install nginx
s.pkgs_install("nginx")
# Create a simple static site
mkdir("/var/www/mysite", mode="0755")
file(
"/var/www/mysite/index.html",
"<html><body><h1>Hello from fscm!</h1></body></html>\n",
mode="0644"
)
# Create nginx config
nginx_config = """
server {
listen 80;
server_name _;
root /var/www/mysite;
index index.html;
}
"""
file("/etc/nginx/sites-available/mysite", nginx_config, mode="0644")
# Enable the site
run("ln -sf /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/")
run("rm -f /etc/nginx/sites-enabled/default")
# Reload nginx
run("systemctl reload nginx", sudo=True)
# Print what we did
print("\n=== Changes made ===")
for change in fscm.CHANGELIST:
print(f" {change}")
if __name__ == "__main__":
main()
Running Your Script¶
Dry Run (Preview Changes)¶
Always preview changes first:
Dry Run Mode
In dry-run mode, fscm shows what would happen without making any changes. Always use this first to verify your configuration.
Apply Changes¶
When you're ready, run without --dry-run:
Sudo
Most system configuration requires root privileges. Run with sudo or
use fscm's built-in sudo support.
Using Dry Run Programmatically¶
You can also enable dry-run mode in your code:
import fscm
# Enable dry-run mode
fscm.settings.dry_run = True
# Now all operations will only be simulated
s.pkgs_install("nginx") # Won't actually install
file("/etc/config", "content") # Won't actually write
Adding Command-Line Arguments¶
For more control, use the built-in clii module:
#!/usr/bin/env python3
import fscm
from fscm.thirdparty.clii import App
cli = App(description="Configure server")
@cli.main
def main(dry_run: bool = False):
"""dry_run: Preview changes without applying"""
fscm.settings.dry_run = dry_run
# Your configuration here...
fscm.s.pkgs_install("nginx")
if __name__ == "__main__":
cli.run()
Arguments are derived from function parameters. Boolean defaults create --flag options.
Using Templates¶
For complex configurations, use Jinja2 templates:
import fscm
# Create templates/nginx.conf.j2:
# server {
# listen {{ port }};
# server_name {{ domain }};
# root {{ root_dir }};
# }
config = fscm.template(
"templates/nginx.conf.j2",
port=80,
domain="example.com",
root_dir="/var/www/html"
)
fscm.file("/etc/nginx/sites-available/mysite", config)
Remote Execution¶
To run on a remote host:
from fscm.remote import Host, SSH, Sudo, executor
# Define the remote host
host = Host(
name="webserver",
connection=SSH(hostname="10.0.0.5", username="ubuntu"),
become=Sudo()
)
# Execute remotely
with executor(host) as exe:
exe.fscm.s.pkgs_install("nginx")
exe.fscm.file("/var/www/index.html", "<h1>Hello!</h1>")
See Remote Execution Guide for details.
Next Steps¶
- Key Concepts — Understand change tracking, system detection
- File Operations — Master file management
- Examples — Real-world configurations