diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore deleted file mode 100644 index f494b1b6a..000000000 --- a/.devcontainer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.tool-versions diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index d5b0dd0f1..000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,121 +0,0 @@ -FROM ubuntu:bionic AS dev-base - -ARG USER_UID=1000 -ARG USER_GID=$USER_UID -ARG USERNAME=vscode - -ENV DEBIAN_FRONTEND=noninteractive - -RUN echo "APT::Install-Recommends 0;" >> /etc/apt/apt.conf.d/01norecommends \ - && echo "APT::Install-Suggests 0;" >> /etc/apt/apt.conf.d/01norecommends \ - && apt update \ - && apt upgrade -y \ - && apt install -y \ - apt-utils \ - dialog \ - wget \ - net-tools \ - wireguard \ - nftables \ - inotify-tools \ - ca-certificates \ - build-essential \ - less \ - automake \ - autoconf \ - libreadline-dev \ - libncurses-dev \ - libssl-dev \ - libyaml-dev \ - libxslt-dev \ - libffi-dev \ - libtool \ - zlib1g-dev \ - unixodbc-dev \ - unzip \ - curl \ - git \ - vim \ - sudo \ - bsdmainutils \ - gpg \ - dirmngr \ - jq \ - locales \ - # Clean up - && apt-get autoremove -y \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* \ - && groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_GID --gid $USERNAME --shell /bin/bash --create-home --groups sudo $USERNAME \ - && echo "%${USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USERNAME} \ - && mkdir -p /home/$USERNAME/.vscode-server/extensions \ - /home/$USERNAME/.vscode-server-insiders/extensions \ - && chown -R $USERNAME \ - /home/$USERNAME/.vscode-server \ - /home/$USERNAME/.vscode-server-insiders \ - && mkdir -p /workspace \ - && chown -R $USERNAME /workspace - -# Set the locale to en_US.UTF-8 and TZ to UTC -RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ - locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 -ENV TZ 'UTC' - -ENV DEBIAN_FRONTEND=dialog - -FROM dev-base AS setup-asdf - -ARG USERNAME=vscode - -RUN git clone https://github.com/asdf-vm/asdf.git /opt/asdf \ - && cd /opt/asdf \ - && git checkout "$(git describe --abbrev=0 --tags)" \ - && mkdir /opt/asdf-data \ - && chown -R $USERNAME /opt/asdf-data - -FROM setup-asdf AS dev-env - -ARG USERNAME=vscode - -USER $USERNAME -WORKDIR /home/$USERNAME -ENV HOME=/home/$USERNAME \ - ASDF_DIR="/opt/asdf" \ - ASDF_DATA_DIR="/opt/asdf-data" - -RUN echo '\n. /opt/asdf/asdf.sh' >> ~/.bashrc \ - && echo '\n. /opt/asdf/completions/asdf.bash' >> ~/.bashrc - -SHELL ["/bin/bash", "-ic"] - -RUN asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang.git && \ - asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git && \ - asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git && \ - asdf plugin-add python https://github.com/danhper/asdf-python.git && \ - asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git - -# Need global erlang version to install Elixir - https://github.com/asdf-vm/asdf-elixir/issues/113 -COPY .tool-versions /home/vscode/.tool-versions - -# No order to asdf, so elixir error without Erlang -RUN asdf install erlang && asdf install - -RUN mix local.hex --force -RUN mix local.rebar --force - -VOLUME ["${ASDF_DATA_DIR}"] - -# Pre-commit install with deps -RUN pip install setuptools wheel -RUN pip install pre-commit -RUN gem install rubocop - -ENV PATH=${HOME}/.local/bin:/opt/asdf-data/shims:/opt/asdf/bin:${PATH} - -RUN git config --global --add safe.directory /workspace - -CMD ["/bin/bash"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md deleted file mode 100644 index e93a1c2bd..000000000 --- a/.devcontainer/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# DevContainer - -Files in this directory are used exclusively for VS Code / Github Codespaces. - -For a general overview of how to run Firezone in Docker locally, see [our -contributing guide](../CONTRIBUTING.md). diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 21972c1fa..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,30 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.231.6/containers/elixir-phoenix-postgres -{ - "name": "Firezone", - "dockerComposeFile": "docker-compose.yml", - "service": "elixir", - "workspaceFolder": "/workspace", - - // Set *default* container specific settings.json values on container create. - "settings": {}, - - "initializeCommand": [".devcontainer/init"], - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "jakebecker.elixir-ls", - "phoenixframework.phoenix", - "rebornix.ruby" - ], - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // This can be used to network with other containers or with the host. - "forwardPorts": [80, 443, 4000, 5432], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "mix deps.get" - - // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" -} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml deleted file mode 100644 index 15e276f95..000000000 --- a/.devcontainer/docker-compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: "3.8" - -services: - caddy: - image: caddy:2 - volumes: - - ./Caddyfile:/etc/caddy/Caddyfile - network_mode: service:firezone - - firezone: - build: - context: . - dockerfile: Dockerfile - args: - # Elixir Version: 1.9, 1.10, 1.10.4, ... - VARIANT: "1.14.0" - # Phoenix Version: 1.4.17, 1.5.4, ... - PHOENIX_VERSION: "1.6.12" - # Node Version: 12, 14, ... - NODE_VERSION: "16" - RUBY_VERSION: "2.7.6" - - volumes: - - ..:/workspace:cached - # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. - network_mode: service:postgres - - environment: - LOCAL_AUTH_ENABLED: 'true' - - # Overrides default command so things don't shut down after the process ends. - command: sleep infinity - - postgres: - image: postgres:13 - restart: unless-stopped - volumes: - - postgres-data:/var/lib/postgresql/data - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: firezone_dev - -volumes: - postgres-data: diff --git a/.devcontainer/init b/.devcontainer/init deleted file mode 100755 index 6e78b1eb1..000000000 --- a/.devcontainer/init +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -cp .tool-versions .devcontainer/.tool-versions diff --git a/.devcontainer/init.cmd b/.devcontainer/init.cmd deleted file mode 100644 index 5d5885f01..000000000 --- a/.devcontainer/init.cmd +++ /dev/null @@ -1 +0,0 @@ -copy .\.tool-versions .\.devcontainer\.tool-versions diff --git a/.dockerignore b/.dockerignore index 74c30fc91..033d76adb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,10 +2,6 @@ apps/fz_http/assets/node_modules apps/fz_http/priv/static/dist apps/fz_http/priv/cert _build -apps/fz_http/_build -apps/fz_wall/_build -apps/fz_vpn/_build -apps/fz_common/_build **/cover docs .DS_Store diff --git a/.github/workflows/omnibus_build.yml b/.github/workflows/omnibus_build.yml index 1fe3d5d64..84ebb8e5b 100644 --- a/.github/workflows/omnibus_build.yml +++ b/.github/workflows/omnibus_build.yml @@ -100,7 +100,7 @@ jobs: - name: Cleanup if: always() run: | - sudo scripts/uninstall.sh + sudo scripts/omnibus-uninstall.sh sudo rm -rf /tmp/firezone* rm -rf omnibus/pkg/* diff --git a/.gitignore b/.gitignore index fe5338137..39be23a21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # macOS cruft .DS_Store -.devcontainer/pki/authorities/local/ +priv/pki/authorities/local/ # The directory Mix will write compiled artifacts to. /_build/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 274b4e91a..e7c82001f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,8 +15,6 @@ started. * [The .env File](#the-env-file) * [Bootstrapping](#bootstrapping) * [Ensure Everything Works](#ensure-everything-works) - * [Running this inside a Devcontainer](#running-this-inside-a-devcontainer) - * [Note: Devcontainer on Windows](#note--devcontainer-on-windows) * [Reporting Bugs](#reporting-bugs) * [Opening a Pull Request](#opening-a-pull-request) * [Run Tests](#run-tests) @@ -88,7 +86,7 @@ machine, and out to the external Internet should work as well. ### Local HTTPS We use Caddy as a development proxy. The `docker-compose.yml` is set up to link -Caddy's local root cert into your `.devcontainer/pki/authorities/local/` directory. +Caddy's local root cert into your `priv/pki/authorities/local/` directory. Simply add the `root.crt` file to your browser and/or OS certificate store in order to have working local HTTPS. This file is generated when Caddy launches for @@ -139,7 +137,7 @@ To start the local development cluster, follow these steps: ``` docker compose build docker compose up -d postgres -docker compose run --rm elixir mix ecto.setup +docker compose run --rm firezone mix ecto.setup docker compose up ``` @@ -151,7 +149,7 @@ and sign in with email `firezone@localhost` and password `firezone1234`. There is a `client` container in the docker-compose configuration that can be used to simulate a WireGuard client connecting to Firezone. It's already provisioned in the Firezone development cluster and has a corresponding -WireGuard configuration located at .devcontainer/wg0.client.conf. +WireGuard configuration located at `priv/wg0.client.conf`. It's attached to the `isolation` Docker network which is isolated from the other Firezone Docker services. By connecting to Firezone from the `client` container, you can test the WireGuard tunnel is set up correctly by pinging the @@ -163,29 +161,6 @@ container, you can test the WireGuard tunnel is set up correctly by pinging the If the above commands indicate success, you should be good to go! -### Running this inside a Devcontainer - -You can run this using Github Codespaces or your own devcontainer using Docker. - -On GitHub Codespaces, follow the instructions above but pass in your Codespace -external url: - -`EXTERNAL_URL=[your_devcontainer_url] MIX_ENV=dev mix start` - -or using the `.env` file - -`env $(cat .env | grep -v \# | xargs) mix start` - -On Github Codespaces you can find your EXTERNAL_URL by issuing the following -command in the terminal: - -`echo "https://${CODESPACE_NAME}-4000.githubpreview.dev"` - -#### Note: Devcontainer on Windows - -If you are on Windows, make sure your git config `core.autocrlf` is off. Otherwise, -the `\r` characters confuse asdf, which in turn fails the devcontainer build. - ## Reporting Bugs We appreciate any and all bug reports. diff --git a/apps/fz_http/assets/package-lock.json b/apps/fz_http/assets/package-lock.json index 8d4992a15..71582ee62 100644 --- a/apps/fz_http/assets/package-lock.json +++ b/apps/fz_http/assets/package-lock.json @@ -37,14 +37,14 @@ } }, "../../../deps/phoenix": { - "version": "1.6.13", + "version": "1.7.0-rc.0", "license": "MIT" }, "../../../deps/phoenix_html": { "version": "3.2.0" }, "../../../deps/phoenix_live_view": { - "version": "0.18.2", + "version": "0.18.3", "license": "MIT" }, "local_modules/admin-one-bulma-dashboard": { diff --git a/apps/fz_http/lib/fz_http/devices.ex b/apps/fz_http/lib/fz_http/devices.ex index 9d4578bee..6d754f4f6 100644 --- a/apps/fz_http/lib/fz_http/devices.ex +++ b/apps/fz_http/lib/fz_http/devices.ex @@ -63,24 +63,17 @@ defmodule FzHttp.Devices do def get_device!(id), do: Repo.get!(Device, id) def create_device(attrs \\ %{}) do - # XXX: insert sometimes fails with deadlock errors, probably because - # of the giant SELECT in queries/inet.ex. Find a way to do this more gracefully. - {:ok, result} = - Repo.transaction(fn -> - %Device{} - |> Device.create_changeset(attrs) - |> Repo.insert() - end) - - case result do - {:ok, _device} -> + attrs + |> Device.create_changeset() + |> Repo.insert() + |> case do + {:ok, device} -> Telemetry.add_device() + {:ok, device} - _ -> - nil + {:error, changeset} -> + {:error, changeset} end - - result end def update_device(%Device{} = device, attrs) do diff --git a/apps/fz_http/lib/fz_http/devices/device.ex b/apps/fz_http/lib/fz_http/devices/device.ex index 46c7089a6..2faa185b2 100644 --- a/apps/fz_http/lib/fz_http/devices/device.ex +++ b/apps/fz_http/lib/fz_http/devices/device.ex @@ -61,7 +61,7 @@ defmodule FzHttp.Devices.Device do timestamps(type: :utc_datetime_usec) end - def create_changeset(device, attrs) do + def create_changeset(device \\ %__MODULE__{}, attrs) do device |> shared_cast(attrs) |> put_next_ip(:ipv4) diff --git a/apps/fz_http/mix.exs b/apps/fz_http/mix.exs index 0dc267f52..08953a69d 100644 --- a/apps/fz_http/mix.exs +++ b/apps/fz_http/mix.exs @@ -107,14 +107,10 @@ defmodule FzHttp.MixProject do # See the documentation for `Mix` for more info on aliases. defp aliases do [ - "ecto.seed": "run priv/repo/seeds.exs", - "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], + "ecto.seed": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], + "ecto.setup": ["ecto.create", "ecto.migrate"], "ecto.reset": ["ecto.drop", "ecto.setup"], - test: [ - "ecto.create --quiet", - "ecto.migrate", - "test" - ] + test: ["ecto.create --quiet", "ecto.migrate", "test"] ] end end diff --git a/apps/fz_http/test/fz_http/rules_test.exs b/apps/fz_http/test/fz_http/rules_test.exs index bfe94ab8f..9c1c6eea7 100644 --- a/apps/fz_http/test/fz_http/rules_test.exs +++ b/apps/fz_http/test/fz_http/rules_test.exs @@ -172,7 +172,7 @@ defmodule FzHttp.RulesTest do describe "as_settings/0" do setup [:create_rules] - test "Maps rules to projections", %{rules: rules} do + test "maps rules to projections", %{rules: rules} do expected_rules = Enum.map(rules, &Rules.setting_projection/1) |> MapSet.new() assert Rules.as_settings() == expected_rules diff --git a/apps/fz_http/test/support/fixtures/devices_fixtures.ex b/apps/fz_http/test/support/fixtures/devices_fixtures.ex index 267b04de4..11434f0bb 100644 --- a/apps/fz_http/test/support/fixtures/devices_fixtures.ex +++ b/apps/fz_http/test/support/fixtures/devices_fixtures.ex @@ -15,12 +15,16 @@ defmodule FzHttp.DevicesFixtures do default_attrs = %{ user_id: user_id, - public_key: "test-pubkey", - name: "factory", + public_key: "test-pubkey-#{counter()}", + name: "factory #{counter()}", description: "factory description" } {:ok, device} = Devices.create_device(Map.merge(default_attrs, attrs)) device end + + defp counter do + System.unique_integer([:positive]) + end end diff --git a/config/dev.exs b/config/dev.exs index 408170d6a..1da99c429 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -31,8 +31,15 @@ config :fz_http, FzHttpWeb.Endpoint, ] get_egress_interface = fn -> - egress_interface_cmd = "route | grep '^default' | grep -o '[^ ]*$'" - System.cmd("/bin/sh", ["-c", egress_interface_cmd]) |> elem(0) |> String.trim() + egress_interface_cmd = + case :os.type() do + {:unix, :darwin} -> "netstat -rn -finet | grep '^default' | awk '{print $NF;}'" + {_os_family, _os_name} -> "route | grep '^default' | grep -o '[^ ]*$'" + end + + System.cmd("/bin/sh", ["-c", egress_interface_cmd], stderr_to_stdout: true) + |> elem(0) + |> String.trim() end egress_interface = System.get_env("EGRESS_INTERFACE") || get_egress_interface.() diff --git a/docker-compose.yml b/docker-compose.yml index dbd396c9f..53c03e90a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,8 +18,8 @@ services: caddy: image: caddy:2 volumes: - - ./.devcontainer/Caddyfile:/etc/caddy/Caddyfile - - ./.devcontainer/pki:/data/caddy/pki + - ./priv/Caddyfile:/etc/caddy/Caddyfile + - ./priv/pki:/data/caddy/pki ports: - 80:80 - 443:443 @@ -209,7 +209,7 @@ services: - TZ=UTC - ALLOWEDIPS="0.0.0.0/0,::/0" volumes: - - ./.devcontainer/wg0.client.conf:/config/wg0.conf + - ./priv/wg0.client.conf:/config/wg0.conf cap_add: - NET_ADMIN - SYS_MODULE diff --git a/docs/docs/administer/uninstall.mdx b/docs/docs/administer/uninstall.mdx index 7df89e065..7c4bd94fc 100644 --- a/docs/docs/administer/uninstall.mdx +++ b/docs/docs/administer/uninstall.mdx @@ -27,10 +27,10 @@ rm -rf $installDir To completely remove Omnibus-based deployments of Firezone run the [uninstall.sh -script](https://github.com/firezone/firezone/blob/master/scripts/uninstall.sh): +script](https://github.com/firezone/firezone/blob/master/scripts/omnibus-uninstall.sh): ```bash -sudo /bin/bash -c "$(curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/uninstall.sh)" +sudo /bin/bash -c "$(curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/omnibus-uninstall.sh)" ``` diff --git a/mix.exs b/mix.exs index 6059237c6..35829f51f 100644 --- a/mix.exs +++ b/mix.exs @@ -70,10 +70,10 @@ defmodule FirezoneUmbrella.MixProject do defp aliases do [ - "ecto.seed": "run apps/fz_http/priv/repo/seeds.exs", - "ecto.setup": ["ecto.create", "ecto.migrate", "ecto.seed"], - "ecto.remigrate": ["ecto.drop", "ecto.create", "ecto.migrate"], + "ecto.seed": ["ecto.create", "ecto.migrate", "run apps/fz_http/priv/repo/seeds.exs"], + "ecto.setup": ["ecto.create", "ecto.migrate"], "ecto.reset": ["ecto.drop", "ecto.setup"], + test: ["ecto.create --quiet", "ecto.migrate", "test"], start: ["compile --no-validate-compile-env", "phx.server", "run --no-halt"] ] end diff --git a/omnibus/config/projects/firezone.rb b/omnibus/config/projects/firezone.rb index 8190557e5..d8b550871 100644 --- a/omnibus/config/projects/firezone.rb +++ b/omnibus/config/projects/firezone.rb @@ -50,7 +50,6 @@ dependency 'firezone-cookbooks' # XXX: Ensure all development resources aren't included exclude '.env' -exclude '.devcontainer' exclude '.github' exclude '.vagrant' exclude '.ci' diff --git a/.devcontainer/Caddyfile b/priv/Caddyfile similarity index 100% rename from .devcontainer/Caddyfile rename to priv/Caddyfile diff --git a/.devcontainer/wg0.client.conf b/priv/wg0.client.conf similarity index 100% rename from .devcontainer/wg0.client.conf rename to priv/wg0.client.conf diff --git a/scripts/uninstall.sh b/scripts/omnibus-uninstall.sh similarity index 100% rename from scripts/uninstall.sh rename to scripts/omnibus-uninstall.sh