bork

the Bash-Operated Reconciling Kludge
授权协议 View license
开发语言 SHELL
所属分类 应用工具、 终端/远程登录
软件类型 开源软件
地区 不详
投 递 者 叶英哲
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Bork - (no longer under development)

Bork puts the 'sh' back into IT. Bork Bork Bork.

Bork is no longer under active development. If you fork it and your fork gets some steam going, please let me know, I'm happy to add you to this list.

Known Active Forks:

the Swedish Chef Puppet of Config Management

Bork is a bash DSL for making declarative assertions about the state of a system.

Bork is written against Bash 3.2 and common unix utilities such as sed, awk andgrep. It is designed to work on any UNIX-based system and maintain awareness ofplatform differences between BSD and GPL versions of unix utilities.

Installation

From source

  1. Clone this repository:git clone https://github.com/mattly/bork /usr/local/src/bork

  2. Symlink the bork binaries into your $PATH:

ln -sf /usr/local/src/bork/bin/bork /usr/local/bin/bork

via Homebrew (Mac OS X)

  1. Install via Homebrew:brew install bork

Usage and Operations

Running bork without arguments will output some help:

bork usage:

bork operation [config-file] [options]

where "operation" is one of:

- check:      perform 'status' for a single command
    example:  bork check ok github mattly/dotfiles
- compile:    compile the config file to a self-contained script output to STDOUT
    --conflicts=(y|yes|n|no)  If given, sets an automatic answer for conflict resolution.
    example:  bork compile dotfiles.sh --conflicts=y > install.sh
- do:         perform 'satisfy' for a single command
    example:  bork do ok github mattly/dotfiles
- satisfy:    satisfy the config file's conditions if possible
- status:     determine if the config file's conditions are met
- types:      list types and their usage information

Let's explore these in more depth:

Assertions and Config Files

At the heart of bork is making assertions in a declarative manner viathe ok function. That is, you tell it what you want the system to look likeinstead of how to make it look like that. An assertion takes a type and anumber of arguments. It invokes the type's handler function with an actionsuch as status, install, or upgrade, which determines the imperativecommands needed to test the assertion or bring it up to date. There are a numberof included types in the types directory, and bork makes it easy to createyour own.

Here's a basic example:

ok brew                                       # presence and updatedness of Homebrew
ok brew git                                   # presence and updatedness of Homebrew git package
ok directory $HOME/code                       # presence of the ~/code directory
ok github $HOME/code/dotfiles mattly/dotfiles # presence, drift of git repository in ~/code/dotfiles
cd $HOME
for file in $HOME/code/dotfiles/configs/.[!.]*
do                                            # for each file in ~/code/dotfiles/configs,
  ok symlink "$(basename $file)" $file       # presense of a symlink to file in ~ with a leading dot
done

When run, bork will test each ok assertion and determine if it's met or not.If not, bork can go ahead and satisfy the assertion by installing, upgrading, oraltering the configuration of the item to match the assertion. It will then testthe assertion again. Declarations are idempotent -- if the assertion is alreadymet, bork will not do anything.

When you're happy with your config script, you can compile it to a standalonescript which does not require bork to run. The compiled script can be passedaround via curl, scp or the like and run on completely new systems.

Assertion Types

You can run bork types from the command line to get a list of the assertion typesand some basic information about their usage and options.

Generic assertions

          check: runs a given command.  OK if returns 0, FAILED otherwise.

File System

      directory: asserts presence of a directory
           file: asserts the presence, checksum, owner and permissions of a file
       download: asserts the presence of a file compared to an http(s) url
        symlink: assert presence and target of a symlink

Source Control

            git: asserts presence and state of a git repository
         github: front-end for git type, uses github urls

Language Package Managers

            gem: asserts the presence of a gem in the environment's ruby
            npm: asserts the presence of a nodejs module in npm's global installation
            pip: asserts presence of packages installed via pip
          pipsi: asserts presence of pipsi or packages installed via pipsi
            apm: asserts the presence of an atom package
         go-get: asserts the presence of a go package

Mac OS X specific

           brew: asserts presence of packages installed via Homebrew on Mac OS X
       brew-tap: asserts a Homebrew formula repository has been tapped; does NOT assert updatedness of a tap's formula. Use `ok brew` for that.
           cask: asserts presence of apps installed via caskroom.io on Mac OS X
       defaults: asserts settings for OS X's 'defaults' system
            mas: asserts a Mac app is installed and up-to-date from the App Store
                 via the 'mas' utility https://github.com/argon/mas
         scutil: verifies OS X machine name with scutil

Linux specific:

            apt: asserts packages installed via apt-get on Debian or Ubuntu Linux
            yum: asserts packages installed via yum on CentOS or RedHat Linux
         zypper: asserts packages installed via zypper (SUSE)

User management (currently Linux-only)

          group: asserts presence of a unix group (Linux only, for now)
           user: assert presence of a user on the system

UNIX utilities

       iptables: asserts presence of iptables rule

Runtime Operations

Per the usage guide, bork has a few main modes of operation:

  • status: Reports on the status of the assertions in a config file.
  • satisfy: Checks the status of assertions in a config file, satisfying themwhere needed.
  • compile: Compiles a config file to a standalone script.
  • check: Performs a status report on a single assertion.
  • do: Performs a satisfy operation on a single assertion.

bork status myconfig.sh

The status command will confirm that assertions are met or not, and outputtheir status. It will not take any action to satisfy those assertions. There area handful of statuses an assertion can return, and this since this mode is theclosest bork can do to a true dry run(*) you can use it to test a scriptagainst a pre-existing machine.

  • Some types, such as git, need to modify local state by talking to the network(such as performing git fetch), without modifying the things the assertion aimsto check.

The status command will give you output such as:

outdated: brew
ok: brew git
missing: brew fish
ok: directory /Users/mattly/code/mattly
conflict (upgradable): github mattly/dotfiles
local git repository has uncommitted changes
ok: symlink /Users/mattly/.gitignore /Users/mattly/code/mattly/dotfiles/configs/gitignore
conflict (clobber required): symlink /Users/mattly/.lein /Users/mattly/code/mattly/dotfiles/configs/lein
not a symlink: /Users/mattly/.lein
mismatch (upgradable): defaults com.apple.dock tilesize integer 36
expected type: integer
received type: float
expected value: 36
received value: 55

Each item reports its status like so:

  • ok: The assertion is met as best we can determine.
  • missing: The assertion is not met, and no trace of it ever being met was found.
  • outdated: The assertion is met, but can be upgraded to a newer version.
  • mismatch (upgradable): The assertion is not met as specified, something isdifferent. It can be satisfied easily. An explanation will be given.
  • conflict (upgradable): The assertion is not met as specified. It can besatisfied easily, but doing so may result in data loss.
  • conflict (clobber required): The assertion is not met as specified. Borkcannot currently satisfy this assertion. In the future, it will be able to,but doing so may result in data loss.

bork check ok github mattly/dotfiles

The check command will take a single assertion on the command line and performa status check as above for it.

bork satisfy myconfig.sh

The satisfy command is where the real magic happens. For every assertion inthe config file, bork will check its status as described in the status commandabove, and if it is not ok it will attempt to make it ok, typically viainstalling or upgrading something -- but sometimes a conflict is detectedwhich could lose data, such as a local git repository having uncommittedchanges. In that case, bork will warn you about the problem and ask if you wantto proceed. Sometimes conflicts are detected which bork does not know how toresolve — it will warn you about the problem so you can fix it yourself.

bork do ok github mattly/dotfiles

The do command will take a single assertion on the command line and perform asatisfy operation on it as above.

bork compile myconfig.sh

The compile command will output to STDOUT a standalone shell script that doesnot require bork to run. You may pass this around as with any file via curl orscp or whatever you like and run it. Any sub-configs via include will beincluded in the output, and any type that needs to include resources to do whatit does, such as the file type, will include their resources in the script asbase64 encoded data.

Custom Types

Writing new types is pretty straightforward, and there is a guide to writingthem in the docs/ directory. If you wish to use a type that is not in bork'stypes directory, you can let bork know about it with the registerdeclaration:

register etc/pgdb.sh
ok pgdb my_app_db

Composing Config Files

You may compose config files into greater operations with the includedirective with a path to a script relative to the current script's directory.

# this is main.sh
include databases.sh
include etc/projects.sh
# this is etc/projects.sh
include project-one.sh
include project-two.sh
# these will be read from the etc/ directory

Taking Further Action on Changes

Bork doesn't have callbacks per-se, but after each assertion there are a handfulof functions you can call to take further action:

ok brew fish
if did_install; then
  sudo echo "/usr/local/bin/fish" >> /etc/shells
  chsh -s /usr/local/bin/fish
fi

There are four functions to help you take further actions on change:

  • did_install: did the previous assertion result in the item being installedfrom scratch?
  • did_upgrade: did the previous assertion result in the existing item beingupgraded?
  • did_update: did the previous assertion result in either the item beinginstalled or upgraded?
  • did_error: did attempting to install or upgrade the previous assertionresult in an error?

Contributing

  1. Fork it
  2. Create your feature branch: git checkout -b feature/my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin feature/my-new-feature
  5. Submit a pull request

Contribution Guidelines

  1. Prefer clarity of intent over brevity. Bash can be an obtuse language, but itdoesn't have to be. Many people have said bork has some of the clearestbash code they've ever seen, and that's a standard to strive for.

  2. Favor helper abstractions over arbitrary platform-specific checks. Seemd5cmd, http, andpermission_cmd, and look at how they'reused.

  3. Types are independent, stateless, and atomic. Do not attempt to maintain acache in a type file unless you're talking to the network. An assertion isthe whole of the assertion — don't attempt to create a multi-stageassertion type that depends on maintaining state. Find a way to express thewhole of the assertion in one go.

  4. Leave Dependency Management to the user. Is a needed binary not installed fora type? Return $STATUS_FAILED_PRECONDITION in your status check. Let theuser decide the best way to satisfy any dependencies.

Community

Feel free to join us in IRC:

Requirements / Dependencies

  • Bash 3.2

Version

0.10.0

License

Apache License 2.0

  • http://sourceforge.net/projects/bork/ root@fedora:~# ls -l total 28 drwxr-xr-x 6 root root  4096 2014-02-25 21:42 bork-1.4 drwxr-xr-x 4 root root  4096 2014-02-25 21:50 Desktop -rw-r--r-- 1 root root

相关阅读

相关文章

相关问答

相关文档