gitlab service control commands

After installing gitlab from the omnibus install, use the gitlab-ctl command to query status, and start/stop the gitlab service (see here):

$ sudo gitlab-ctl status

If gitlab’s main service has been disabled, all the sub-services will report ‘runsv not running’:

fail: gitaly: runsv not running

You can reset the main service to run at startup with (see here):

sudo systemctl enable gitlab-runsvdir.service

To disable startup at boot:

sudo systemctl disable gitlab-runsvdir.service

If runsvdir is not enabled to start at boot, then start with:

sudo systemctl start gitlab-runsvdir.service

To start/stop gitlab:

$ sudo gitlab-ctl start

$ sudo gitlab-ctl stop

AWS IoT and Node.js on the Raspberry Pi

There are many approaches for installing node.js on the Raspberry Pi (Google and you’ll find lots of guides), presumably because for a while there didn’t seem to be any official binaries in the official apt repos so people were building and sharing their own.

I installed a version from somewhere (can’t actually remember where as it was a while back) and it doesn’t support ES6 class syntax used by some of the dependent libraries in the AWS IoT SDK:

$ node index.js
/home/pi/aws-iot-nodejs-pi-lights/node_modules/aws-iot-device-sdk/node_modules/mqtt/node_modules/websocket-stream/server.js:6
class Server extends WebSocketServer{
^^^^^
SyntaxError: Unexpected reserved word
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/home/pi/aws-iot-nodejs-pi-lights/node_modules/aws-iot-device-sdk/node_modules/mqtt/node_modules/websocket-stream/index.js:2:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)

The version I currently have installed is:

pi@raspberrypi:~ $ node -v
v0.10.29

Since I’m not sure where this version came from originally, (and apt-get upgrade is not finding any updates), I uninstalled:

sudo apt-get remove nodejs
sudo apt-get remove npm

Then I followed the steps in the AWS IoT SDK guide here to install using the version provided from Adafruit’s repo  (official node.js binaries for ARM are also available from nodejs.org here).

With version provided from Adafruit, this gives v 0.12.6 but unfortunately this still gives the same error with the ES6 class keyword.

$ node -v
v0.12.6

Next, lets try the ARM version from nodejs.org. There’s step by step instructions here showing how to download the tar, extract and copy to /usr/local/

Now we have:

$ node -v
v8.9.1

And now trying to run my AWS IoT node.js based app, success!

 

 

Installing SSL certificates for Nginx on Ubuntu

Purchasing an SSL certificate requires creating a Certificate Signing Request (CSR) which you can do on your host using:

openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

When you purchase your certificate from your vendor, you’ll provide the text content from your CSR file. Once you have the certificate files (normally a .crt and a .key file), transfer them to your server, and place them somewhere like /etc/ssl-certs/.

In your /etc/nginx/nginx.conf (or /etc/nginx/sites-enabled/default), add to the server {  } block:

server {
  listen 443 ssl;
  ssl on;
  ssl_certificate     /etc/ssl-certs/yourdomain_com.crt;
  ssl_certificate_key /etc/ssl-certs/yourdomain.com.key;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;
        
  # rest of server config
}

Restart nginx with:

sudo service nginx restart

This is documented in the nginx docs here.

AWS IoT Retrieving SQS Messages from a Queue using an IoT Rule and a Lambda function

AWS IoT Rules have predefined rules for sending a message to an SQS Queue, but for some reason not to retrieve a message from a queue using an IoT rule (or does it? if you know how, leave me a comment). You can easily retrieve a message using a Lambda function using the AWS SDK apis though, and you can call a Lambda function using an IoT Rule, so let’s set that up.

To create an IoT Rule to call the Lambda function, which we’ll trigger with incoming MQTT messages on a topic called topic/checkForMessage:

Next, select an action from the long list of available actions, chose ‘Invoke a Lambda function’:

Select the Lambda function we want to call, in this case it’s one created earlier (it has to exist to show in the list, if not press ‘Create a new Resource’ to create one):

On the next summary screen press ‘Create Rule’ and you’re done:

To allow the IoT Rule to call the function, we need to grant the lambda:invokeFunction rule.

Per the docs, we can use the AWS CLI to add the permission like this:

aws lambda add-permission 
  --function-name "function_name" 
  --region "region" 
  --principal iot.amazonaws.com 
  --source-arn arn:aws:iot:us-east-2:account_id:rule/rule_name 
  --source-account "account_id" 
  --statement-id "unique_id" 
  --action "lambda:InvokeFunction"

To apply this to our function and rule, replace:

“function_name” : “LightsOnReceiveMessageFromQueue”

“region”: “us-east-1”

source-arn arn: aarn:aws:iot:full-arn-for-the-rule – see below

account_id: your-aws-account-id

rule_name: RetrieveSQSMessageFromQueue

“account_id”: “your-account-id”

“unique_id”: unique-id-for-this-permission

I’m not sure the AWS Console for IoT shows the ARN for IoT Rules anywhere in it’s pages, but you can easily list it with the AWS CLI, using:

$ aws iot list-topic-rules
{
    "rules": [
        {
            "ruleArn": "arn:aws:iot:us-east-1:your-account-id:rule/RetrieveSQSMessageFromQueue",
            "ruleName": "RetrieveSQSMessageFromQueue",
            "topicPattern": "topic/checkForMessage",
            "createdAt": 1511115896.0,
            "ruleDisabled": false
        }
    ]
}

Ok, plugging in my values into the aws cli statement I have a permission added.

This is it for the IoT Rule. To summarize, this allows us to:

  • respond to incoming messages from an AWS IoT device publishing a message to an MQTT topic called topic/checkForMessages
  • when a message arrives from the device on the topic, it triggers the IoT Rule we just created
  • the rule invokes an AWS Lambda to interact with an AWS SQS Queue to pull a message from a queue.

I’ll share more details on the implementation of the Lambda to interact with the SQS queue and the implementation of the node.js app on a Raspberry Pi in upcoming posts. You’re probably wondering what this is that I’m building? Check back for my followup posts to find out!

This is the second post in a series on AWS and IoT, the first is here: