Family Circles
  1. Overview
  2. Installing
    1. Overview
    2. Docker
  3. Environment
  4. Config File
  5. Perl Modules
  6. fcservice
  7. fcapi

Overview

File System /fc/bin/fcservice SQLite API http 80 /fc /fc/etc/empty.conf PERL5LIB=/fc/libPATH=/fc/bin:$PATHFC_CONFIG=/fc/etc/empty.json Daemon Command Line /fc/bin/fcapi Container

I use containers for running the service and the above is an outline of the familycircles container. The container consists of an OS image. Additional OS required packages for Family Circles are installed in the image and then the fcservice.tar.gz is extracted into the filesystem at /fc. The outlined environment variables are set during the image creation. Later, during run time fcservice is started.

I usually setup up containers in the following configuration for a particular data file I want to make available.

readonly1 readonly<N> . loadbalancer readwriteadmin SharedStorage Daemon Container

I have one internal container with full access where I create the data file, but while I'm working on it it isn't available to the internet. Once I have a data file that I feel is ready, I export the data to a shared storage. Then I have a set of read only containers that will load the data file on fcservice start and are accessed through a load balancer for external user interaction.

Installing

Overview

The service is perl code. It depends on a number of perl modules and SQLite, so any platform that supports these items can be used to run the service.

This is a very generic outline of the steps involved to run the service:

  1. take any OS
  2. install a current version of SQLite
  3. install a current version of perl
  4. add the identified perl modules to perl
  5. download the latest fcservice.tar.gz
  6. extract in some location
  7. set your environment
  8. create a config file
  9. execute fcservice

Outside of the above I'm not currently planning on going into details of how to setup the service for every possible situation and I also don't plan on providing simple installers for xyz OS. However, if someone wanted to fund instructions for a specific OS or if the donations become significant enought then these instructions will get expanded.

What I will go over is how I install and use the service for my needs. I use docker and will assume you are already familiar with it and have it setup and running on some server.

Docker

Quick Start:
$ docker run -d --name fcservice -p 80:80 familycircles/service
$ docker logs -f fcservice
HTTP::Server::PSGI: Accepting connections at http://0:80/

The above will start a service listening on port 80 with no data in it. Then follow the log file from the service.

Suppose the server that the above was started from was test123.test.com. Then you could go to the admin interface from fc.jenika.com and enter http://test123.test.com for the service name and it will connect and report the current status of that service. You should see under Records that the family and person counts are 0.

When you connect to the above service from the browser you should see http access request lines appear as requests are made to the service. You can use ctrl-c to stop following the log file. You can then stop the service with:

$ docker stop fcservice

If you want to remove that service, use this line:

$ docker rm fcservice

If you want to remove the image use this:

$ docker image rm familycircles/service:latest

The docker container is based on the following:

  1. fedora:latest
  2. dnf -y install perl-Pod-Usage perl-Plack perl-Module-Load-Conditional perl-libwww-perl perl-JSON perl-JSON-XS perl-IO perl-HTTP-Message perl-Getopt-Long perl-DBI perl-DBD-SQLite perl-Clone perl-Carp
  3. extract the fcservice.tar.gz in /fc

A more typical scenario I use for running the service is that I will create a specific config file that I want to use for a container and then I will use the following.

# create a custom config file place in some local storage for container
$ mkdir -p /containers/service.test.com
$ vi /containers/service.test.com/empty.json
# create contianer with a map the containers /fc/etc directory
# to my containers directory with my config
docker create --name service.test.com -v /containers/service.test.com:/fc/etc --restart unless-stopped familycircles/service

# start container
docker start service.test.com

If I want to use a custom config file name I do something like this:

# create a custom config file place in some local storage for container
$ mkdir -p /containers/service.test.com
$ vi /containers/service.test.com/test.json
# create contianer with a map the containers /fc/etc directory
# to my containers directory with my config
docker create --name service.test.com --env FC_CONFIG=/fc/etc/test.json -v /containers/service.test.com:/fc/etc --restart unless-stopped familycircles/service

# start container
docker start service.test.com

Environment

The perl code for the service depends on three environment variables being properly set.

All the above settings can be adjusted from the docker command using the docker --env flag.

Config File

The services config file uses a JSON format. The following parameters are supported in the service config file.

These are the values used by fcapi.

These are the values used by fcservice.

Combining both the above into one file is what I tend to do, but if you plan to use only one of the applications from some server then you can include only what's required for the application you use.

FamilyCircles::Load::GEDOM requires the following load parameters.

FamilyCircles::Load::JSON requires the following load parameters.

Examples

This is the default empty config file used in the container.

{
  "service" : "http://localhost/",
  "server" : {
    "port" : 80
  },
  "headers" : {
    "Access-Control-Allow-Origin" : "*"
  },
  "api" : ["read","write","admin"],
  "data" : {
    "db" : {
      "ds"   : "DBI:SQLite:database=:memory:",
      "user" : "",
      "pass" : ""
    }
  }
}

This config file uses default server settings and loads a demo GEDCOM file. This config assumes /data/demo.ged file exists inside the container either by copying it in or by mapping something to /data to make it available.

{
  "service" : "http://localhost:5000/",
  "api" : ["read","write","admin"],
  "headers" : {
    "Access-Control-Allow-Origin" : "*"
  },
  "data" : {
    "db" : {
      "ds"   : "DBI:SQLite:database=:memory:",
      "user" : "",
      "pass" : ""
    },
    "load" : {
      "driver" : "GEDCOM",
      "file" : "/data/demo.ged"
    }
  }
}

Perl Modules

CPAN PackageModule
Carp Carp
Clone Clone
DBI DBI
DBD-SQLite DBD::SQLite
File-Temp File::Temp
Getopt-Long Getopt::Long
HTTP-Message HTTP::Request
IO IO::File
JSON JSON
libwww-perl LWP
Module-Load-Conditional Module::Load::Conditional
Plack Plack::Component
Plack::Request
Plack::Runner
Pod-Usage Pod::Usage

fcservice

Usage:
      fcervice [-config <file>]

fcapi

Usage:
      fcapi -search <name> [-config <file>]
      fcapi -get <id> [-config <file>]
      fcapi -add <json> [-config <file>]
      fcapi -delete <id> [-config <file>]
      fcapi -clear [-config <file>]
      fcapi -load -file <file> -format GEDCOM|JSON [-config <file>]
      fcapi -load -url <url> -format GEDCOM|JSON [-config <file>]
      fcapi -export [-config <file>]
      fcapi -usage [-config <file>]
      fcapi -api [-config <file>]