Lab 11 - Bonus Lab!
Facilitator: kian, trinityc
10 min readTable of contents
- Overview
- Part 1: Installing Puppet
- Part 2: Using Puppet
- Part a: Making a Home Directory and a User
- Part b: Install java
- Part c: Installing the Minecraft Server configuration
- Part d: Installing the Minecraft Server
- Part e: Templating a systemd unit file
- Part f: Running the service
- Part g: Backups
- Part h: (Bonus, optional if you want Minecraft to not Out Of Memory)
- Part i: (Bonus, running Minecraft)
- Part 3: Cleanup
- Part 4: Submission
Overview
NOTE: This lab is completely optional. Completing it before the late lab deadline will count as an additional completed, on-time lab (so please try it out if you weren’t able to finish a previous lab)!
For this lab, we will be installing and configuring a Minecraft server. All of this configuration can be successfully done without a Minecraft client or knowledge on how to play the game itself.
If you want to actually be able to connect to the server: If you’re not using the provided VM make sure your Linux VM has enough RAM to host the server (2-4Gb).
Getting help
If you want any help with any part of this lab, join the OCF Discord (https://ocf.io/discord) and ask in the #decal-general channel!
The original creator of this lab is Frank Dai (fydai), and there was originally a message here telling you to ping him if you needed any help. You are still welcome to try (or, you can also ping current decal facilitators as well) :)
The most important trick with puppet
If you mess anything up, delete everything (in particular /home/minecraft
),
and just run puppet again! Puppet ensures that even starting from nothing, you
can reconstruct your entire previous state. If you do this and get issues with
Puppet executing things out of order than you would like them, add in a
require
parameter to the resource that should be defined later. For instance,
if you want to create something after the /home/minecraft
directory, throw in
an require => File['/home/minecraft']
option. In general, capitalize the name
of the resource, and put the string before the colon between the square braces.
Part 1: Installing Puppet
First, we’re going to install Puppet. Feel free to simply copy the commands below to set up Puppet. Make sure to copy the whole thing!
(This step is not necessary if you already installed Puppet.)
wget https://apt.puppetlabs.com/puppet7-release-jammy.deb && \
sudo dpkg -i puppet7-release-jammy.deb && \
sudo apt-get update && \
sudo apt-get -y install puppet-agent puppetserver && \
source /etc/profile.d/puppet-agent.sh && \
echo 'export PATH="/opt/puppetlabs/bin:$PATH"' >> ~/.bashrc
Part 2: Using Puppet
Make a minecraft.pp
file anywhere, which through the course of this lab, will
eventually configure and run a Minecraft Server. To run your puppet code, use
sudo puppet apply minecraft.pp
. Puppet, being declarative, will do nothing if
the system is already configured properly, so run puppet early and often to
detect bugs as soon as possible.
Useful references are this section are the Puppet documentation and there is a lot of sample code avaliable in the OCF Puppet configuration. When you are stuck, looking at existing code and see how they did things will generally be helpful. Also remember that there are code examples on the slides!
Part a: Making a Home Directory and a User
Put the following code into minecraft.pp
:
file { '/home/minecraft':
ensure => 'directory',
}
Run sudo puppet apply minecraft.pp
to apply it, and ensure that the
/home/minecraft
directory was created.
Inside minecraft.pp
, write some Puppet code to create a user named
minecraft
, that the Minecraft server will run under. The minecraft
user
should have home directory /home/minecraft
. Now modify the code creating
/home/minecraft
to set owner the owner to minecraft
user you just made.
Check the example code on the slides if you are unsure about how to do this.
Checking Part a
Run sudo puppet apply minecraft.pp
.
Now run ls -l /home
and verify that /home/minecraft
is owned by the
minecraft user.
Part b: Install java
Add a few lines to minecraft.pp
to install the default-jre
package.
Checking Part 2b
Run java
and verify that the binary exists.
Part c: Installing the Minecraft Server configuration
Copy paste the contents of
https://raw.githubusercontent.com/0xcf/decal-labs/master/a10/server.properties
locally into a file named server.properties
Ensure that /home/minecraft/server.properties
contains the contents of the
server.properties
you just saved.
Hint: Use the file
function! Also note that in this lab, you should be using
absolute file paths.
Read and agree to the
Minecraft EULA, and
ensure that /home/minecraft/eula.txt
contains the text eula=true
by
hardcoding the string eula=true
into your minecraft.pp
.
Make sure that all of the above files are owned by the minecraft
user.
Checking Part c
Run ls -l /home/minecraft
and ensure that the above files exist, contain what
they’re supposed to, and they are all owned by the minecraft
user, not yours.
Part d: Installing the Minecraft Server
Ensure that /home/minecraft/server.jar contains the Minecraft Server, available at https://piston-data.mojang.com/v1/objects/1b557e7b033b583cd9f66746b7a9ab1ec1673ced/server.jar. This server jar is for Minecraft 1.16.5, if you’d like to run a different version you can download the jar from within the Minecraft launcher or from the Minecraft wiki.
Note that the source
parameter of the file
resource accepts a URL as its
argument. Also make it owned by the minecraft
user.
Checking Part d
You know what to do!
Part e: Templating a systemd unit file
Copy the following template into the same directory into your minecraft.pp
file as minecraft.service.erb
.
Edit the file to be a proper erb
template, so that <INSERT YOUR RAM AMOUNT
HERE>
becomes the value of the memory_available
variable when puppet runs.
You want to use the templated variable @memory_available
in the .erb
file,
and declare the variable $memory_available
it in the .pp
file.
Hint: In the slides), there is an example of templating a file.
Hint 2: A .erb (Embedded Ruby) file means that Ruby is used as the templating language instead of the puppet language. Make sure not to confuse the syntax between the two!
Now edit your minecraft.pp
file, so that it sets the $memory_available
variable to be the half the total amount of RAM available to the system (use
Google and StackOverflow), and that it puts the templated file into
/etc/systemd/system/minecraft.service
.
Hint: You need to figure out how to define variables and set variables in
puppet. Note that variables should be prefixed by $
. You can assign variables
just like any other language. Don’t forget to look at the sample code on the
slides (it doesn’t cover variable assignment however) and don’t forget to use
absolute paths!
Note that the systemd unit file does not have a proper ExecStop, which maybe result in some world corruption.
[Unit]
Description=Minecraft Server
Wants=network.target
After=network.target
[Service]
User=minecraft
WorkingDirectory=/home/minecraft
# This should look like ExecStart=/usr/bin/java -Xmx504578 -jar server.jar
ExecStart=/usr/bin/java -Xmx<INSERT YOUR RAM AMOUNT HERE> -jar server.jar
ExecStop=/bin/kill -- $MAINPID TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
Checking Part e
Look at /etc/systemd/system/minecraft.service
to ensure it contains the
contents you want before proceeding.
Part f: Running the service
Ensure that the minecraft
systemd service is enabled and started.
Checking Part f
This is the critical moment! If you’ve done everything before correctly, this
should work (until Minecraft OOMs)! If the systemd unit fails immediately, try
to run the ExecStart command manually, by going into /home/minecraft/
and
running sudo -u minecraft java -Xmx1009156 -jar server.jar
.
You can verify that something is trying to start by running tail -f
/home/minecraft/logs/latest.log
. If it ever stops loading, the server has run
out of memory, and “Part h” below should have a workaround.
Part g: Backups
We should backup our minecraft server!
Ensure there is a directory /home/minecraft/backups/
, owned by the minecraft
user.
Ensure there is a script, /home/minecraft/backup.sh
that is executable, with
the following contents however you’d like.
#!/bin/sh
cp -r /home/minecraft/world "/home/minecraft/backups/world-$(date -Is)"
The command copies the directory containing into the minecraft world into a
subdirectory of backups
indexed by the current date.
Use puppet to add a cron entry to execute /home/minecraft/backup.sh
every
minute as the minecraft user.
Checking Part g
Look in the /home/minecraft/backups
contains backups!
Part h: (Bonus, optional if you want Minecraft to not Out Of Memory)
We could be doing this by typing this a bunch of commands to add a swap file, and enabling it as swap, but we will do this puppet style!
Configure puppet to create a 4GB file /swapfile
with the command dd
if=/dev/zero of=/swapfile bs=2M count=2048
. Look through the flags to the
exec
resource to see how you can do this.
Now configure Puppet to run mkswap /swapfile && swapon /swapfile
unless swap
is currently active, which you can check by seeing if swapon -s | grep
/swapfile
returns a zero code. There are two arguments that can do this,
unless
or onlyif
. Experiment to see which one works.
Checking Part h
Run swapon -s
, and check that /swapfile
is listed. Ensure that there is no
extranous output when you run puppet, if your checks are correctly done, this
shouldn’t happen. Check /home/minecraft/logs/latest.log
to make sure that the
server has start up properly. If it has, then congratulations!
Part i: (Bonus, running Minecraft)
Due to security issues, the Minecraft server running is only listening to
127.0.0.1
, which means by default you can only access a Minecraft client
running on the VM. You have two ways to get around this. One is changing
server-ip
in server.properties to a blank string (i.e. server-ip=
), which will allow access by
anybody. If you do this you probably want to set up a whitelist. The other
option is SSH port forwarding. The command, if run on your machine, captures
traffic at port 25565 on your local computer, and forwards them to port 25565 on
your VM. The command will run forever, just leave it in the background while you
try to connect.
ssh -NL 25565:localhost:25565 <username>@<username>.decal.xcf.sh
If you chose the first option, you can connect by typing your domain name (e.g.
Part 3: Cleanup
There is currently a cronjob copying the minecraft world every minute. That
might run you out of disk space. To disable that, you should run sudo crontab
-e
and remove the line for the backups.
Trying to run a Minecraft Server constantly might also eat up some system resources. You can stop and disable the minecraft systmemd unit manually if it is causing issues.
If you added the swapfile, you might want to remove that.
Another way you can clean up is with puppet. By default, puppet doesn’t remove
files it doesn’t know about. However, you can use ensure => absent
to make
sure files are gone, and similarly for the other resource types.
Part 4: Submission
Congratulations on finishing the lab!
To submit, copy paste the code you have for each section into the gradescope submission.