To read: The twelve factor app

Introduction

In the modern era, software is commonly delivered as a service: called web apps, or software-as-a-service. The twelve-factor app is a methodology for building software-as-a-service apps that:

  • Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;
  • Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
  • Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
  • Minimize divergence between development and production, enabling continuous deployment for maximum agility;
  • And can scale up without significant changes to tooling, architecture, or development practices.

The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc).

The twelve factors

I. Codebase

One codebase tracked in revision control, many deploys

II. Dependencies

Explicitly declare and isolate dependencies

III. Config

Store config in the environment

IV. Backing services

Treat backing services as attached resources

V. Build, release, run

Strictly separate build and run stages

VI. Processes

Execute the app as one or more stateless processes

VII. Port binding

Export services via port binding

VIII. Concurrency

Scale out via the process model

IX. Disposability

Maximize robustness with fast startup and graceful shutdown

X. Dev/prod parity

Keep development, staging, and production as similar as possible

XI. Logs

Treat logs as event streams

XII. Admin processes

Run admin/management tasks as one-off processes

How to write a C MQTT client using Mosquitto

Introduction

How to write a C MQTT client using Mosquitto The 2018 version, based upon this excellent post by Kevin Boone:

Writing an MQTT client C for ActiveMQ from the ground up

The article above is a good and easy starting point, but it hasn’t been updated for 2 years so when you run it with the latest version of Mosquitto, it doesn’t work – and it’s a bit hacky (using “sleep” to avoid a concurrency problem).

So I analyzed the latest mosquitto_pub code from mosquitto repository itself to see how it’s working, and this article is the result.

What’s changed

  • There’s a queue inside mosquitto, `mosquitto_loop` must be called for it to be processed. Alternatively, you can also use the `mosquitto_loop_start` and `mosquitto_loop_stop`
  • I added asynchronous (callback) processing to wait for calls to complete, instead of the ole’ sleep function
  • It’s 2018! Everyone is adopting HTTPS. Accordingly, your MQTT traffic shouldn’t be left bare for all to see! Let’s use TLS to encrypt the traffic

The code

How to use callback

I want to publish just once message, so my flow is the following

  • On connect complete -> publish a message
  • On publish complete -> start to disconnect
  • On disconnect complete -> exit the loop and return control to the main thread. If you don’t wait for this, data may not even get sent!

To do this, I set up 3 “hooks” (callback function), like this

mosquitto_connect_callback_set(mosq, my_connect_callback);

mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);

mosquitto_publish_callback_set(mosq, my_publish_callback);
And then write the callback functions to execute my flow
void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
{
    int rc = MOSQ_ERR_SUCCESS;
    if(!result){
        printf("Sending message...\n");
        rc = mosquitto_publish(mosq, &mid_sent, MQTT_TOPIC, strlen(text), text, qos, retain);
        if(rc){
            switch(rc){
                case MOSQ_ERR_INVAL:
                    fprintf(stderr, "Error: Invalid input. Does your topic contain '+' or '#'?\n");
                    break;
                case MOSQ_ERR_NOMEM:
                    fprintf(stderr, "Error: Out of memory when trying to publish message.\n");
                    break;
                case MOSQ_ERR_NO_CONN:
                    fprintf(stderr, "Error: Client not connected when trying to publish.\n");
                    break;
                case MOSQ_ERR_PROTOCOL:
                    fprintf(stderr, "Error: Protocol error when communicating with broker.\n");
                    break;
                case MOSQ_ERR_PAYLOAD_SIZE:
                    fprintf(stderr, "Error: Message payload is too large.\n");
                    break;
            }
            mosquitto_disconnect(mosq);
        }
    } else {
        if(result){
            fprintf(stderr, "%s\n", mosquitto_connack_string(result));
        }
    }
}

void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
{
    printf("Disconnected!\n");
    connected = false;
}

void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
    printf("Published!\n");
    if(disconnect_sent == false){
        mosquitto_disconnect(mosq);
        disconnect_sent = true;
    }
}

How to process the queue with mosquitto_loop

In the main trunk of your code, do this

int rc;
do {
//network동작 끝나기 전에 모스키토 동작을 막기위해 잠깐 딜레이가 필요
  rc = mosquitto_loop(mosq, -1, 1);
} while (rc == MOSQ_ERR_SUCCESS && connected);

How to add TLS to the connection process

Before connecting, set TLS options with mosquitto_tls_set

mosquitto_username_pw_set(mosq, MQTT_USERNAME, MQTT_PASSWORD);
mosquitto_tls_set(mosq, "ca-cert.pem", NULL, NULL, NULL, NULL);
int ret = mosquitto_connect(mosq, MQTT_HOSTNAME, MQTT_PORT, 0);

Complete publish – subscribe sample

Available at https://github.com/thanhphu/mosquitto-sample. Happy cloning!

 

Find and block unsafe content on your wordpress installation

For some reason, my WP installation decided to load some files via http instead of https

Screen Shot 2018-11-12 at 3.28.59 PM.png

To find out which file it is, I used the Javascript consoleScreen Shot 2018-11-12 at 3.29.39 PM.png

It’s wp-emoji in this case, and I don’t use emojis on my site, so I decided to block it by adding this to my theme’s functions.php

 

remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );

 

How to turn on the quit confirmation prompt in Chrome

Recently Chrome 69 started to disrespect the keyboard mapping on my Mac, which result in the Cut key becomes the Quit key! I searched for the option to confirm before quitting but the results are all outdated… Unbelievable! So here’s how:

On Linux and Windows

Go to chrome://flags

Search for Warn before quitting

píc.JPG

On Mac

Chrome Menu / Warn Before Quitting

Screen Shot 2018-09-21 at 10.31.19 AM.png

Random notes trying to install s3fs and backblaze support on Linux

B2 support for duplicity

Must be installed with pip for python 2

apt-get install python-pip
pip install b2

apt-get install duplicity
add-apt-repository ppa:duplicity-team/ppa
apt-get update
apt-get --only-upgrade install duplicity

duplicity /mount/point b2://<box's application ID>:<key>@<box id>

Worth noting that the documentation on backblaze themselves is wrong, you must use your bucket’s app id, not your master app id

Installing s3fs on ubuntu

libfuse must be installed from source or else you’ll get “modprobe: ERROR: ../libkmod/libkmod.c:514 lookup_builtin_file() could not open builtin file ‘/lib/modules/2.6.32-042stab131.1/modules.builtin.bin'”

wget https://github.com/libfuse/libfuse/archive/fuse-2.9.8.tar.gz
tar xvf fuse-2.9.8.tar.gz
cd libfuse-fuse-2.9.8
./configure

Opps… error! 

zsh: no such file or directory: ./configure

I noticed there’s configure.ac file, so it should be

autoconf

Opps… error again

configure.ac:6: error: possibly undefined macro: AM_INIT_AUTOMAKE
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
configure.ac:10: error: possibly undefined macro: AC_PROG_LIBTOOL
configure.ac:13: error: possibly undefined macro: AM_PROG_CC_C_O
configure.ac:73: error: possibly undefined macro: AM_ICONV
configure.ac:75: error: possibly undefined macro: AM_CONDITIONAL

Let’s try this

> ./makeconf.sh
Running libtoolize…
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
Running autoreconf…
configure.ac:10: installing './compile'
configure.ac:5: installing './config.guess'
configure.ac:5: installing './config.sub'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
example/Makefile.am: installing './depcomp'

Cool, seems to work well

./configure
make
make install

Okay… now let’s try

>s3fs bucket /mount/point
fuse: failed to open /dev/fuse: Operation not permitted

Damn…

I’m going to use aws-cli instead. From https://gist.github.com/keeross/b19b6e5603c78073d58b

aws-cli to backup vesta to Amazon S3

  • Install pip (if not installed already):
$ curl -O https://bootstrap.pypa.io/get-pip.py
  • Install AWS cli tool:
$ sudo pip install awscli
  • Configure AWS cli tool:
$ aws configure
AWS Access Key ID [None]: <YOUR_AWESOME_KEY>
AWS Secret Access Key [None]: <YOUR_AWESOME_KEY>
Default region name [None]: us-west-2
Default output format [None]: json
  • Backup old file, then open and edit Vesta command v-backup-user:
$ cp /usr/local/vesta/bin/v-backup-user /usr/local/vesta/bin/v-backup-user_backup
$ sudo nano /usr/local/vesta/bin/v-backup-user
  • Somewhere in Variable&Function section add:
# AWS arguments
bucket_name=<your_awesome_bucket_name>
  • Search for # Creating final tarball section and right after this line chown admin:$user $BACKUP/$user.$date.tar add new code:
# AWS UPLOAD
aws s3api put-object --bucket $bucket_name --key $user/$user.$date.tar --body $BACKUP/$user.$date.tar --storage-class REDUCED_REDUNDANCY
echo -e "$(date "+%F %T") AWS: Uploaded and backed. $user.$date.tar"
msg="$msg\n$(date "+%F %T") AWS: Uploaded and backed. $user.$date.tar"