{"id":14008241,"url":"https://github.com/sshoogr/sshoogr","last_synced_at":"2025-12-17T01:50:07.141Z","repository":{"id":7951277,"uuid":"9346373","full_name":"sshoogr/sshoogr","owner":"sshoogr","description":"A Groovy-based DSL for working with remote SSH servers.","archived":false,"fork":false,"pushed_at":"2023-03-22T16:36:11.000Z","size":2097,"stargazers_count":354,"open_issues_count":30,"forks_count":55,"subscribers_count":40,"default_branch":"main","last_synced_at":"2024-05-19T05:26:19.103Z","etag":null,"topics":["config-management","dsl","groovy","ssh","ssh-client"],"latest_commit_sha":null,"homepage":"","language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshoogr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2013-04-10T13:10:53.000Z","updated_at":"2024-05-16T16:34:58.000Z","dependencies_parsed_at":"2024-01-03T01:33:03.274Z","dependency_job_id":null,"html_url":"https://github.com/sshoogr/sshoogr","commit_stats":{"total_commits":295,"total_committers":18,"mean_commits":16.38888888888889,"dds":"0.14915254237288134","last_synced_commit":"1f81e3f4ac5be170b9ccad8ff8e6ef48f31c1ac8"},"previous_names":["aestasit/sshoogr"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshoogr%2Fsshoogr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshoogr%2Fsshoogr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshoogr%2Fsshoogr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshoogr%2Fsshoogr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshoogr","download_url":"https://codeload.github.com/sshoogr/sshoogr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["config-management","dsl","groovy","ssh","ssh-client"],"created_at":"2024-08-10T11:01:29.958Z","updated_at":"2025-12-17T01:50:02.071Z","avatar_url":"https://github.com/sshoogr.png","language":"Groovy","funding_links":[],"categories":["Groovy","网络编程"],"sub_categories":[],"readme":"# sshoogr\n\n![GitHub Workflow Status](https://github.com/sshoogr/sshoogr/workflows/Build/badge.svg)\n![ASL2 Licensed](http://img.shields.io/badge/license-ASL2-blue.svg)\n![Latest Version](https://api.bintray.com/packages/sshoogr/sshoogr/sshoogr/images/download.svg)\n\n## Overview\n\nThe `sshoogr` (pronounced `[ʃʊgə]`) is a **Groovy**-based **DSL** library for working with remote servers through **SSH**. The **DSL** allows:\n\n- connecting,\n- executing remote commands,\n- copying files and directories,\n- creating tunnels in a simple and concise way.\n\nThe library was jointly developed by **Aestas/IT** (http://aestasit.com) and **NetCompany A/S** (http://www.netcompany.com/) to support the quickly growing company's operations and hosting department.\n\n### Installing `sshoogr` with SDKMAN!\n\nThe simplest way to use `sshoogr` from the command line is by using [SDKMAN!](http://sdkman.io).\n\nIf SDKMAN is not yet installed, open a terminal and enter the following:\n\n    $ curl -s get.sdkman.io | bash\n\nFollow the instructions presented in the terminal, then enter the following command:\n\n    $ sdk install sshoogr\n\nThis will install the `sshoogr` and make it available on your path.\n\n### Using `sshoogr` in Groovy scripts\n\nThe easiest way to use `sshoogr` in a **Groovy** script is by importing the dependency using [Grape](http://groovy.codehaus.org/Grape).\n\n```groovy\n@Grab('com.aestasit.infrastructure.sshoogr:sshoogr:0.9.28')\nimport static com.aestasit.infrastructure.ssh.DefaultSsh.*\n```\n\nThe entry point for using the **DSL** is the `remoteSession` method, which accepts an **SSH** **URL** and a closure with **Groovy** or **DSL** code:\n\n```groovy\nremoteSession('user2:654321@localhost:2222') {\n  exec 'rm -rf /tmp/*'\n  exec 'touch /var/lock/my.pid'\n  remoteFile('/var/my.conf').text = \"enabled=true\"\n}\n```\n\nFor more use cases, please refer to the following sections or to the `examples` folder in this repository.\n\n### Remote connections\n\nThe `remoteSession` method accepts an **SSH** **URL** and a closure, for example:\n\n```groovy\nremoteSession(\"user:password@localhost:22\") {\n  //...\n}\n```\n\nInside the closure you can execute remote commands, access remote file content, upload and download files, create tunnels.\n\nIf your connection settings were set with the help of default configuration (see \"Configuration options\" section),\nthen you can omit the **URL** parameter:\n\n```groovy\nremoteSession {\n  //...\n}\n```\n\nFurthermore, it is possible to override the default values in each session by directly assigning `host`, `username`, `password` and `port` properties:\n\n```groovy\nremoteSession {\n\n  host = 'localhost'\n  username = 'user2'\n  password = '654321'\n  port = 2222\n\n  //...\n\n}\n```\n\nThe **SSH**'s **URL** can be also assigned from withing the remote session declaration, like so:\n\n```groovy\nremoteSession {\n\n  url = 'user2:654321@localhost:2222'\n\n  //...\n\n}\n```\n\nThe actual connection to the remote host will be executed upon the first command or file access, and, naturally, the connection will be\nautomatically closed after the code block terminates.\n\nYou can explicitly call `connect` or `disconnect` methods to control this behavior:\n\n```groovy\nremoteSession {\n\n  // explicitly call connect\n  connect()\n\n  // do some stuff ...\n\n  // explicitly disconnect\n  disconnect()\n\n  // explicitly connect again\n  connect()\n\n  //...\n\n}\n```\n\nIn the next section, we will see how to execute remote commands.\n\n### Executing commands\n\nThe simplest way to execute a command within a remote session is by using the `exec` method that just takes a command string:\n\n```groovy\nremoteSession {\n  exec 'ls -la'\n}\n```\n\nYou can also pass a list of commands in an array:\n\n```groovy\nexec([\n  'ls -la',\n  'date'\n])\n```\n\nThe `exec` behavior can also be controlled with additional named parameters given to the method. For example, in order\nto hide commands output, you can use the following syntax:\n\n```groovy\nexec(command: 'ls –la', showOutput: false)\n```\n\nThe additional Parameter names are specified in the \"Configuration options\" section for the `execOptions`. They can all\nbe used to override default settings for specific commands.\n\nIn the same way, you can also define common parameters for a block of commands passed as an array:\n\n```groovy\nexec(showOutput: false, command: [\n  'ls -la',\n  'date'\n])\n```\n\nAlso you can get access to command output, exit code and exception thrown during command execution. This can be useful\nfor implementing logic based on a result returned by the remote command and/or parsing of the output. For example,\n\n```groovy\ndef result = exec(command: '/usr/bin/mycmd', failOnError: false, showOutput: false)\nif (result.exitStatus == 1) {\n  result.output.eachLine { line -\u003e\n    if (line.contains('WARNING')) {\n      throw new RuntimeException(\"Warning!!!\")\n    }\n  }\n}\n```\n\nTwo additional methods that you can use around your commands are `prefix` and `suffix`. They are similar to using the `prefix`\nand `suffix` options in `execOptions` or named parameters to `exec` method.\n\n```groovy\nprefix(\"sudo\") {\n  exec 'ls -la'\n  exec 'df -h'\n}\n```\n\nAnd with `suffix`:\n\n```groovy\nsuffix(\"\u003e\u003e output.log\") {\n  exec 'ls -la'\n  exec 'df -h'\n  exec 'date'\n  exec 'facter'\n}\n```\n \n### File uploading/downloading\n\nThe simplest way to modify a remote text file content is by using `remoteFile` method, which returns a remote\nfile object instance, and assign some string to the `text` property:\n\n```groovy\nremoteFile('/etc/yum.repos.d/puppet.repo').text = '''\n  [puppet]\n  name=Puppet Labs Packages\n  baseurl=http://yum.puppetlabs.com/el/$releasever/products/$basearch/\n  enabled=0\n  gpgcheck=0\n'''\n```\n\nEach line of the input string will be trimmed before it's copied to the remote file.\nFor text file downloading you can just read the `text` property:\n\n```groovy\nprintln remoteFile('/etc/yum.repos.d/puppet.repo').text\n```\n\nUploading of a single file can be done in the following way:\n\n```groovy\nscp \"$buildDir/test.file\", '/tmp/test.file'\n```\n\nThis method only works for file uploading (from local environment to remote). You can also write the example above\nin a more verbose form with the help of closures:\n\n```groovy\nscp {\n  from { localFile \"$buildDir/test.file\" }\n  into { remoteFile '/tmp/test.file' }\n}\n```\n\nA whole directory can be uploaded by using the `remoteDir` and `localDir` methods of `scp`.\n\n```groovy\nscp {\n  from { localDir \"$buildDir/application\" }\n  into { remoteDir '/var/bea/domain/application' }\n}\n```\n\nIn similar fashion, you can download directories and files:\n\n```groovy\nscp {\n  from { remoteDir '/etc/nginx' }\n  into { localDir \"$buildDir/nginx\" }\n}\n```\n\nYou can also copy multiple sources into multiple targets:\n\n```groovy\nscp {\n  from {\n    localDir \"$buildDir/doc\"\n    localFile \"$buildDir/readme.txt\"\n    localFile \"$buildDir/license/license.txt\"\n  }\n  into {\n    remoteDir '/var/server/application'\n    remoteDir '/repo/company/application'\n  }\n}\n```\n\nDuring any upload/download operation, local and remote directories will be created automatically.\n\n### Tunneling\n\nIf inside your build script you need to get access to a remote server that is not visible directly from the local\nmachine, then you can create a tunnel to that server by using the `tunnel` method:\n\n```groovy\ntunnel('1.2.3.4', 8080) { int localPort -\u003e\n  //...\n}\n```\n\nAll code executed within the closure passed to the tunnel method will have access to a server tunnel running on `localhost`\nand randomly selected `localPort`, which is passed as a parameter to the closure. Inside that tunnel code you can, for\nexample, deploy a web application or send some **HTTP** command to remote server:\n\n```groovy\ntunnel('1.2.3.4', 8080) { int localPort -\u003e\n  def result = new URL(\"http://localhost:${localPort}/flushCache\").text\n  if (result == 'OK') {\n    println \"Cache is flushed!\"\n  } else {\n    throw new RuntimeException(result)\n  }\n}\n```\n\nThe tunnel will be closed upon closure completion.\nAlso, you can define a local port yourself in the following way:\n\n```groovy\ntunnel(7070, '1.2.3.4', 8080) {\n  def result = new URL(\"http://localhost:7070/flushCache\").text\n  //...\n}\n```\n\n### Configuration options\n\nThe following list gives an overview of the available configuration options:\n\n - `defaultHost`, `defaultUser`, `defaultPassword`, `defaultPort` (defaults to 22) - Default host, user name, password or port to use in remote connection in case they are not specified in some other way (through `url`, `host`, `port`, `user` or `password` properties inside the `remoteSession` method).\n - `defaultKeyFile` - Default key file to use in remote connection in case it is not specified through the `keyFile` property inside the `remoteSession` method.\n - `failOnError` (defaults to true) - If set to true, failed remote commands and file operations will throw an exception.\n - `verbose` (defaults to false) - If set to true, the library produces more debug output.\n\nThe `sshOptions` may also contain a nested `execOptions` structure, which defines remote command execution (see\n\"Executing commands\" section) options. It has the following properties:\n\n - `showOutput` (defaults to true) - If set to true, remote command output is printed.\n - `showCommand` (defaults to true) - If set to true, remote command is printed.\n - `hideSecrets` (defaults to true) - If set to true, secret Strings contained in ExecOptions.secrets will be redacted from output and replaced by `********`.\n - `secrets` (defaults to [ ]) - a list of secret Strings to be redacted from output\n - `maxWait` (defaults to 0) - Number of milliseconds to wait for command to finish. If it is set to 0, then library will wait forever.\n - `succeedOnExitStatus` (defaults to 0) - Exit code that indicates commands success. If command returns different exit code, then build will fail.\n - `failOnError` (defaults to true) - If set to true, failed remote commands will fail the build.\n - `verbose` (defaults to false) - If set to true, library produces more debug output.\n - `prefix` - String to prepend to each executed command, for example, \"`sudo`\".\n - `suffix` - String to append to each executed command, for example, \"`\u003e\u003e output.log`\".\n\nThere is also a nested `scpOptions` structure, which defines remote file copying options (see \"File uploading/downloading\"\nsection). It has the following properties:\n\n - `failOnError` (defaults to true) - If set to true, failed file operations will fail the build.\n - `showProgress` (defaults to false) - If set to true, library shows additional information regarding file upload/download progress.\n - `verbose` (defaults to false) - If set to true, library produces more debug output.\n\n### Advanced usage\n\n#### Creating a `SshDslEngine` instance\n\nIf you need to embed `sshoogr` into your own **DSL** or another library you may need to use internal classes instead of default static methods. The main library's classes are `SshDslEngine` and `SshOptions`, which need to be imported before the library can be used:\n\n```groovy\nimport com.aestasit.infrastructure.ssh.dsl.SshDslEngine\nimport com.aestasit.infrastructure.ssh.SshOptions\n```\n\nTo create a simple instance of the engine with the default options you can just use the following instruction:\n\n```groovy\ndef engine = new SshDslEngine(new SshOptions())\n```\n    \nThe `engine` instance gives access to the `remoteSession` method.\n\n#### Populating `SshOptions`\n\nA more verbose example of creating a `SshOptions` object can be found below:\n\n```groovy\nimport com.aestasit.infrastructure.ssh.log.SysOutLogger\n\n//...\n\noptions = new SshOptions()\noptions.with {\n\n  logger = new SysOutLogger()\n\n  defaultHost = '127.0.0.1'\n  defaultUser = 'user1'\n  defaultPassword = '123456'\n  defaultPort = 2233\n\n  reuseConnection = true\n  trustUnknownHosts = true\n\n  execOptions.with {\n    showOutput = true\n    failOnError = false\n    hideSecrets = true\n    secrets = ['secret1']\n    succeedOnExitStatus = 0\n    maxWait = 30000\n  }\n\n  scpOptions.with {\n    verbose = true\n    showProgress = true\n  }\n\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshoogr%2Fsshoogr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshoogr%2Fsshoogr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshoogr%2Fsshoogr/lists"}