Specinfra

repository·master·Indexed 43 days ago

https://github.com/mizzy/specinfra

A framework for defining and executing system inspection and management commands across various operating systems, including NixOS, AIX, Alpine Linux, Amazon Linux 2022, and Arch Linux. It provides a structured way to verify file permissions, package installations, process states, and network reachability, with built-in integration for RSpec test suites.

Tokens
43.7K
Snippets
209
Records
226
Agent score
52%

What's inside Specinfra

  1. Manage Runit services with Specinfra

    master

    Specinfra provides a module for managing services under the runit init system. This module allows you to check the status, enable/disable, and control the lifecycle (start, stop, restart, reload) of services using standard sv and filesystem operations.

    # Note: These methods are part of the Specinfra::Command::Module::Service::Runit module
    # and are used to generate shell commands for service management.
    
    # Check if a service is currently running
    # Uses: sv status <service> | grep -E '^run: '
    
    # Check if a service is enabled
    # Uses: test ! -f /etc/sv/<service>/down
    
    # Enable a service
    # Uses: ln -s /etc/sv/<service> /var/service/
    
    # Disable a service
    # Uses: rm /var/service/<service>
    
    # Start a service
    # Uses: sv up /var/service/<service>
    
    # Stop a service
    # Uses: sv down /var/service/<service>
    
    # Restart a service
    # Uses: sv restart /var/service/<service>
    
    # Reload a service
    # Uses: sv reload /var/service/<service>
  2. Configure Specinfra with RSpec

    master

    If RSpec is defined in your environment, Specinfra automatically configures itself to integrate with your test suite. It includes Specinfra::Helper::Configuration and registers several settings that you can use to define your test environment.

    Available RSpec settings include:

    • :os
    • :host
    • :ssh
    • :scp
    • :sudo_password
    • :winrm
    • :docker_container
    • :architecture (defaults to :x86_64)

    Additionally, any defaults defined in Specinfra.configuration.defaults are automatically added as RSpec settings. Specinfra also hooks into the before :each lifecycle to associate the current RSpec example with the active backend.

    # Example RSpec configuration usage
    RSpec.configure do |config| 
      config.os = :linux
      config.host = '192.168.1.10'
      config.ssh = { user: 'admin', key: '~/.ssh/id_rsa' }
    end
  3. Check if a Darwin package is installed via pkgutil

    master

    Use check_is_installed_by_pkgutil to verify the installation of a macOS package bundle using the system pkgutil tool. If a version is provided, the generated command includes a grep filter to ensure the installed version matches the requested one.

    # Check for package existence
    cmd = Specinfra::Command::Darwin::Base::Package.check_is_installed_by_pkgutil('com.example.pkg')
    
    # Check for a specific version
    cmd = Specinfra::Command::Darwin::Base::Package.check_is_installed_by_pkgutil('com.example.pkg', '2.0.0')
  4. Retrieve ZFS dataset properties

    master

    To fetch the properties and values of a ZFS dataset, use get_property. This generates a command using zfs get -Hp -o property,value all, which returns the property names and their corresponding values in a machine-readable format.

    # Returns a string command to get properties
    get_property('pool/dataset')
    # Output: "zfs get -Hp -o property,value all pool/dataset"
  5. Install or remove Homebrew packages on Darwin

    master

    Generate commands to manage Homebrew packages. Note that Homebrew does not natively support installing specific versions via the standard install command; it installs the latest available version unless other mechanisms are used.

    # Generate install command
    install_cmd = Specinfra::Command::Darwin::Base::Package.install('package_name')
    # Result: "brew install 'package_name'"
    
    # Generate uninstall command
    remove_cmd = Specinfra::Command::Darwin::Base::Package.remove('package_name')
    # Result: "brew uninstall 'package_name'"
  6. Inspect Alpine processes using Specinfra

    master

    When working with Alpine Linux, you can use Specinfra::Command::Alpine::Base::Process.get to generate shell commands for inspecting process details. The method accepts a process name and an opts hash containing a :format key.

    • If :format is set to 'args', it returns a command to fetch the command-line arguments for the process.
    • For any other format, it returns a command that fetches the specified column along with the arguments, filtering for the process name.

    Note: The process string is automatically escaped to prevent shell injection.

    # Example: Get the arguments for a process named 'nginx'
    cmd = Specinfra::Command::Alpine::Base::Process.get('nginx', { format: 'args' })
    # Returns: "ps -o args | grep nginx | head -1"
    
    # Example: Get the PID (using 'pid' as format) for a process named 'nginx'
    cmd = Specinfra::Command::Alpine::Base::Process.get('nginx', { format: 'pid' })
    # Returns: "ps -o pid,args | grep -E '\\s+nginx' | awk '{ print $1 }' | head -1"
  7. Check if a Debian package is installed

    master

    Use check_is_installed to generate a command that verifies if a specific package is currently installed on a Debian-based system. You can optionally specify a version to ensure a exact match. The command checks for the status install ok installed or hold ok installed using dpkg-query and grep.

    # Check if package is installed (any version)
    cmd = Specinfra::Command::Debian::Base::Package.check_is_installed('vim')
    
    # Check if a specific version is installed
    cmd = Specinfra::Command::Debian::Base::Package.check_is_installed('vim', '2:8.2.2434-3ubuntu3')
  8. Check for entries in /etc/fstab

    master

    Use Specinfra::Command::Linux::Base::Fstab.check_has_entry(mount_point) to verify if a specific mount point exists within the /etc/fstab file. This method executes an awk command to find the exact mount point while filtering out commented lines (lines starting with #).

    An alias get_entry is available which performs the exact same operation.

    # Returns a command string to check for a specific mount point
    Specinfra::Command::Linux::Base::Fstab.check_has_entry('/mnt/data')
    
    # Alias usage
    Specinfra::Command::Linux::Base::Fstab.get_entry('/mnt/data')
  9. Inspect FreeBSD V6 user properties via pw

    master

    In FreeBSD V6 environments, user information such as home directories and login shells is retrieved using the pw user show command. The Specinfra::Command::Freebsd::V6::User class provides methods to construct shell commands that parse the output of pw user show using cut and grep to validate or retrieve specific user attributes.

    # Example of how the underlying commands are constructed:
    # To check if a user has a specific home directory:
    # pw user show <user> | cut -f 9 -d ':' | grep -w -- <path_to_home>
    
    # To check if a user has a specific login shell:
    # pw user show <user> | cut -f 10 -d ':' | grep -w -- <path_to_shell>
  10. Retrieve host IP addresses on OpenBSD

    master

    When working with OpenBSD hosts in specinfra, you can retrieve IP addresses for a given hostname using the following command patterns. These commands rely on getent hosts and awk to parse the output:

    • Generic IP Address: Retrieves the first IP address returned by getent hosts. Note that if both IPv4 and IPv6 are present, this behavior mimics Linux and simply picks the first record.
    • IPv4 Address: Specifically filters the getent hosts output to return only the record matching the IPv4 pattern (^[0-9.]+$).
    • IPv6 Address: Specifically filters the getent hosts output to return only the record matching the IPv6 pattern (^[0-9a-f:]+$).
    # Examples of the command strings generated by the Specinfra::Command::Openbsd::Base::Host class:
    
    # Get first available IP (generic)
    getent hosts <name> | awk '{print $1; exit}'
    
    # Get IPv4 specifically
    getent hosts <name> | awk '$1 ~ /^[0-9.]+$/ {print $1}'
    
    # Get IPv6 specifically
    getent hosts <name> | awk 'tolower($1) ~ /^[0-9a-f:]+$/ {print $1}'
  11. Perform file system operations

    master

    Methods for modifying the file system:

    • change_mode(file, mode, options = {}): Changes file permissions. Option: recursive: true (adds -R).
    • change_owner(file, owner, group=nil, options = {}): Changes user and/or group ownership. Option: recursive: true (adds -R).
    • change_group(file, group, options = {}): Changes group ownership. Option: recursive: true (adds -R).
    • create_as_directory(file): Creates a directory path using mkdir -p.
    • copy(src, dest, options = {}): Copies files/directories. Option: recursive: true (adds -R).
    • move(src, dest): Moves/renames a file or directory.
    • remove(file): Deletes a file or directory recursively (rm -rf).
    • download(src, dest): Downloads a file from a URL using curl -sSL.