Arc is an infrastructure automation tool similar to Ansible, but using Lua for scripting. It allows you to define tasks that can be executed on remote systems via SSH.
Clone the repository and build the project:
git clone https://github.com/myFavShrimp/arc.git
cd arc
cargo build --release
The binary will be available at target/release/arc
.
Arc uses a Lua script (arc.lua
by default) to define targets and tasks.
-- Define a target system
targets.systems["frontend-server"] = {
address = "192.168.1.100",
user = "root",
}
targets.systems["api-server"] = {
address = "192.168.1.101",
user = "root",
port = 42, -- defaults to 22 if not specified
}
-- Define a group of systems
targets.groups["web-servers"] = {
members = {"frontend-server", "api-server"}
}
-- Define tasks
tasks["check_nginx"] = {
handler = function (system)
local result = system:run_command("nginx -v")
return result.exit_code == 0
end,
tags = {"nginx"}
}
tasks["install_nginx"] = {
handler = function (system)
local nginx_installed = tasks["check_nginx"].result
if nginx_installed == false then
return system:run_command("apt install nginx -y")
end
end,
dependencies = {"check_nginx"},
tags = {"nginx"}
}
To run all tasks on all systems:
arc
To run tasks with a specific tag:
arc --tag nginx
To run tasks on specific a group:
arc --group web-servers
Arc provides several command-line options:
Usage:
arc [OPTIONS]
Options:
-v, --verbose... Enable verbose output (repeat for increased verbosity)
-t, --tag <TAG> Filter tasks by tag
-g, --group <GROUP> Run tasks only on specific groups
-d, --dry-run Perform a dry run without executing commands or modifying the file system
-h, --help Print help information
Run tasks with the "nginx" tag:
arc -t nginx
Run tasks on the "web-servers" group with verbose output:
arc -g web-servers -v
Run tasks with multiple tags and groups:
arc -t nginx -t security -g web-servers -g database-servers
Perform a dry run without executing commands:
arc --dry-run
The system
object is provided to task handlers and represents a connection to a remote system.
name
: The name of the system as defined in targets.systemsaddress
: The IP address of the systemport
: The SSH port of the systemuser
: The SSH user used to connect to the system
-
run_command(cmd)
: Execute a command on the remote system- Parameters:
cmd
(string) - The command to execute - Returns: A table with the following fields:
stdout
: Command standard outputstderr
: Command standard errorexit_code
: Command exit code
- Parameters:
-
read_file(path)
: Read a file from the remote system- Parameters:
path
(string) - Path to the file - Returns: A table with the following fields:
path
: Path to the filecontent
: Content of the file
- Parameters:
-
write_file(path, content)
: Write a file to the remote system- Parameters:
path
(string) - Path to the filecontent
(string) - Content to write
- Returns: A table with the following fields:
path
: Path to the filebytes_written
: Number of bytes written
- Parameters:
-
rename_file(from, to)
: Rename a file on the remote system- Parameters:
from
(string) - Original pathto
(string) - New path
- Parameters:
-
remove_file(path)
: Remove a file from the remote system- Parameters:
path
(string) - Path to the file
- Parameters:
-
remove_directory(path)
: Remove a directory from the remote system- Parameters:
path
(string) - Path to the directory
- Parameters:
-
create_directory(path)
: Create a directory on the remote system- Parameters:
path
(string) - Path to the directory
- Parameters:
-
set_permissions(path, mode)
: Set permissions for a file or directory- Parameters:
path
(string) - Path to the file or directorymode
(number) - Permissions mode (e.g.tonumber("755", 8)
)
- Parameters:
-
metadata(path)
: Get metadata for a file or directory- Parameters:
path
(string) - Path to the file or directory - Returns: A table with the following fields:
path
: Path to the filesize
: Size in bytespermissions
: Permission modetype
: Type of file ("file", "directory", or "unknown")uid
: User IDgid
: Group IDaccessed
: Last access timemodified
: Last modification time
- Parameters:
The fs
object provides access to the local file system.
read_file(path)
: Read a file from the local file system- Parameters:
path
(string) - Path to the file - Returns: Content of the file as a string
- Parameters:
The template
object allows rendering templates using the Tera templating engine.
render(template_content, context)
: Render a template with given context- Parameters:
template_content
(string) - Template contentcontext
(table) - Variables to use for template rendering
- Returns: Rendered template as string
- Parameters:
The format
object provides utilities for working with JSON.
-
to_json(value)
: Convert a Lua value to JSON- Parameters:
value
(any) - Value to convert - Returns: JSON string
- Parameters:
-
to_json_pretty(value)
: Convert a Lua value to pretty-printed JSON- Parameters:
value
(any) - Value to convert - Returns: Pretty-printed JSON string
- Parameters:
-
from_json(json_string)
: Parse a JSON string to a Lua value- Parameters:
json_string
(string) - JSON string to parse - Returns: Parsed Lua value
- Parameters:
Tasks are defined using the tasks
global table:
tasks["task_name"] = {
handler = function(system)
-- Task implementation
return result
end,
dependencies = {"other_task"}, -- Optional
tags = {"tag1", "tag2"}, -- Optional
groups = {"group1", "group2"}, -- Optional
}
handler
: The function that implements the task. Takes a system object and returns a result.dependencies
: Array of task names that must be executed before this task.tags
: Array of tags associated with the task, used for filtering.groups
: Array of group names this task should run on. If not specified, the task runs on all groups.
Within a task, you can access the result of a previously executed dependency using:
local result = tasks["dependent_task"].result
Targets define the systems and groups that tasks will run on.
targets.systems["system_name"] = {
address = "ip_or_hostname",
user = "ssh_username",
port = 22, -- optional, defaults to 22
}
targets.groups["group_name"] = {
members = {"system1", "system2"},
}