diff --git a/playbooks/game.yml b/playbooks/game.yml index d61a117..81bc85a 100755 --- a/playbooks/game.yml +++ b/playbooks/game.yml @@ -29,3 +29,19 @@ - industrial-foregoing-1.16.3-3.1.1-a834e76.jar become: yes tags: [ game, minecraft, forge, valhelsia ] + - role: factorio + vars: + server_version: 1.0.0 + download_checksum: sha256:81d9e1aa94435aeec4131c8869fa6e9331726bea1ea31db750b65ba42dbd1464 + service_name: factorio-main + service_root: /opt/factorio/main + factorio_server_settings: + name: "Krabby Land" + description: "Where a kid can have fun" + max_players: 8 + visibility: + public: false + lan: false + admins: [ "rehashed_salt" ] + become: yes + tags: [ game, factorio ] diff --git a/roles/factorio/.github/workflows/ansible-tests.yml b/roles/factorio/.github/workflows/ansible-tests.yml new file mode 100644 index 0000000..55213cc --- /dev/null +++ b/roles/factorio/.github/workflows/ansible-tests.yml @@ -0,0 +1,65 @@ +--- +# Got this action from: https://github.com/colin-mccarthy/ansible_lint_demo + +name: Ansible Tests +on: pull_request +jobs: + yamllint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r dev-requirements.txt + - name: Test with molecule + run: make lint + molecule_centos: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install dependencies + run: | + sudo apt install docker + python -m pip install --upgrade pip + pip install -r dev-requirements.txt + - name: Test with molecule + run: make test_centos + molecule_debian: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install dependencies + run: | + sudo apt install docker + python -m pip install --upgrade pip + pip install -r dev-requirements.txt + - name: Test with molecule + run: make test_debian + molecule_ubuntu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install dependencies + run: | + sudo apt install docker + python -m pip install --upgrade pip + pip install -r dev-requirements.txt + - name: Test with molecule + run: make test_ubuntu diff --git a/roles/factorio/.gitignore b/roles/factorio/.gitignore new file mode 100644 index 0000000..22d0d82 --- /dev/null +++ b/roles/factorio/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/roles/factorio/.yamllint b/roles/factorio/.yamllint new file mode 100644 index 0000000..2988da4 --- /dev/null +++ b/roles/factorio/.yamllint @@ -0,0 +1,13 @@ +--- +extends: default + +rules: + empty-lines: disable + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + line-length: disable + truthy: disable diff --git a/roles/factorio/README.md b/roles/factorio/README.md new file mode 100644 index 0000000..a061433 --- /dev/null +++ b/roles/factorio/README.md @@ -0,0 +1,257 @@ +# Factorio + +[![Install from Ansible Galaxy](https://img.shields.io/badge/role-bplower.factorio-blue.svg)](https://galaxy.ansible.com/bplower/factorio/) +![Ansible Lint](https://github.com/bplower/ansible-factorio/workflows/Ansible%20Tests/badge.svg) + +A role for creating Factorio servers +https://galaxy.ansible.com/bplower/factorio/ + +## Requirements + +No requirements + +## Role Variables + +Variables can be roughly divided into two groups: deployment configurations and +Factorio configurations. + +### Deployment Configurations + +The deployment configurations are all related to the way in which ansible +installs the factorio server. These should be abstracted enough to allow +multiple factorio servers to be run simultaneously. + +``` +server_sources: "/opt/games/sources/factorio" +server_version: "0.17.79" +download_url: "https://www.factorio.com/get-download/{{ server_version }}/headless/linux64" +service_name: "factorio-server" +service_user: "factorio" +service_group: "factorio" +service_root: "/home/{{ service_user }}" +service_port: 34197 +service_restart_permitted: true +factorio_default_save: "{{ service_root }}/factorio/saves/default-save.zip" +factorio_target_save: "{{ factorio_default_save }}" +``` + +More detailed information about these variables is as follows: + +- Variable: `server_sources`
+ Default: `"/opt/games/sources/factorio"`
+ Comments:
+ Where to cache server binaries downloaded from the download_url + +- Variable: `server_version`
+ Default: `"0.17.79"`
+ Choices: + - "0.18.26" + - "0.17.79" + - "0.17.74" + - "0.16.51" + - "0.15.40" + - "0.14.23" + - "0.13.20" + - "0.12.35" + + Comments:
+ You must set the `download_checksum` value if you set this variable. This + value is used in the default `download_url`. + +- Variable: `download_url`
+ Default: `"https://www.factorio.com/get-download/{{ server_version }}/headless/linux64"`
+ Comments:
+ The URL to download the server binary from. This will only be downloaded if + the path `"{{ server_sources }}/factorio-{{ server_version }}.tar.gz"` does + not exist. + +- Variable: `download_checksum`
+ Default: `"sha256:9ace12fa986df028dc1851bf4de2cb038044d743e98823bc1c48ba21aa4d23df"` + Comments:
+ The checksum that must match the downloaded server binary. This ensures the integrity. + If you change the `download_url` or `server_version`, you need to adapt the checksum as well. To get the + checksum of a server binary, you can use `curl --silent --location | sha256sum`. + To disable the checksum verification, just set it to an empty string (`""`). + +- Variable: `service_name`
+ Default: `"factorio-server"`
+ Comments:
+ The name of the service to create. Multiple instances of factorio servers can + be run on a single host by providing different values for this variable (See + the examples section of this document). + +- Variable: `service_user`
+ Default: `"factorio"`
+ Comments:
+ The user the service should be run as. + +- Variable: `service_group`
+ Default: `"factorio"`
+ Comments:
+ The group the service user should be a member of. + +- Variable: `service_root`
+ Default: `"/home/{{ service_user }}"`
+ Comments:
+ The directory in which to store the contents of the factorio zip file + downloaded from the server. This will result in the factorio resources being + stored at `{{ service_root }}/factorio/`. + +- Variab: `service_port`
+ Default: `34197`
+ Comments:
+ The port to host the service on. This default is the factorio default value. + +- Variable: `service_restart_permitted`
+ Default: `true`
+ Comments:
+ Setting this to `false` will prevent the service from being restarted if + changes were applied. This allows settings to be applied in preparation for + the next service restart without immediately causing service interruption. + +- Variable: `factorio_default_save`
+ Default: `"{{ service_root }}/factorio/saves/default-save.zip"`
+ Comments:
+ The default save file used by the server. + +- Variable: `factorio_target_save`
+ Default: `"{{ factorio_default_save }}"`
+ Comments:
+ The save file to be run by the server. This distinction is provided to + facilitate switching between multiple save files. + +### Factorio Configurations + +Settings for various config files can be set in dictionaries loosely named after +the file. Each dictionary starts with `factorio_` followed by the filename +(excluding the filetype extension) where hyphens ( - ) are replaced by +underscores ( _ ). For example, the `server-settings.json` file is associated +with the dictionary variable `factorio_server_settings`. + +The `default/` folder contains serveral files showing example dictionaries +representing the values provided by the Factorio servers various examples JSON +files. + +The following is a list of config files that have been implemented: + +- Filename: `server-settings.json`
+ Variable: `factorio_server_settings`
+ Example: + ``` + factorio_server_settings: + name: "My Public Server" + max_players: 10 + game_password: "mypassword" + visibility: + public: true + lan: true + ``` + +- Filename: `server-whitelist.json`
+ Variable: `factorio_server_whitelist`
+ Example: + ``` + factorio_server_whitelist: + - Oxyd + ``` + +- Filename: `map-settings.json`
+ Variable: `factorio_map_settings`
+ Example: + ``` + factorio_map_settings: + pollution: + enabled: false + ``` + +- Filename: `map-gen-settings.json`
+ Variable: `factorio_map_gen_settings`
+ Example: + ``` + factorio_map_gen_settings: + water: "high" + autoplace_controles: + coal: + size: "very-low" + ``` + +## Example Playbooks + +An out of the box example might look as follows: + +``` +--- +- name: Create a default factorio server + hosts: localhost + roles: + - role: bplower.factorio +``` + +An example with a non-default port, and customized name: +``` +--- +- name: My slightly changed factorio server + hosts: localhost + roles: + - role: bplower.factorio + service_port: 12345 + factorio_server_settings: + name: "My factorio server" +``` + +An example of multiple servers on a single host: +``` +--- +- name: Factorio farm + hosts: localhost + roles: + - role: bplower.factorio + service_port: 50001 + service_name: factorio_1 + service_root: /home/{{ service_user }}/{{ service_name }} + - role: bplower.factorio + service_port: 50002 + service_name: factorio_2 + service_root: /home/{{ service_user }}/{{ service_name }} +``` + +## License + +GNU GPLv3 + +# Development & Contributions + +I don't use this project regularly anymore, but I try to keep it up to date when +possible. If you have any issues or questions about it, I encourage you to open +a PR or issue. + +## Testing + +This role uses yamllint for yaml validation, and molecule + docker for testing. +Both tools can be installed using the `dev-requirements.txt` file. You will need +to install docker separately. + +``` +pip install -r dev-requirements.txt` +``` + +Grouping all supported platforms together caused issues for CI, so the test are +split into 3 scenarios based on the platforms being tested. + +The makefile can be used to start each of the tests, and supports a helpmenu with +descriptions for each target: + +``` +$ make help + +Usage: + make + +Targets: + help Display this help + lint Lint yaml files + test_all Run all molecule tests + test_centos Run molecule centos tests + test_debian Run molecule debian tests + test_ubuntu Run molecule ubuntu tests +``` diff --git a/roles/factorio/defaults/main.yml b/roles/factorio/defaults/main.yml new file mode 100644 index 0000000..1941601 --- /dev/null +++ b/roles/factorio/defaults/main.yml @@ -0,0 +1,44 @@ +--- +# defaults file for factorio +server_version: "0.17.79" +server_sources: "/opt/games/sources/factorio" +download_url: "https://www.factorio.com/get-download/{{ server_version }}/headless/linux64" +download_checksum: "sha256:9ace12fa986df028dc1851bf4de2cb038044d743e98823bc1c48ba21aa4d23df" + +# Configs for the service running the server +service_name: "factorio-server" +service_user: "factorio" +service_group: "factorio" +service_root: "/home/{{ service_user }}" +service_port: 34197 +service_restart_permitted: true +factorio_default_save: "{{ service_root }}/factorio/saves/default-save.zip" +factorio_target_save: "{{ factorio_default_save }}" + +# Configs for the factorio server. These examples were copied from +# server-settings.example.json and are saved in server-settings.json +factorio_server_settings: {} + +# Do not define server settings in this dictionary. This dictionary allows you +# to overwrite a single setting without requiring you to provide other defaults. +# See the documentation for more information. +default_factorio_server_settings: + name: "Name of the game as it will appear in the game listing" + description: "Description of the game that will appear in the listing" + visibility: + public: false + lan: true + +# server-whitelist.json settings +factorio_server_whitelist_enabled: false +# factorio_server_whitelist: [] + +# map-gen-settings.json settings +factorio_map_gen_settings_enabled: false +# factorio_map_gen_settings: {} + +# map-settings.json settings +factorio_map_settings_enabled: false +# factorio_map_settings: {} + +ansible_name_prefix: "({{ service_name }})" diff --git a/roles/factorio/defaults/map-gen-settings.yml b/roles/factorio/defaults/map-gen-settings.yml new file mode 100644 index 0000000..23a69ee --- /dev/null +++ b/roles/factorio/defaults/map-gen-settings.yml @@ -0,0 +1,40 @@ +--- +# Settings for the map-gen-settings.json file +# Right now this is just an example of the default values as shown in the +# map-gen-settings.example.json file that's provided with the factorio server + +factorio_map_gen_settings: + # Sizes can be specified as none, very-low, low, normal, high, very-high + terrain_segmentation: "normal" + water: "normal" + width: 0 + height: 0 + starting_area: "normal" + peaceful_mode: false + autoplace_controls: + coal: + frequency: "normal" + size: "normal" + richness: "normal" + copper-ore: + frequency: "normal" + size: "normal" + richness: "normal" + crude-oil: + frequency: "normal" + size: "normal" + richness: "normal" + enemy-base: + frequency: "normal" + size: "normal" + richness: "normal" + iron-ore: + frequency: "normal" + size: "normal" + richness: "normal" + stone: + frequency: "normal" + size: "normal" + richness: "normal" + # Use null for a random seed, number for a specific seed. + seed: null diff --git a/roles/factorio/defaults/map-settings.yml b/roles/factorio/defaults/map-settings.yml new file mode 100644 index 0000000..f3450da --- /dev/null +++ b/roles/factorio/defaults/map-settings.yml @@ -0,0 +1,99 @@ +--- +# Settings for the map-settings.json file +# Right now this is just an example of the default values as shown in the +# map-settings.example.json file that's provided with the factorio server + +factorio_map_settings: + difficulty_settings: + recipe_difficulty: 1 + technology_difficulty: 1 + technology_price_multiplier: 1 + pollution: + enabled: true + # these are values for 60 ticks (1 simulated second) amount that is + # diffused to neighboring chunk + diffusion_ratio: 0.02 + min_to_diffuse: 15 + ageing: 1 + expected_max_per_chunk: 7000 + min_to_show_per_chunk: 700 + min_pollution_to_damage_trees: 3500 + pollution_with_max_forest_damage: 10000 + pollution_per_tree_damage: 2000 + pollution_restored_per_tree_damage: 500 + max_pollution_to_restore_trees: 1000 + enemy_evolution: + enabled: true + time_factor: 0.000004 + destroy_factor: 0.002 + pollution_factor: 0.000015 + enemy_expansion: + enabled: true + min_base_spacing: 3 + max_expansion_distance: 7 + friendly_base_influence_radius: 2 + enemy_building_influence_radius: 2 + building_coefficient: 0.1 + other_base_coefficient: 2.0 + neighbouring_chunk_coefficient: 0.5 + neighbouring_base_chunk_coefficient: 0.4 + max_colliding_tiles_coefficient: 0.9 + settler_group_min_size: 5 + settler_group_max_size: 20 + min_expansion_cooldown: 14400 + max_expansion_cooldown: 216000 + unit_group: + min_group_gathering_time: 3600 + max_group_gathering_time: 36000 + max_wait_time_for_late_members: 7200 + max_group_radius: 30.0 + min_group_radius: 5.0 + max_member_speedup_when_behind: 1.4 + max_member_slowdown_when_ahead: 0.6 + max_group_slowdown_factor: 0.3 + max_group_member_fallback_factor: 3 + member_disown_distance: 10 + tick_tolerance_when_member_arrives: 60 + max_gathering_unit_groups: 30 + max_unit_group_size: 200 + steering: + default: + radius: 1.2 + separation_force: 0.005 + separation_factor: 1.2 + force_unit_fuzzy_goto_behavior: false + moving: + radius: 3 + separation_force: 0.01 + separation_factor: 3 + force_unit_fuzzy_goto_behavior: false + path_finder: + fwd2bwd_ratio: 5 + goal_pressure_ratio: 2 + max_steps_worked_per_tick: 100 + use_path_cache: true + short_cache_size: 5 + long_cache_size: 25 + short_cache_min_cacheable_distance: 10 + short_cache_min_algo_steps_to_cache: 50 + long_cache_min_cacheable_distance: 30 + cache_max_connect_to_cache_steps_multiplier: 100 + cache_accept_path_start_distance_ratio: 0.2 + cache_accept_path_end_distance_ratio: 0.15 + negative_cache_accept_path_start_distance_ratio: 0.3 + negative_cache_accept_path_end_distance_ratio: 0.3 + cache_path_start_distance_rating_multiplier: 10 + cache_path_end_distance_rating_multiplier: 20 + stale_enemy_with_same_destination_collision_penalty: 30 + ignore_moving_enemy_collision_distance: 5 + enemy_with_different_destination_collision_penalty: 30 + general_entity_collision_penalty: 10 + general_entity_subsequent_collision_penalty: 3 + max_clients_to_accept_any_new_request: 10 + max_clients_to_accept_short_new_request: 100 + direct_distance_to_consider_short_request: 100 + short_request_max_steps: 1000 + short_request_ratio: 0.5 + min_steps_to_check_path_find_termination: 2000 + start_to_goal_cost_multiplier_to_terminate_path_find: 500.0 + max_failed_behavior_count: 3 diff --git a/roles/factorio/defaults/server-settings.yml b/roles/factorio/defaults/server-settings.yml new file mode 100644 index 0000000..c103f2b --- /dev/null +++ b/roles/factorio/defaults/server-settings.yml @@ -0,0 +1,70 @@ +--- +# Settings for the server-settings.json file +# Right now this is just an example of the default values as shown in the +# server-settings.example.json file that's provided with the factorio server + +factorio_server_settings: + name: "Name of the game as it will appear in the game listing" + + description: "Description of the game that will appear in the listing" + + tags: ["game", "tags"] + + # Maximum number of players allowed, admins can join even a full server. + # 0 means unlimited. + max_players: 0 + + # public: Game will be published on the official Factorio matching server + # lan: Game will be broadcast on LAN + visibility: + public: true + lan: true + + # Your factorio.com login credentials. Required for games with visibility + # public + username: "" + password: "" + + # Authentication token. May be used instead of 'password' above. + token: "" + + game_password: "" + + # When set to true, the server will only allow clients that have a valid + # Factorio.com account + require_user_verification: true + + # optional, default value is 0. 0 means unlimited.", + max_upload_in_kilobytes_per_second: 0 + + # optional one tick is 16ms in default speed, default value is 0. 0 means no + # minimum. + minimum_latency_in_ticks: 0 + + # Players that played on this map already can join even when the max player + # limit was reached. + ignore_player_limit_for_returning_players: false + + # possible values are, true, false and admins-only + allow_commands: "admins-only" + + # Autosave interval in minutes + autosave_interval: 10 + + # server autosave slots, it is cycled through when the server autosaves. + autosave_slots: 5 + + # How many minutes until someone is kicked when doing nothing, 0 for never. + afk_autokick_interval: 0 + + # Whether should the server be paused when no players are present. + auto_pause: true + + only_admins_can_pause_the_game: true + + # Whether autosaves should be saved only on server or also on all connected + # clients. Default is true. + autosave_only_on_server: true + + # List of case insensitive usernames, that will be promoted immediately + admins: [] diff --git a/roles/factorio/defaults/server-whitelist.yml b/roles/factorio/defaults/server-whitelist.yml new file mode 100644 index 0000000..8f50448 --- /dev/null +++ b/roles/factorio/defaults/server-whitelist.yml @@ -0,0 +1,8 @@ +--- +# Settings for the server-whitelist.json file +# Right now this is just an example of the default values as shown in the +# server-whitelist.example.json file that's provided with the factorio server + +factorio_server_whitelist: + - Rseding91 + - Oxyd diff --git a/roles/factorio/dev-requirements.txt b/roles/factorio/dev-requirements.txt new file mode 100644 index 0000000..8e5a6ff --- /dev/null +++ b/roles/factorio/dev-requirements.txt @@ -0,0 +1,2 @@ +yamllint +molecule[docker] diff --git a/roles/factorio/handlers/main.yml b/roles/factorio/handlers/main.yml new file mode 100644 index 0000000..0e419b4 --- /dev/null +++ b/roles/factorio/handlers/main.yml @@ -0,0 +1,13 @@ +--- +# handlers file for factorio + +- name: Reload factorio server (daemon_reload) + systemd: + name: "{{ service_name }}" + daemon_reload: yes + +- name: Restart factorio service + systemd: + name: "{{ service_name }}" + state: restarted + when: service_restart_permitted diff --git a/roles/factorio/makefile b/roles/factorio/makefile new file mode 100644 index 0000000..a05bcac --- /dev/null +++ b/roles/factorio/makefile @@ -0,0 +1,21 @@ +.DEFAULT_GOAL:=help + +.PHONY: help deps clean build watch + +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) + +lint: ## Lint yaml files + yamllint . + +test_all: ## Run molecule tests + molecule test --all + +test_centos: ## Run molecule centos tests + molecule test --scenario-name centos + +test_debian: ## Run molecule debian tests + molecule test --scenario-name debian + +test_ubuntu: ## Run molecule ubuntu tests + molecule test --scenario-name ubuntu diff --git a/roles/factorio/meta/.galaxy_install_info b/roles/factorio/meta/.galaxy_install_info new file mode 100644 index 0000000..e8ffbb2 --- /dev/null +++ b/roles/factorio/meta/.galaxy_install_info @@ -0,0 +1,2 @@ +install_date: Tue Dec 22 03:10:51 2020 +version: master diff --git a/roles/factorio/meta/main.yml b/roles/factorio/meta/main.yml new file mode 100644 index 0000000..5e3baf3 --- /dev/null +++ b/roles/factorio/meta/main.yml @@ -0,0 +1,21 @@ +--- +galaxy_info: + author: Brahm Lower + description: A role for creating Factorio servers + license: license (GPLv3) + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - 8 + - name: Ubuntu + versions: + - bionic + - focal + - name: Debian + version: + - stretch + - buster + galaxy_tags: + - factorio +dependencies: [] diff --git a/roles/factorio/molecule/centos/INSTALL.rst b/roles/factorio/molecule/centos/INSTALL.rst new file mode 100644 index 0000000..d926ca2 --- /dev/null +++ b/roles/factorio/molecule/centos/INSTALL.rst @@ -0,0 +1,22 @@ +******* +Docker driver installation guide +******* + +Requirements +============ + +* Docker Engine + +Install +======= + +Please refer to the `Virtual environment`_ documentation for installation best +practices. If not using a virtual environment, please consider passing the +widely recommended `'--user' flag`_ when invoking ``pip``. + +.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ +.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site + +.. code-block:: bash + + $ python3 -m pip install 'molecule[docker]' diff --git a/roles/factorio/molecule/centos/converge.yml b/roles/factorio/molecule/centos/converge.yml new file mode 100644 index 0000000..7a8a67d --- /dev/null +++ b/roles/factorio/molecule/centos/converge.yml @@ -0,0 +1,10 @@ +--- +- name: Converge + hosts: all + tasks: + - name: "Include ansible-factorio" + include_role: + name: "ansible-factorio" + vars: + service_name: foobar + server_version: 0.17.79 diff --git a/roles/factorio/molecule/centos/molecule.yml b/roles/factorio/molecule/centos/molecule.yml new file mode 100644 index 0000000..1772a58 --- /dev/null +++ b/roles/factorio/molecule/centos/molecule.yml @@ -0,0 +1,16 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance_centos8 + image: jrei/systemd-centos:8 + privileged: true + command: /sbin/init + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro +provisioner: + name: ansible +verifier: + name: ansible diff --git a/roles/factorio/molecule/centos/verify.yml b/roles/factorio/molecule/centos/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/roles/factorio/molecule/centos/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/roles/factorio/molecule/debian/INSTALL.rst b/roles/factorio/molecule/debian/INSTALL.rst new file mode 100644 index 0000000..d926ca2 --- /dev/null +++ b/roles/factorio/molecule/debian/INSTALL.rst @@ -0,0 +1,22 @@ +******* +Docker driver installation guide +******* + +Requirements +============ + +* Docker Engine + +Install +======= + +Please refer to the `Virtual environment`_ documentation for installation best +practices. If not using a virtual environment, please consider passing the +widely recommended `'--user' flag`_ when invoking ``pip``. + +.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ +.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site + +.. code-block:: bash + + $ python3 -m pip install 'molecule[docker]' diff --git a/roles/factorio/molecule/debian/converge.yml b/roles/factorio/molecule/debian/converge.yml new file mode 100644 index 0000000..7a8a67d --- /dev/null +++ b/roles/factorio/molecule/debian/converge.yml @@ -0,0 +1,10 @@ +--- +- name: Converge + hosts: all + tasks: + - name: "Include ansible-factorio" + include_role: + name: "ansible-factorio" + vars: + service_name: foobar + server_version: 0.17.79 diff --git a/roles/factorio/molecule/debian/molecule.yml b/roles/factorio/molecule/debian/molecule.yml new file mode 100644 index 0000000..dbb8425 --- /dev/null +++ b/roles/factorio/molecule/debian/molecule.yml @@ -0,0 +1,22 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance_debian9 + image: jrei/systemd-debian:9 + privileged: true + command: /sbin/init + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - name: instance_debian10 + image: jrei/systemd-debian:10 + privileged: true + command: /sbin/init + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro +provisioner: + name: ansible +verifier: + name: ansible diff --git a/roles/factorio/molecule/debian/verify.yml b/roles/factorio/molecule/debian/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/roles/factorio/molecule/debian/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/roles/factorio/molecule/ubuntu/INSTALL.rst b/roles/factorio/molecule/ubuntu/INSTALL.rst new file mode 100644 index 0000000..d926ca2 --- /dev/null +++ b/roles/factorio/molecule/ubuntu/INSTALL.rst @@ -0,0 +1,22 @@ +******* +Docker driver installation guide +******* + +Requirements +============ + +* Docker Engine + +Install +======= + +Please refer to the `Virtual environment`_ documentation for installation best +practices. If not using a virtual environment, please consider passing the +widely recommended `'--user' flag`_ when invoking ``pip``. + +.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ +.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site + +.. code-block:: bash + + $ python3 -m pip install 'molecule[docker]' diff --git a/roles/factorio/molecule/ubuntu/converge.yml b/roles/factorio/molecule/ubuntu/converge.yml new file mode 100644 index 0000000..7a8a67d --- /dev/null +++ b/roles/factorio/molecule/ubuntu/converge.yml @@ -0,0 +1,10 @@ +--- +- name: Converge + hosts: all + tasks: + - name: "Include ansible-factorio" + include_role: + name: "ansible-factorio" + vars: + service_name: foobar + server_version: 0.17.79 diff --git a/roles/factorio/molecule/ubuntu/molecule.yml b/roles/factorio/molecule/ubuntu/molecule.yml new file mode 100644 index 0000000..7cf561a --- /dev/null +++ b/roles/factorio/molecule/ubuntu/molecule.yml @@ -0,0 +1,22 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance_ubuntu1804 + image: jrei/systemd-ubuntu:18.04 + privileged: true + command: /sbin/init + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - name: instance_ubuntu2004 + image: jrei/systemd-ubuntu:20.04 + privileged: true + command: /sbin/init + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro +provisioner: + name: ansible +verifier: + name: ansible diff --git a/roles/factorio/molecule/ubuntu/verify.yml b/roles/factorio/molecule/ubuntu/verify.yml new file mode 100644 index 0000000..a82dd6f --- /dev/null +++ b/roles/factorio/molecule/ubuntu/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + assert: + that: true diff --git a/roles/factorio/tasks/main.yml b/roles/factorio/tasks/main.yml new file mode 100644 index 0000000..d3fc655 --- /dev/null +++ b/roles/factorio/tasks/main.yml @@ -0,0 +1,90 @@ +--- +# tasks file for factorio +# Create the user and group to run the factorio server +- name: "{{ ansible_name_prefix }} Create OS group for factorio" + group: + name: "{{ service_group }}" + state: present + +- name: "{{ ansible_name_prefix }} Create OS user for factorio" + user: + name: "{{ service_user }}" + state: present + group: "{{ service_group }}" + +# Download the factorio server version if needed +- name: "{{ ansible_name_prefix }} Make factorio bin source folder" + file: + path: "{{ server_sources }}" + state: directory + mode: u+rwx + +- name: "{{ ansible_name_prefix }} Download factorio headless server from {{ download_url }}" + get_url: + url: "{{ download_url }}" + dest: "{{ server_sources }}/factorio-{{ server_version }}.tar.gz" + checksum: "{{ download_checksum }}" + retries: 3 + delay: 5 + +# Copy the factorio version to the production location +- name: "{{ ansible_name_prefix }} Make factorio bin source folder" + file: + path: "{{ service_root }}" + state: directory + mode: u+rwx + +- name: "{{ ansible_name_prefix }} Extract Factorio headless server to {{ server_sources }}" + unarchive: + src: "{{ server_sources }}/factorio-{{ server_version }}.tar.gz" + copy: no + dest: "{{ service_root }}" + creates: "{{ service_root }}/factorio" + +- name: "{{ ansible_name_prefix }} Make sure game save directory exists" + file: + path: "{{ service_root }}/factorio/saves" + state: directory + mode: u+rwx + +# Create the various settings files +- name: "{{ ansible_name_prefix }} Set server settings" + include: set-server-settings.yml + +- name: "{{ ansible_name_prefix }} Set server whitelist" + include: set-server-whitelist.yml + +- name: "{{ ansible_name_prefix }} Set map gen settings" + include: set-map-gen-settings.yml + +- name: "{{ ansible_name_prefix }} Set map settings" + include: set-map-settings.yml + +# Create the save if one doesn't already exist +- name: "{{ ansible_name_prefix }} Create default save file" + command: "{{ service_root }}/factorio/bin/x64/factorio --create {{ factorio_target_save }}" + args: + creates: "{{ factorio_target_save }}" + +# Set the permissions so only the user has access +- name: "{{ ansible_name_prefix }} Make {{ service_root }} owned by {{ service_user }}" + file: + path: "{{ service_root }}" + state: directory + owner: "{{ service_user }}" + group: "{{ service_group }}" + recurse: yes + +# Create the service +- name: "{{ ansible_name_prefix }} Create service file" + template: + src: service-template.service.j2 + dest: /etc/systemd/system/{{ service_name }}.service + mode: "u=rwx,g=r,o=r" + vars: + bin: "{{ service_root }}/factorio/bin/x64/factorio" + save: "{{ factorio_target_save }}" + description: "Factorio {{ server_version }} {{ service_name }}" + notify: + - Reload factorio server (daemon_reload) + - Restart factorio service diff --git a/roles/factorio/tasks/set-map-gen-settings.yml b/roles/factorio/tasks/set-map-gen-settings.yml new file mode 100644 index 0000000..dca8913 --- /dev/null +++ b/roles/factorio/tasks/set-map-gen-settings.yml @@ -0,0 +1,18 @@ +--- +# Set the content of map-gen-settings.json + +- name: ({{ service_name }}) Create map-gen-settings.json file + copy: + content: "{{ factorio_map_gen_settings | to_json }}" + dest: "{{ service_root }}/factorio/data/map-gen-settings.json" + when: factorio_map_gen_settings_enabled + notify: + - Restart factorio service + +- name: ({{ service_name }}) Remove map-gen-settings.json file + file: + path: "{{ service_root }}/factorio/data/map-gen-settings.json" + state: absent + when: not factorio_map_gen_settings_enabled + notify: + - Restart factorio service diff --git a/roles/factorio/tasks/set-map-settings.yml b/roles/factorio/tasks/set-map-settings.yml new file mode 100644 index 0000000..debaa19 --- /dev/null +++ b/roles/factorio/tasks/set-map-settings.yml @@ -0,0 +1,18 @@ +--- +# Set the content of map-settings.json + +- name: ({{ service_name }}) Create map-settings.json file + copy: + content: "{{ factorio_map_settings | to_json }}" + dest: "{{ service_root }}/factorio/data/map-settings.json" + when: factorio_map_settings_enabled + notify: + - Restart factorio service + +- name: ({{ service_name }}) Remove map-settings.json file + file: + path: "{{ service_root }}/factorio/data/map-settings.json" + state: absent + when: not factorio_map_settings_enabled + notify: + - Restart factorio service diff --git a/roles/factorio/tasks/set-server-settings.yml b/roles/factorio/tasks/set-server-settings.yml new file mode 100644 index 0000000..b2c4c99 --- /dev/null +++ b/roles/factorio/tasks/set-server-settings.yml @@ -0,0 +1,25 @@ +--- +# Set the content of server-settings.json + +# Two tasks are used here as a somewhat lazy way around `factorio_server_settings` +# being passed to the `combine()` function when it hasn't been defined by the +# user. The default definition for it in defaults/main.py is an empty dict +# which for some reason results in being interpreted as undefined. + +# Open a pull request if you know a better way + +- name: ({{ service_name }}) Create server-settings.json file (overwriting defaults) + copy: + content: "{{ default_factorio_server_settings|combine(factorio_server_settings) | to_json }}" + dest: "{{ service_root }}/factorio/data/server-settings.json" + when: factorio_server_settings + notify: + - Restart factorio service + +- name: ({{ service_name }}) Create server-settings.json file (using defaults) + copy: + content: "{{ default_factorio_server_settings | to_json }}" + dest: "{{ service_root }}/factorio/data/server-settings.json" + when: not factorio_server_settings + notify: + - Restart factorio service diff --git a/roles/factorio/tasks/set-server-whitelist.yml b/roles/factorio/tasks/set-server-whitelist.yml new file mode 100644 index 0000000..c3b6f01 --- /dev/null +++ b/roles/factorio/tasks/set-server-whitelist.yml @@ -0,0 +1,18 @@ +--- +# Set the content of server-whitelist.json + +- name: ({{ service_name }}) Create server-whitelist.json file + copy: + content: "{{ factorio_server_whitelist | to_json }}" + dest: "{{ service_root }}/factorio/data/server-whitelist.json" + when: factorio_server_whitelist_enabled + notify: + - Restart factorio service + +- name: ({{ service_name }}) Remove server-whitelist.json file + file: + path: "{{ service_root }}/factorio/data/server-whitelist.json" + state: absent + when: not factorio_server_whitelist_enabled + notify: + - Restart factorio service diff --git a/roles/factorio/templates/service-template.service.j2 b/roles/factorio/templates/service-template.service.j2 new file mode 100644 index 0000000..50c2597 --- /dev/null +++ b/roles/factorio/templates/service-template.service.j2 @@ -0,0 +1,10 @@ +[Unit] +Description={{ description }} + +[Service] +ExecStart={{ bin }} --start-server {{ save }} --port {{ service_port }} --server-settings {{ service_root }}/factorio/data/server-settings.json +User={{ service_user }} +Group={{ service_group }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/factorio/vars/main.yml b/roles/factorio/vars/main.yml new file mode 100644 index 0000000..c8b378b --- /dev/null +++ b/roles/factorio/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for factorio diff --git a/roles/requirements.yml b/roles/requirements.yml index b673502..90ba4d1 100644 --- a/roles/requirements.yml +++ b/roles/requirements.yml @@ -34,3 +34,9 @@ - src: nkakouros.nextcloud version: master name: nextcloud + +# Game Servers +# Upstream: https://github.com/bplower/ansible-factorio +- src: bplower.factorio + version: master + name: factorio