{"id":14966043,"url":"https://github.com/melezhik/sparrowdo","last_synced_at":"2026-04-01T17:16:57.984Z","repository":{"id":53895939,"uuid":"184820471","full_name":"melezhik/sparrowdo","owner":"melezhik","description":"Run Sparrow tasks remotely","archived":false,"fork":false,"pushed_at":"2026-03-23T19:29:11.000Z","size":234,"stargazers_count":24,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-28T18:07:43.465Z","etag":null,"topics":["automation","configuration-management","provisioning","raku"],"latest_commit_sha":null,"homepage":"","language":"Raku","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/melezhik.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-05-03T21:08:28.000Z","updated_at":"2026-03-18T08:46:53.000Z","dependencies_parsed_at":"2024-01-05T11:56:58.299Z","dependency_job_id":"ef659570-fe94-4352-8f54-15a4abd55b98","html_url":"https://github.com/melezhik/sparrowdo","commit_stats":{"total_commits":291,"total_committers":1,"mean_commits":291.0,"dds":0.0,"last_synced_commit":"24d9e68a33fd3292617cadf7f4efa88da1be1848"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/melezhik/sparrowdo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melezhik%2Fsparrowdo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melezhik%2Fsparrowdo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melezhik%2Fsparrowdo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melezhik%2Fsparrowdo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/melezhik","download_url":"https://codeload.github.com/melezhik/sparrowdo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melezhik%2Fsparrowdo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","configuration-management","provisioning","raku"],"created_at":"2024-09-24T13:35:44.770Z","updated_at":"2026-04-01T17:16:57.961Z","avatar_url":"https://github.com/melezhik.png","language":"Raku","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sparrowdo\n\nRun Sparrow tasks remotely (and not only)\n\n# Build status\n\n![SparkyCI](https://sparky.sparrowhub.io/badge/gh-melezhik-Sparrowdo?foo=bar)\n\n# Install\n\n    zef install Sparrowdo\n\n# Usage\n\n    sparrowdo --host=remote-host [options]\n\nFor example:\n\n    # ssh host, bootstrap first, use of local repository\n    sparrowdo --host=13.84.166.232  --repo=file:///home/melezhik/repo --verbose  --bootstrap\n\n    # docker host, don't add sudo\n    sparrowdo --docker=SparrowBird --image=alpine:latest --no_sudo\n\n    # localhost, with sudo\n    sparrowdo --localhost\n\n    # read hosts from file\n    sparrowdo --host=hosts.raku\n\n# DSL\n\nSparrow6 DSL provides high level functions to manage configurations.\n\nJust create a file named `sparrowdo` in current working directory and add few functions:\n\n    $ cat sparrowfile\n\n    user 'zookeeper';\n\n    group 'birds';\n\n    directory '/var/data/avifauna/greetings/', %( owner =\u003e 'zookeeper' );\n\n    file-create '/var/data/avifauna/greetings/sparrow.txt', %( \n      owner =\u003e 'zookeeper',\n      group =\u003e 'birds', \n      mode  =\u003e '0644', \n      content =\u003e 'I am little but I am smart'\n    );\n\n    service-start 'nginx';\n\n    package-install ('nano', 'ncdu', 'mc' );\n\n\nThe full list of function is available at [Sparrow6 DSL](https://github.com/melezhik/Sparrow6/blob/master/documentation/dsl.md)\ndocumentation.\n\nIf DSL is not enough you can call any Sparrow6 plugin using `task-run` function:\n\n    task-run \"show me your secrets\", \"azure-kv-show\", %(\n      kv      =\u003e \"Stash\" # key vault name\n      secret  =\u003e ( \"password\", \"login\" ) # secret names\n    )\n\n\n## DSL vs `task-run` function\n\nDSL is high level adapter with addition of some \"syntax sugar\" to make a code concise and readable. \n\nDSL functions are Raku functions, you take advantage of input parameters validation. \n\nHowever DSL is limited. Not every Sparrow6 plugin has related DSL function.\n\nOnce we've found some Sparrow6 plugin common enough we add a proper DSL wrapper for it.\n\nIn case you need more DSL wrappers let us know!\n\n# Sparrowdo workflow\n\n      ====================                                   ====================\n      |                  |  --- [ Bootstrap ]                |                  | LocalHost\n      |    MasterHost    |  --- [ Sparrowdo Scenario ] ---\u003e  |    TargetHost    | Docker \n      |                  |               *                   |                  | Ssh\n      ====================               |                   ====================\n       {Sparrow6 Module}                 |                    {Sparrow6 Client}\n                                          \\    parameters\n                                           \\-----------------\u003e [ tasks ]\n                                                                ^  ^  ^\n                                                               /  /  /\n                                    ------------              /  /  /\n                                   { Repository } ------------------\n                                    ------------          [ plugins ]\n                                 -------------------\n                                /      |       |     \\\n                               /       |       |      \\\n                              /        |       |       \\\n                             /         |       |        \\\n                          [CPAN]   [RubyGems] [PyPi]  [raku.land]\n\n\n## Master host\n\nMaster host is where Sparrow6 tasks \"pushed\" from totarget hosts.\n\nSparrowdo should be installed on master host:\n\n    $ zef install Sparrowdo\n\n## Sparrowdo scenario\n\nSparrowdo scenario is a collection of Sparrow6 tasks executed on target host.\n\n## Target hosts\n\nTarget hosts are configured by Sparrow6 which should be installed there as well:\n\n    $ zef install Sparrow6\n\n## Bootstrap\n\nBootstrap is process of automation of Sparrow6 installation on target host:\n\n    $ sparrowdo --host=192.168.0.1 --bootstrap\n\nBootstrap runs under `sudo` and requires sudo privileges on target host.\n\n## Sudo\n\nExecution of Sparrow6 tasks on target host is made under `sudo` by default, to disable this use `no_sudo` flag:\n\n    $ sparrowdo --docker=brave_cat --no_sudo # We don't need sudo on docker\n\n## Various types of target hosts\n\nOnce sparrowfile is created it could be run on target host.\n\nSsh host:\n\n    $ sparrowdo --host=192.168.0.1\n\nDocker container:\n\n    $ sparrowdo --docker=old_dog\n\nLocalhost:\n\n    $ sparrowdo --localhost\n\n## Repositories\n\nSparrowdo use Sparrow6 repository to download tasks that are executed on target hosts.\n\nDuring scenario execution Sparrowdo pulls plugins from repository and runs it _with parameters_.\n\nPlugin that gets run with parameters is a Sparrow6 task.\n\n* Detailed explanation of Sparrow6 tasks is available at [Sparrow6 development](https://github.com/melezhik/Sparrow6/blob/master/documentation/development.md) documentation.\n* Detailed explanation of Sparrow6 plugins  [Sparrow6 plugins](https://github.com/melezhik/Sparrow6/blob/master/documentation/plugins.md) documentation\n* Detailed explanation of Sparrow6 repositories is available at [Sparrow6 repositories](https://github.com/melezhik/Sparrow6/blob/master/documentation/repository.md) documentation.\n\nBy default local repository located at `~/repo` is used:\n\n    $ sparrowdo --host=192.168.0.1 #  using repo ~/repo\n\nUse `--repo` flag to set repository URI. For example:\n\n    $ sparrowdo --repo=file:///tmp/repo --localhost # use /tmp/repo repository for local mode\n\n    $ docker run --name --name=fox -d sh -v /tmp/repo:/var/data\n\n    $ sparrowdo --repo=/var/data --docker=fox --repo=file://var/data # mount /tmp/repo to /var/data within docker instance\n\n    $ sparrowdo --repo=http://sparrow.repo # use http repository\n\nSsh mode supports synchronizing local file repositories with master and target host using scp.\nIt extremely useful if for some reason you can't use http based repositories:\n\n    # scp local repository /tmp/repo to target host\n    # and use it within target host\n\n    $ sparrowdo --sync=/tmp/repo --host=192.168.0.1\n\n\nRead [Sparrow6 documentation](https://github.com/melezhik/Sparrow6/blob/master/documentation/repository.md)\nto know more about Sparrow6 repositories.\n\n# Sparrowdo files anatomy\n\nWhen Sparrowdo scenario executed there are might be _related_ that get _copied_ to a target host,\nfor convenience, so that one can reliably refer to those files inside Sparrowdo scenario.\n\nThus Sparrowdo _project_ might consists of various files and folders:\n\n    .\n    ├── conf\n    │   └── alternative.pl6\n    ├── config.raku\n    ├── vars\n    │   └── vars.env\n    ├── data\n    │   └── list.dat\n    ├── tasks\n    │   └── install\n    │       └─── task.bash\n    ├── files\n    │   └── baz.txt\n    ├── sparrowfile\n    └── templates\n        └── conf.tt\n\n* `sparrowfile`\n\nThe minimal setup is just `sparrowfile` placed in the current working directory.\n\nThat file contains Sparrowdo scenario to be executed.\n\nOne may optionally define other data that make up the whole set up:\n\n* `conf`\n\nDirectory to hold configuration files\n\n* `config.raku` \n\nDefault configuration file, if placed in current working directory will define Sparrowdo configuration, see\nalso [scenarios configuration](#scenario-configuration) section, alternatively one may place configuration file to `conf` directory and\nchoose to run with that file:\n\n\n    $ sparrowdo --conf=conf/alternative.pl6\n\n* `vars`\n\nDirectory containing file with some environment variables, for example:\n\n`vars/vars.env`\n\n```bash\n#!bash\nexport NAME=alexey\nexport LASTNAME=melezhik\n```\n\nTo use variables either reference them through tags:\n\n```\nsparrowdo --tags name=.env[NAME],lastname=.env[NAME] --host admin.panel\n```\n\nAnd then:\n\n```raku\n#!raku\n\nsay tags()\u003cname\u003e; # alexey\nsay tags()\u003clastname\u003e; # melezhik\n```\n\nOr use standard Rakulang `%*ENV` syntax:\n\n```raku\n#!raku\n\nsay %*ENV\u003cNAME\u003e; # alexey\nsay %*ENV\u003cLASTNAME\u003e; # melezhik\n```\n\n\nTo use host specific env files, use `vars/vars.host-foo.bar.baz.env` format, for example:\n\n`vars/vars.host-192.168.0.0.1.env` will use  env vars from this file if `--host` parameter is set to `192.168.0.1` during sparrowdo run \n\n\nTo override location of vars file use SPARROWDO_ENV_FILE variable:\n\n```bash\nexport SPARROWDO_ENV_FILE=~/vars\n```\n\nThis will force sparrowdo to look for env files in `~/vars` instead of `vars/`\n\n* `files`\n\nDirectory containing files, so one could write such a scenario:\n\n    file \"/foo/bar/baz.txt\", %( source =\u003e \"files/baz.txt\" )\n\n* `tasks`\n\nDirectory containing tasks files, for example for `tasks/install/task.bash`\nsparrow task:\n\n    task-run \"tasks/install\";\n\n* `templates`\n\nThe same as `files` directory, but for templates, technically `templates` and `files` as equivalent, but\nnamed separately for logical reasons. Obviously one can populate templates using that directory:\n\n\n    template-create '/var/data/animals.txt', %(\n      source =\u003e ( slurp 'templates/animals.tmpl' ),\n      owner =\u003e 'zookeeper',\n      group =\u003e 'animals' ,\n      mode =\u003e '644',\n      variables =\u003e %(\n        name =\u003e 'red fox',\n        language =\u003e 'English'\n      ),\n    );\n\n* `data`\n\nThe same as `files` and `templates` folder but to keep \"data\" files, just another folder\n to separate logically different pieces of data:\n\n\n    file \"/data/list.txt\", %( source =\u003e \"data/list.dat\" )\n\n# Scenario configuration\n\nIf `config.raku` file exists at the current working directory it _will be\nloaded_ via Raku [EVALFILE](https://docs.raku.org/routine/EVALFILE) at the _beginning_ of scenario. \n\nFor example:\n\n    $ cat config.raku\n\n    {\n      user         =\u003e 'foo',\n      install-base =\u003e '/opt/foo/bar'\n    }\n\nLater on in the scenario you may access config data via `config` function, that returns\nconfiguration as Raku Hash object:\n\n    $ cat sparrowfile\n\n    my $user         = config\u003cuser\u003e;\n    my $install-base = config\u003cinstall-base\u003e;\n\nTo refer configuration files at arbitrary location use `--conf` parameter:\n\n    $ sparrowdo --conf=conf/alternative.conf\n\nSee also [Sparrowdo files anatomy](#sparrowdo-files-anatomy) section.\n\n# Including other Sparrowdo scenarios\n\nBecause Sparrowdo scenarios are Raku code files, you're free to include other scenarios into\n\"main\" one using via Raku [EVALFILE](https://docs.raku.org/routine/EVALFILE) mechanism:\n\n\n    $ cat sparrowfile\n\n    EVALFILE \"another-sparrowfile\";\n\nIncluding another scenario does not include related files (`data`, `files`, `templates`) into main one,\nso you can only reuse Sparrowdo scenario itself, but not it's _related_ files.\n\n# Bootstrap and manual install\n\nTo ensure that target hosts has all required Sparrow6 dependencies one may choose bootstrap mechanism that\ninstalls those dependencies on target host. This operation is carried out under `sudo`.\n\nBootstrap is disabled by default and should be enabled by `--bootstrap` option:\n\n    $ sparrowdo --host=192.168.0.1 --bootstrap\n\nBe aware that all dependencies will be installed _system wide_ rather then user account, because `sudo` is used.\n\nif you don't want bootstrap target host, you can always choose to install Sparrow6 zef module \non target host, which is enough to start using Sparrowdo to manage target host:\n\n    $ zef install Sparrow6\n\n# Run Sparrowdo on docker\n\nSparrowdo supports docker as target host, just refer to running docker container by name to\nrun Sparrowdo scenario on it:\n\n    $ sparrowdo --docker=running-horse\n\nIf you need to pull an image first and then run docker container\nfor this image, choose `--image` option:\n\n    $ sparrowdo --docker=running-horse --image=alpine:latest --bootstrap --no_sudo\n\n# Run Sparrowdo on ssh hosts\n\nThis is probably one the most common use case for Sparrowdo - configuring servers by ssh:\n\n    $ sparrowdo --host=192.168.0.1\n\n# Run Sparrowdo in local mode\n\nIn case you need to run sparrowdo on localhost use `--localhost` flag:\n\n    $ sparrowdo --localhost\n\n# Safe mechanism to pass secrets\n\nSparrowdo allow safely pass secrets to remote ssh host by using secret files:\n\nCreate file with some secrets in Bash format, pay attention, variables should be exported:\n\n`nano ~/secrets.env`\n\n```\nexport LOGIN=admin\nexport PASSWORD=12345\n```\n\nUse `--secretsfile` option to specify file:\n\n```bash\nsparrowdo --secretsfile ~/secrets.env\n```\n\nSparrowdo will copy file on remote host, source it exporting declared Bash variables and remove immediately,\nso file won't be kept on remote host. Bash variables are available in Sparrowdo scenario using standard\nRakulang `%*ENV` notation:\n\n\n```raku\nsay %*ENV\u003cLOGIN\u003e;\nsay %*ENV\u003cPASSWORD\u003e;\n```\n\nFor convenience, secrets could be passed in `vars/` format using tags:\n\n```bash\nsparrowdo --secretsfile ~/secrets.env --tags user=.env[LOGIN],password=.env[PASSWORD]\n```\n\n```raku\nsay tags()\u003cuser\u003e; # the same as %*ENV\u003cLOGIN\u003e;\nsay tags()\u003cpassword\u003e; # the same as %*ENV\u003cPASSWORD\u003e;\n```\n\n\n# Sparrowdo cli \n\n`sparrowdo` is Sparrowdo cli to run Sparrowdo scenarios, it accepts following arguments:\n\n* `--version`\n\nShow version and exit\n\n* `--host`\n\nOne of two things:\n\nSsh host to run Sparrowdo scenario on. Default value is `127.0.0.1`. For example:\n\n      --host=192.168.0.1\n\nPath to raku file with hosts configuration. For example:\n\n      --host=hosts.raku\n\nThis will effectively runs Sparrowdo in asynchronous mode through Sparky backend.\n\nSee [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md) doc.\n\n* `--workers`\n\nNumber of asynchronous workers when run in asynchronous mode through Sparky backend\n\nSee [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md) doc.\n\n* `--watch`\n\nRuns watcher job\n\nSee [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md#watcher-jobs) doc.\n\n* `--docker`\n\nName of docker container to run sparrowdo scenario on, to run docker container first\nafter pulling an image use `--image` option\n\n* `--localhost`\n\nIf set, runs Sparrowdo in localhost, in that case Sparrow6 tasks get run directly without launching ssh.\n\n* `--with_sparky`\n\nIf set, run in asynchronous mode through Sparky backend.\n\nSee [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md#watcher-jobs) doc.\n\n* `--desc`\n\nSet a descriptive name to a build, only works when run in asynchronous mode through Sparky backend\n\n* `--ssh_user`\n\nIf set defines ssh user when run Sparrowdo scenario over ssh, none required.\n\n* `--ssh_port`\n\nIf set defines ssh port to use  when run Sparrowdo scenario over ssh. Default value is 22.\n\nIf set, run Sparrowdo scenario on localhost, don't confuse with `--host=127.0.0.1` which\nruns scenario on the machine but using ssh.\n\n* `--repo`\n\nDefines Sparrow6 repository `URI`, for example:\n\n    --repo=https://192.168.0.1 # Remote http repository\n\n    --repo=file:///var/data/repo # Local file system repository\n\nIf `--repo` is not set, Sparrowdo uses default local repository located at `~/repo` path.\n\nSparrowdo uses repository to pull plugins from, see also [Sparrowdo workflow](#sparrowdo-workflow) section.\n\nSee also [Sparrow6 Repositories](https://github.com/melezhik/Sparrow6/blob/master/documentation/repository.md)\ndocumentation.\n\n* `--sync`\n\nIf set synchronize local file system repository with target hosts using `scp`, it's useful if for some reasons\nremote http repositories are not available or disable, so one can _automatically copy_ repository from master host\nto target. `--sync` parameter value should file path pointing repository directory at master host:\n\n    --sync=/var/data/repository\n\n* `--no_index_update`\n\nIf set, don't request Sparrow6 repository update. Useful when in limited internet and using http based remote repositories.\n\n* `--dry_run`\n\nRuns in dry run mode. Only applies when run in asynchronous mode through a Sparky backend.\n\nSee [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md) doc.\n\n* `--tags`\n\nSet host(s) tags, see [Sparky integration](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md) doc.\n\n* `--color`\n\nEnable color output. Disabled by default.\n\n* `--verbose`\n\nIf set print additional information during Sparrowdo scenario execution.\n\n* `--debug`\n\nIf set, runs Sparrow6 tasks in `debug` mode, giving even more information, during scenario execution.\n\n* `--prefix`\n\nIf set, define path to be appending to local cache directory on target host, used predominantly \nwhen running concurrent Sparrowdo scenario on one target host, for example in Sparky CI server.\nNone required, no default value.\n\n# Advanced topics\n\n[Run Sparrowdo scenarios in asynchronous mode, using Sparky backend](https://github.com/melezhik/sparrowdo/blob/master/doc/sparky-integration.md)\n\n# Author\n\nAlexey Melezhik\n\n# See also\n\n* [Sparrow6](https://github.com/melezhik/Sparrow6)\n\n# Thanks\n\nTo God as the One Who inspires me to do my job!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmelezhik%2Fsparrowdo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmelezhik%2Fsparrowdo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmelezhik%2Fsparrowdo/lists"}