pmctl

Control tool for Power Manager.

Synopsis

pmctl -browse -format ``( plist json)`` -h -help -legal -netrc path -u URL -url URL -v -verbose -version

Description

pmctl is a tool for managing DssW Power Manager.

pmctl is used to connect to and control Power Manager. pmctl is the main command line tool for interacting with local and remote Power Manager instances.

pmctl can send requests to Power Manager. Responses can be displayed in common script friendly formats.

If no URL is provided, pmctl will connect to the default instance of Power Manager. The default is typically the local instance of Power Manager.

A provided URL must include a pm:// or dnssd:// scheme. The file path form is used to connect with older local versions of Power Manager through a UNIX domain socket.

IPv6 shorthand notation is supported. The IPv6 loopback address can be written as [::1].

./pmctl
./pmctl -u pm://192.168.1.40:4567
./pmctl -u pm://localhost:4567
./pmctl -u pm://[::1]:4567
./pmctl -u pm:/var/tmp/uk.co.dssw.powermanager/pmd
./pmctl -u dnssd://Mac-Pro
./pmctl -u dnssd://Mac-Pro.local.

A range of URL schemes are supported by pmctl

pmctl can connect to Bonjour/ZeroConf advertised Power Manager services. Use the dnssd:// scheme to provide the service name to resolve and connect to.

By default, Bonjour service name resolution occurs within the local. domain. Append the domain to the URL dnssd://Mac-Pro.other-domain. to provide an alternative domain to resolve service names with.

./pmctl build.version

Get the version details of the local Power Manager instance.

Sets of parameters can be associated with a request. A parameter consists of a name and value pair.

name=value

Base parameter format.

./pmctl scheduler.setenabled enabled=true

Enable the scheduler with a request and parameter.

Parameters containing spaces must be quoted to avoid the shell splitting the contents:

./pmctl scheduler.remove 'unique ID=Weekend Sleep'

Parameters with spaces must be quoted.

Preprocessed Parameters

Parameters may be preprocessed using parentheses. Preprocessed parameters expand the range of input pmctl can use when building a request. They allow for parameters to be read from files, remote resources, and for pass phrases to be securely requested from the command line.

Some complex parameters must be preprocessed. These parameters include those that require structures or arrays.

./pmctl scheduler.set event=(plist:file:///Users/Shared/event.plist)

Set an event using the contents of a local property list file.

Permitted formats include:

Remote Parameters

A parameter can be fetched from a file path or a URL:

./pmctl eventstore.store events=(plist:https://example.com/events.plist)

Using a remote property list as a parameter.

Remote parameters can also be encoded as plain text or JavaScript Object Notation (JSON). These formats contain less structured information and will likely require additional type coercion:

name=(json:URL)
name=(plain:URL)

Alternative parameter formats.

The URL may refer to local or remote resources:

./pmctl scheduler.set event=(plist:file:///Users/Shared/event.plist)
./pmctl scheduler.set event=(plist:http://www.example.com/event.plist)
./pmctl scheduler.set event=(plist:https://www.example.com/event.plist)

A range of URL schemes are supported for getting property lists.

URLs may be escape encoded. Relative file scheme URLs are evaluated using the current working directory as the base location.

Raw Parameters

A parameter may need to include contents that match pmctl’s preprocessing format. To avoid preprocessing content, use the raw preprocessor:

'name=(raw:contents)'

Base raw parameter format.

The brackets and prefixed raw will be removed, but the contents will be untouched and passed through as the parameter.

If an event has the unique ID (plist:file:///tmp/), the following command will issue an appropriate remove request:

./pmctl scheduler.remove 'unique ID=(raw:(plist:file:///tmp/))'

Remove an event with the unique ID: (plist:file:///tmp/).

Multiple Requests

Multiple requests can be sent by appending the requests to the command. A single connection is created and the requests are issued in the order provided on the command line.

pmctl sends one request at a time. pmctl may interrupt the requests, if authentication is required by the Scheduler. In this case, the authentication must be completed successfully before the remaining requests are sent.

Responses to multiple requests are grouped and output as a dictionary or an associative array:

./pmctl build.version notifications.warningperiod notifications.notifyperiod
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>build.version</key>
        <string>uk.co.dssw.powermanager.pmd v5.0.0</string>
        <key>notifications.notifyperiod</key>
        <integer>900</integer>
        <key>notifications.warningperiod</key>
        <integer>3</integer>
    </dict>
</plist>

Multiple requests are supported. Responses are returned as dictionaries.

Character Encoding

All character encoding and input is assumed to be UTF8. Providing input in other encodings may can authentication to fail.

UTF8 encoding is the default for macOS’s Terminal.app application.

Parameter Coercion

Parameters need to passed to Power Manager in specific formats. All parameters provided directly from command line arguments are strings; in many cases strings are not the appropriate format.

Type coercion is limited in the possible conversions that can be performed. Where a conversion is not possible, the original parameter is left untouched. In this situation the request is expected to fail with an error message explaining which parameter is invalid.

pmctl can coerce parameters manually by extending the request format.

./pmctl scheduler.setenabled enabled:boolean=true

Coerce the parameter enabled from a string to a boolean.

To coerce a parameter, insert a final parameter type into the request before the equals symbol. Supported types include:

Return Values

pmctl returns EXIT_SUCCESS, 0 if a connection is established. EXIT_FAILURE is returned if no connection could be established, or authentication failed.

The return value can be used to test if Power Manager is available locally, or at a specified address.

#!/bin/sh

`./pmctl`
if [ "$?" -ne "0" ]; then
  echo "Power Manager is not available"
else
  echo "Power Manager is available"
fi

Shell script to test pmctl’s return value.

#!/bin/sh

`./pmctl -u pm://192.168.1.1:1234` && ( echo "Power Manager is available" ) || ( echo "Power Manager is not available" )

One line shell script to test pmctl’s return value.

pmctl’s return value can not be used to determine the success or failure of a request. The success or failure of a request can be determined by the response returned.

Authentication and Authorisation

Authorisation is required for Power Manager requests that access privileged information or make device wide changes. By default, only device administrators can make these restricted requests.

Authentication determines who is making the request. Authorisation determines who can make the request.

By default, the authentication process delegated to the device’s Pluggable Authentication Module (PAM) implementation. Prompts and messages from PAM are passed to the client for interactive responses.

Avoiding Interactive Authentication

When writing scripts or tools that use pmctl as a client, being able to avoid an interactive prompt is often essential.

Power Manager and pmctl support multiple methods of authentication.

netrc

pmctl can use a netrc file to provide credentials. A netrc file is a specially formatted text file containing device credentials that are used for login and password based PAM requests.

A minimal netrc file contains a single login (hello) and password (world) pair:

default
    login hello
    password world

Sample netrc file format.

To use a netrc file with pmctl, use the -netrc flag and pass the path to the netrc file:

./pmctl -netrc ~/netrc.txt

Pass a netrc file to pmctl.

To use a netrc file when disabling the scheduler, the pmctl command becomes:

./pmctl -verbose -netrc ~/netrc.txt scheduler.setenabled enabled:boolean=false

Pass a netrc file to pmctl command to disable the scheduler.

The netrc approach works for authentication prompts that include login: and password: prompts. If the device uses a non-standard or multilingual prompt, the netrc approach will not be able to respond appropriately.

Client Side Certificates

Power Manager supports client side Transport Layer Security (TLS) certificates for authentication.

A certificate can be associated with a specific user. When the certificate is used to connect to Power Manager, the associated user will be considered to be making the requests with no additional authentication.

This approach allows a certificate to avoid storing plain text credentials and is the preferred method of non-interactive authentication.

Creating a Client Certificate

To associate a certificate with a user, a TLS certificate pair is required.

The certificate pair can be created using a wide range of tools. Power Manager will evaluate the certificate but does not enforce hostname validity; this allows self-signed certificates to be used.

To create a certificate pair using the widely available openssl, issue the command:

/usr/bin/openssl req -new -utf8 -x509 -days 3650 -newkey rsa:2048 -sha256 -nodes -keyout 'key.pem' -out 'certificate.pem'

When prompted, providing * for the Common Name and leaving all other fields blank, ., will result in a well-formed self-signed certificate.

The openssl command above will create two files:

Both files need to be passed to pmctl to authenticate the connection using a client side certificate.

Associating a Client Certificate

To associate a certificate pair with a user, issue this command to pmctl:

./pmctl -verbose -authenticate-on-connect -client-certificate certificate.pem -client-key key.pem

Associate a client certificate with a user.

pmctl will prompt for to authentication the first time an unseen client certificate is used. If the authentication is successful, the certificate will be associated with that user.

Both the certificate and key must be passed by the -client-certificate and -client-key flags with every connection.

The certificate pair remains associated with the user indefinitely and can be used to avoid interactive authentication.

To use a client certificate when disabling the scheduler, the pmctl command becomes:

./pmctl -verbose -client-certificate certificate.pem -client-key key.pem scheduler.setenabled enabled:boolean=false

Use a client certificate with pmctl to disable the scheduler.

Certificate pairs can be copied to other devices and used by multiple scripts without needing to disclose authentication credentials. This approach can be useful for administrators wishing to provide non-administrators with access to Power Manager, but without involving the non-administrator user with the client certificate process.

Files