{"id":8855,"date":"2017-02-12T02:09:39","date_gmt":"2017-02-12T02:09:39","guid":{"rendered":"https:\/\/kb.okra.host\/article\/scripting-with-beacon\/"},"modified":"2021-04-06T14:42:59","modified_gmt":"2021-04-06T13:42:59","slug":"scripting-with-beacon","status":"publish","type":"ht_kb","link":"https:\/\/kb.okra.host\/de\/article\/scripting-with-beacon\/","title":{"rendered":"Skripting mit Beacon"},"content":{"rendered":"<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1411\" style=\"border: none\" src=\"https:\/\/kb.apiscp.com\/wp-content\/uploads\/2017\/02\/beacon.png\" alt=\"\" width=\"263\" height=\"58\" \/><\/p>\n<p>Beacon is a scripting companion to <a href=\"https:\/\/kb.apiscp.com\/control-panel\/logging-into-the-control-panel\/\">apnscp<\/a>\u00a0that provides a simple interface to interacting with more than <a href=\"http:\/\/api.apnscp.com\/docs\/\">2,000 commands<\/a>\u00a0exposed in apnscp. If apnscp can do it so can you, minus a pretty interface of course! Beacon may also be downloaded from our <a href=\"https:\/\/github.com\/apisnetworks\/beacon\">github repo<\/a>.<\/p>\n<h2 id=\"getting-started\" >Getting Started<\/h2>\n<p>Beacon requires an API key for authentication. Visit <strong>Dev<\/strong> &gt; <strong>API Keys<\/strong> within <a href=\"https:\/\/kb.apiscp.com\/control-panel\/logging-into-the-control-panel\/\">apnscp<\/a> to create your API key. On first use, specify <code>--key<\/code> to set the key:<\/p>\n<p><code>beacon exec --key=AAAA-BBBB-CCCC-DDDD common_get_web_server_name<\/code><\/p>\n<p>If\u00a0everything went as expected, your domain will be printed out.<\/p>\n<p>Once the key is set, you can skip &#8211;key=&#8230; unless you change the key again, in which case specify &#8211;key=&#8230; and <strong>&#8211;set<\/strong> to overwrite the key. If you&#8217;re running Beacon on your desktop to interact with apnscp, use &#8211;key=&#8230; in conjunction with <strong>&#8211;endpoint<\/strong>=https:\/\/launchpad.url.in.the.panel:2083\/soap. Your endpoint URI is provided in\u00a0<strong>Dev<\/strong> &gt; <strong>API Keys<\/strong>.<\/p>\n<h2 id=\"command-format\" >Command Format<\/h2>\n<p>Each Beacon command consists of the imperative, <code>exec<\/code>, followed by the module name + method name, both in lowercase and delimited by an underscore. For example, to check system load average, which is exposed as &#8220;<a href=\"https:\/\/github.com\/apisnetworks\/apnscp-modules\/blob\/master\/modules\/common.php\">get_load<\/a>&#8221; in the &#8220;Common&#8221; module, it is formatted as common_get_load:<\/p>\n<p><code>beacon exec common_get_load<\/code><\/p>\n<p>Which will return an array of three elements, 1, 5 and 15-minute load averages.<\/p>\n<h2 id=\"parameters\" >Parameters<\/h2>\n<p>Parameters, if necessary, follow command invocation. Primitives are simply passed as-is observing shell <a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/special-chars.html\">special characters<\/a> and <a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/parameter-substitution.html\">variable interpolation<\/a> rules. When working with booleans, use &#8220;0&#8221; instead of &#8220;false&#8221;. Omitted parameters must be explicitly specified with an empty string (&#8220;&#8221;).\u00a0Arrays may either be formatted with or without its numeric indices. Hash keys precede the value. Arrays and hashes are enclosed with &#8220;[]&#8221;, infinitely nested, and hash keys are postfixed with a colon.<\/p>\n<h3 id=\"primitive-examples\" >Primitive examples<\/h3>\n<p><code>beacon exec sql_create_mysql_database test<br \/>\nbeacon exec common_get_service_value siteinfo admin_user<br \/>\nbeacon exec file_chown \/var\/www\/myfile.txt myadmin 1<br \/>\n<\/code><\/p>\n<h3 id=\"array-hash-examples\" >Array\/hash examples<\/h3>\n<p><code>beacon exec file_set_acls \/var\/www\/ myotheruser rwx [recursive:1]<br \/>\nbeacon exec sql_create_mysql_database foobar<br \/>\nbeacon exec wordpress_update_themes mydomain.com \"\" [avada,twentyseventeen]<\/code><\/p>\n<h2 id=\"interpreting-responses\" >Interpreting Responses<\/h2>\n<p>By default, Beacon presents itself in human-readable format with <a href=\"http:\/\/php.net\/print_r\">print_r<\/a>. Use <code>--format=json<\/code> to output the result as JSON and as bash-friendly arrays, <code>--format=bash:<\/code><\/p>\n<p><code>$ beacon exec --format=json common_get_load<\/code><br \/>\n<code>{\"1\":\"0.52\",\"5\":\"0.82\",\"15\":\"0.94\"}<br \/>\n$ beacon exec --format=bash common_get_load<\/code><br \/>\n<code>(['1']='0.47' ['5']='0.81' ['15']='0.94')<\/code><\/p>\n<p>No trailing EOL marker is included in the actual output for ease of parsing.<\/p>\n<h2 id=\"chaining\" >Chaining<\/h2>\n<p>Chaining is the real magic in Beacon. By mixing shell data types and Beacon, it&#8217;s easy to store output and work with it.<\/p>\n<h3 id=\"checking-if-all-wordpress-domains-are-current\" >Checking if all WordPress domains are current<\/h3>\n<p>Iterate over all domains. Check each domain if WordPress is current, update if not.<\/p>\n<pre data-language=\"shell\"><code># () also works in lieu of declare -a...<\/code> <code>declare -a DOMAINS=$(beacon exec \u00a0--format=bash aliases_list_aliases)<\/code> <code>for domain in ${DOMAINS[@]} ; do<\/code> <code>\u00a0 \u00a0 STATUS=$(beacon eval wordpress_is_current $domain)<\/code> <code>\u00a0 \u00a0 if [$STATUS == 0]; then continue ; fi<\/code> <code>\u00a0 \u00a0 beacon wordpress_update $domain\u00a0<\/code> <code>done<\/code><\/pre>\n<h3 id=\"create-an-addon-domain-then-install-wordpress-or-drupal-onto-it\" >Create an addon domain, then install WordPress or Drupal onto it<\/h3>\n<p>Creates a new addon domain, then installs WordPress, Drupal, or any <a href=\"https:\/\/kb.apiscp.com\/control-panel\/detecting-a-web-application\/\">web app<\/a>. &#8220;${n,,}&#8221; takes the parameter\u00a0<em>n\u00a0<\/em>and converts to lowercase in bash v4+ using <a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/parameter-substitution.html#PARAMSUBREF\">case modifiers<\/a>.<\/p>\n<pre>function newdomain {\r\n    domain=${1,,}\r\n    app=${2,,}\r\n    path=\/var\/www\/${domain}\r\n    beacon exec aliases_add_shared_domain $domain $path\r\n    beacon exec aliases_synchronize_changes\r\n    beacon exec ${app}_install $domain \r\n}<\/pre>\n<h2 id=\"introspection\" >Introspection<\/h2>\n<p>Sometimes the publicized name isn&#8217;t too clear. Use <span style=\"color: #222222;font-family: monospace\">show<\/span>\u00a0for code introspection. Introspection fetches code from our <a href=\"https:\/\/github.com\/apisnetworks\/apnscp-modules\/tree\/master\/modules\">GitHub repository<\/a> and uses reflection to get an accurate representation.<\/p>\n<p><code>beacon show common_get_load<\/code><\/p>\n<pre data-language=\"php\"><code>\/**\r\n * array get_load (void)\r\n *\r\n * @privilege PRIVILEGE_ALL\r\n * @return array returns an assoc array of the 1, 5, and 15 minute\r\n * load averages; indicies of 1,5,15\r\n *\/\r\npublic function get_load()\r\n{\r\n        $fp = fopen('\/proc\/loadavg', 'r');\r\n        $loadData = fgets($fp);\r\n        fclose($fp);\r\n        $loadData = array_slice(explode(\" \", $loadData), 0, 3);\r\n        return array_combine(array(1, 5, 15), $loadData);\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Beacon is a scripting companion to apnscp\u00a0that provides a simple interface to interacting with more than 2,000 commands\u00a0exposed in apnscp. If apnscp can do it so can you, minus a pretty interface of course! Beacon may also be downloaded from our github repo. Getting Started Beacon requires an API key&#8230;<\/p>","protected":false},"author":1,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"ht-kb-category":[60],"ht-kb-tag":[],"class_list":["post-8855","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-guides"],"_links":{"self":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb"}],"about":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/comments?post=8855"}],"version-history":[{"count":1,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8855\/revisions"}],"predecessor-version":[{"id":8856,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8855\/revisions\/8856"}],"wp:attachment":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/media?parent=8855"}],"wp:term":[{"taxonomy":"ht_kb_category","embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb-category?post=8855"},{"taxonomy":"ht_kb_tag","embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb-tag?post=8855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}