Deploy the Game Server¶
iFun Engine game server can be packed in a single package and copied around to install/upgrade on a live server. The package includes service script and auxiliary resource files as well as server binary. This chapter explains how to manage iFun Engine game servers installed by the package.
Currently, Ubuntu 14.04 / 16.04, Centos 7 are supported. Centos 6.5 is experimentally supported.
Deployment to Ubuntu 14.04 / 16.04¶
Tweaking the Upstart service file¶
etc/upstart/init/{project-name}.conf
This file is an upstart configuration file. You can edit the file to control how the upstart service works. In general, default setting is sufficient. For details about Upstart, please refer to Upstart Intro, Cookbook and Best Practises.
Note
If you are using Flavors: Identifying servers according to their role, you need to edit etc/upstart/init/${project-name}.${flavor}.conf
.
etc/upstart/default/{project-name}
This file contains default values for variables used in the configuration file.
You may want to update the enabled
, uid
, and gid
as follows:
# Sets this to 1 to enable, to 0 to disable
enabled=1
uid=root
gid=root
enabled
: 1 if the service should start by default.uid
: user id to run the service.root
, by default. You better consider using a non-root user for security reasons.gid
: group id to run the service. Similarly to the uid, non-root user is preferred.
If you changed the upstart conf file, you may want to your custom variables in this file.
Note
If you are using Flavors: Identifying servers according to their role, you need to edit etc/upstart/default/${project-name}.${flavor}
.
Warning
Ubuntu 16.04 manages services via systemd
instead of upstart
. So, please refer to
Deployment to Centos 7.
Packaging the Server¶
Generate a package as explained in Server management part 3: Server packaging.
(Running make package
after turning on WANT_DEB_PACKAGE
in CMakeLists.txt is sufficient.)
After getting a deb file, you can verify its contents using dpkg-deb --contents
.
$ dpkg-deb --contents example_0.0.1_install.deb
drwxrwxr-x root/root 0 2015-03-16 17:46 ./etc/
drwxr-xr-x root/root 0 2015-03-16 17:46 ./etc/init/
-rw-r--r-- root/root 1090 2015-03-13 16:58 ./etc/init/example.conf
drwxr-xr-x root/root 0 2015-03-16 17:46 ./etc/default/
-rw-r--r-- root/root 72 2015-03-13 16:58 ./etc/default/example
drwxrwxr-x root/root 0 2015-03-16 17:46 ./usr/
...
drwxrwxr-x root/root 0 2015-03-16 17:46 ./usr/lib/
-rw-r--r-- root/root 3305589 2015-03-16 14:46 ./usr/lib/libexample.so
drwxrwxr-x root/root 0 2015-03-16 17:46 ./usr/bin/
-rwxr-xr-x root/root 2688 2015-03-13 16:58 ./usr/bin/example-launcher
Make sure the package contains all the required resource files. Then, copies it to a live server.
Installing / Upgrading the Server¶
After copying the deb file, install the server using the dpkg
command like this:
(We assume a project name example
here.)
$ sudo dpkg -i example_0.0.1_install.deb
[sudo] password for ubuntu:
Selecting previously unselected package example.
(Reading database ... 424079 files and directories currently installed.)
Preparing to unpack example_0.0.1_install.deb ...
Unpacking example (0.0.1) ...
Setting up example (0.0.1) ...
Processing triggers for ureadahead (0.100.0-16) ...
ureadahead will be reprofiled on next reboot
You may see an installation error message if you have not installed the funapi1-runtime
package on the target server.
If the case, simply run like this:
$ sudo apt-get install -f
Then, it will resolves the dependency issue and continue to install the game package.
Starting the service¶
Game server can start as a service like this:
$ sudo start example
example start/running, process 27687
Stopping the service¶
Similarly, service can be stopped using the stop
command.
$ sudo stop example
example stop/waiting
Giving an extra command line arguments¶
As explained, iFun Engine uses MANIFEST.json
as its configuration storage.
And this file is also automatically packaged when running make package
.
We also have studied in Flavors: Identifying servers according to their role that different flavors could have different MANIFEST.json. But same flavor must share the same MANIFEST.json, since flavor is a unit of the same configuration.
To tweak the behavior, we have introduced tentative ways like Temporarily overriding MANIFEST.json. The technique can be applied in the live environment, too.
But what if we want to add a command line argument rather than one managed by MANIFEST.json? Since iFun Engine uses Google Gflag you may want to add your own flags. .. code-block:: c++
DEFINE_string(my_arg1, “my_default_value”, “description on my_arg1”);
This is perfectly fine and easy to pass the argument especially it’s in the development environment.
$ ./my_game_server-local --my_arg1=my_value
Or, it’s also possible to pass the argument in a predefined environment variable named EXTRA_ARGS
.
$ EXTRA_ARGS="--my_arg1=my_value" ./my_game_server-local
OR
$ export EXTRA_ARGS="--my_arg1=my_value"
$ ./my_game_server-local
Either works for the development environment because you can control the shell.
But you do not have such a control when running the game server through Upstart.
Instead, you need to add the EXTRA_ARGS
in /etc/default/<project_name>
(or /etc/default/<project_name>.<flavor>
if using Flavors: Identifying servers according to their role)
Please note that it should be like:
export EXTRA_ARGS="--my_arg1=my_value --my_arg2=another_value"
export
must be there and there are no whitespaces before/after =
.
Deployment to Centos 7¶
Tweaking systemd unit file¶
You need to edit etc/systemd/{project-name}.service
in your source directory.
In general, default setting is sufficient.
For details, please refer to Systemd.
Note
If you are using Flavors: Identifying servers according to their role, you need to edit etc/systemd/${project-name}.${flavor}.service
.
Running as a non-root user
It’s recommended to run the service as a non-root user for security reasons.
Suppose we want to run a user id of centos
and a group id of centos
.
The unit file can look like this:
[Service]
LimitNOFILE=999999
# It is strongly recommended that one should use uid:gid other than the root
# NOTE: Please update User=, Group=, and ExecStartPre=
User=centos
Group=centos
# Makes the daemon automatically restart
Type=simple
Restart=on-failure
RestartSec=5s
# create directories, and change permissions (with root privileges)
PermissionsStartOnly=true
ExecStartPre=/usr/bin/mkdir -p /var/log/funapi/example/glog \
/var/log/funapi/example/activity \
/var/crash/funapi/example
# NOTE: change root:root to service's uid:gid
ExecStartPre=/usr/bin/chown -R centos:centos /var/log/funapi/example/glog \
/var/log/funapi/example/activity \
/var/crash/funapi/example
ExecStart=/usr/bin/example-launcher
Packaging the Server¶
Generate a package as explained in Server management part 3: Server packaging.
(Running make package
after turning on WANT_RPM_PACKAGE
in CMakeLists.txt is sufficient.)
After getting a rpm file, you can verify its contents using rpm --qpl
.
$ rpm -qpl example_0.0.1_install.rpm
/lib/systemd/system/example.service
/usr/bin/example-launcher
/usr/lib/libexample.so
/usr/share/example/DEBIAN
/usr/share/example/LICENSE
/usr/share/example/README
/usr/share/example/VERSION
/usr/share/example/manifests/default
/usr/share/example/manifests/default/MANIFEST.json
/usr/share/example/resources/.stamp
/usr/share/example/resources/game_data/.stamp
/usr/share/example/resources/json_protocols/.stamp
/usr/share/example/symbols/libexample.so/91EE2EBCB776CA83BCB729D47A709F4A0/libexample.so.sym
Installing / Upgrading the Server¶
After copying the rpm file, install the server using the rpm
command like this:
(We assume a project name example
here.)
$ sudo rpm -i example_0.0.1_install.rpm
Activating the systemd service¶
To make the service automatically starts after reboot, we need to activate the systemd service:
$ sudo systemctl enable example
Stopping the service¶
Similarly, service can be stopped using the stop
argument.
$ sudo systemctl stop example
Giving an extra command line arguments¶
The idea explained in Giving an extra command line arguments applies the same here.
That is EXTRA_ARGS
must be added in /etc/default/<project name>
.
However, Centos should drop prepended export
like this:
EXTRA_ARGS="--my_arg1=my_value --my_arg2=another_value"
Installing the Server at Non-Standard Location¶
We have studied how to install the game server using the DEB
and RPM
(Deployment to Ubuntu 14.04 / 16.04 and Deployment to Centos 7)
This is recommended in most cases. However there might be a case that all the files should be installed at a non-standard location. For example, the publisher might request to make the game server runnable under a particular user home directory. In this case, you may need a game server in a gzipped tar file.
Open up CMakeLists.txt
and make it generate a TGZ package.
set(WANT_TGZ_PACKAGE true)
Now, make package
will generate <project_name>_<version>_install.tar.gz
instead of .deb or .rpm.
Note
If using Flavors: Identifying servers according to their role, output should be <project_name>_<version>_install-<flavor_name>.tar.gz
.
Assuming a project name hello
and a flavor lobby
, an output would be hello_0.0.1_install-lobby.tar.gz
.
Then, we can ship it to the publisher and let it install under any directory (say, /home/zeus
).
$ cd /home/zeus
$ tar zxf hello_0.0.1_install-lobby.tar.gz
You can verify that the contents in the gzipped tar file have been extracted under the home directory. This looks fine so far. But what about the service scripts? Since it’s just a tar file, it won’t install the service script and we cannot run the game server as a daemon. This can be nagging. Unfortunately, we need one-time manual job to solve the problem.
Manually registering an Upstart script (Ubuntu 14.04)¶
After extracting the tar file, you can locate etc/
under /home/zeus/
.
Again, there should be init/
and default/
under etc/
.
The former contains an upstart script and the latter has a configuration file declaring variables used in the upstart script.
$ cd /home/zeus
$ ls etc
default init
Assuming a project name hello
and a flavor lobby
, we will have files like this:
$ ls etc/default
hello.lobby
$ ls etc/init
hello.lobby.conf
Append a line in etc/default/hello.lobby
like this:
export GAME_ROOT_DIR=/home/zeus
Warning
export
is required.
Tip
There are other variables that you can manipulate.
GAME_ROOT_DIR
: Specifies the top-level directory of the game server. It defaults to/
.GAME_MANIFEST_OVERRIDE
: Specifies a path to a MANIFEST override file as explained in Temporarily overriding MANIFEST.json. It defaults to/etc/<project_name>/MANIFEST.override.json
.GAME_LOG_ROOT_DIR
: Specifies where glog files would be generated. It defaults to/var/log/funapi/<project_name>
.GAME_CRASHDUMP_ROOT_DIR
: Specifies where dump files would be generated. It defaults to/var/crash/funapi/<project_name>
.GAME_GLOG_OPTIONS
: Specifies Google’s glog options. It defaults to--max_log_size=10 --stop_logging_if_full_disk
.GAME_CONTACT_EMAIL_ADDRESS
: Specifies an email address to receive server crash reports. The server must have been correctly configured apostfix
. If null, the default, reporting is disabled.
After setting GAME_ROOT_DIR
in the default file, copy /home/zeus/etc/default/hello.lobby
and /home/zeus/etc/init/hello.lobby.conf
to /etc/default/
and /etc/init/
, respectively. All set! You can now run using sudo service hello start
.
Manually registering a Systemd unit (CentOS 7 / Ubuntu 16.04)¶
Steps are similar to the Upstart case.
After extracting the tar file, you can locate lib/systemd/system/
under /home/zeus/
.
It contains an systemd unit file. hello.lobby.service
in this example.
$ ls lib/systemd/system
hello.lobby.service
Copy the file to /lib/systemd/system/
Then, creates /etc/default/hello.lobby
and append a line like below:
GAME_ROOT_DIR=/home/zeus
Warning
Unlike the Ubuntu case, export
shouldn’t be used.
Tip
There are other variables that you can manipulate.
GAME_ROOT_DIR
: Specifies the top-level directory of the game server. It defaults to/
.GAME_MANIFEST_OVERRIDE
: Specifies a path to a MANIFEST override file as explained in Temporarily overriding MANIFEST.json. It defaults to/etc/<project_name>/MANIFEST.override.json
.GAME_LOG_ROOT_DIR
: Specifies where glog files would be generated. It defaults to/var/log/funapi/<project_name>
.GAME_CRASHDUMP_ROOT_DIR
: Specifies where dump files would be generated. It defaults to/var/crash/funapi/<project_name>
.GAME_GLOG_OPTIONS
: Specifies Google’s glog options. It defaults to--max_log_size=10 --stop_logging_if_full_disk
.GAME_CONTACT_EMAIL_ADDRESS
: Specifies an email address to receive server crash reports. The server must have been correctly configured apostfix
. If null, the default, reporting is disabled.
You can verify by running sudo systemctl start hello.lobby
.
Locking iFun Engine Version¶
It could be catastrophic if auto-update could impact the running game server.
Hence, we may want to lock the versions of funapi1-runtime
and iFun agents like Authenticator, Biller, and Leaderboard.
On Ubuntu¶
To lock the version of funapi1-runtime
:
$ sudo apt-mark hold funapi1-runtime
After the command, apt-get upgrade
will skip the package.
Checking which packages are locked
$ sudo apt-mark showhold
funapi1-runtime
Releasing the version lock
$ sudo apt-mark unhold funapi1-runtime
After this, apt-get upgrade
will upgrade the package.
On CentOS¶
CentOS requires an extra package to lock the version of installed package.
$ sudo yum install yum-versionlock
After installing yum-versionlock
, run like this:
$ sudo yum versionlock funapi1-runtime
Then, yum update
will skip the locked package.
Checking which packages are locked
$ sudo yum -q versionlock list
0:funapi1-runtime-1.0.0-1680centos7.*
Releasing the version lock
$ sudo yum versionlock delete funapi1-runtime
After this, yum update
will try to upgrade the package.
Warning
On CentOS 6, you should do like sudo yum versionlock delete '*:funapi1-runtime*'
.
Inspecting the Game Server¶
Checking the status and the service script logs¶
As explained, iFun Engine game server is managed either by upstart or systemd. If daemon could not start due to configuration errors or packaging issues, we can inspect the log messages of upstart or systemd like this:
upstart
/var/log/upstart/{project-name}.log
contains log messages regarding upstart daemon spawning.
systemd
To access the systemd daemon logs, run journalctl -x -u {project-name}
.
Game server logs¶
iFun Engine game server leaves log files in /var/log/funapi/{project-name}
.
activity/{날짜}/activity_log.json.*
: activity log messages as defined in{project-name}_loggers.json
in your source directory.glog/*
: Google Glog messages viaLOG(...)
.
Game server dump files¶
Once the game server crashes, it generates a dump file like /var/crash/funapi/{project-name}/{dump-uuid}.dmp
To inspect the dump file, you can use funapi_stackwalk.