I wanted to run this Elixir web application to enable myself to contribute sometime someday. I knew I was in for a ride.
Wrap-up and simplification of https://docs.akkoma.dev/develop/development/setting_up_akkoma_dev/.
It links to Debian-targetting https://docs.akkoma.dev/develop/installation/debian_based_en/ —
— but note that you can pick other distributions on the sidebar: https://docs.akkoma.dev/develop/installation/fedora_based_en/
Just not specifically openSUSE.
FOR_INSTALL=( git gcc make cmake file-devel )
FOR_INSTALL+=( postgresql-server postgresql-contrib )
FOR_INSTALL+=( elixir )
sudo zypper install ${FOR_INSTALL[@]}
git clone https://akkoma.dev/AkkomaGang/akkoma.git && cd akkoma
mix deps.get
mix pleroma.instance gen
It will now ask questions.
What domain will your instance use? (e.g akkoma.example.com) [] localhost
What base url will uploads use? (e.g https://media.example.com/media)
Generally this should NOT use the same domain as the instance [] localhost
What is the name of your instance? (e.g. The Corndog Emporium) [localhost]
What is your admin email address? [] admin@localhost
What email address do you want to use for sending email notifications? [admin@localhost]
Do you want search engines to index your site? (y/n) [y] n
— Press Enter for defaults from then on.
Inspect the result closely. I found this to be an error-prone step.
grep -UF $'\033' config/generated_config.exs && echo "Unwanted escape sequences."
LESS= less config/generated_config.exs
Check the generated config with a less with no flags enabled.
I checked with -R in my $LESS environment variable and you will learn the pitfall down this blog post.
Alternatively, use
cat -v config/generated_config.exs # purists hate this
mv config/{generated_config.exs,dev.secret.exs}
initdb -D ~/postgres_akkomy
echo "unix_socket_directories = '/tmp'" >> ~/postgres_akkomy/postgresql.conf
sed -E -i 's|(host +all +all +127.0.0.1/32 +)ident|\1md5|' ~/postgres_akkomy/pg_hba.conf
pg_ctl -D ~/postgres_akkomy -l ~/postgres_akkomy_log start
psql -f config/setup_db.psql -d postgres -h /tmp
mix ecto.migrate
mix phx.server
if you will want to later create a post quick, you can instead already jump into the IEx REPL with iex -S mix phx.server
- Here is where the Configuration Pitfall (below) occurs for me.
But if you have everything work —
- check http://localhost:4000
- check http://localhost:4000/whatever
— open another shell and run
mix pleroma.user new shrimple shrimple@shrimple.pl --password hey
To post post quick, if you haven’t already started with IEx REPL, Ctrl-C and (a)abort the server, then switch to iex -S mix phx.server
Once it starts up and you get shown the prompt,
iex(1)> me = Pleroma.User.get_by_nickname("shrimple")
iex(2)> Pleroma.Web.CommonAPI.post(me, %{status: "yo", visibility: "public"})
You can see the object URL in the returned value. Substitute /objects/ with /embed/ and you get a HTML file download. Remember to add port :4000 and replace https with http.
Now jump to Setting up test execution below.
Configuration Pitfall.
I navigated to http://localhost:4000 and got a frontend-lacking “Welcome to Akkoma” response.
Still not having any frontend configured, I chose to navigate to http://localhost:4000/admin … (I expected admin to be default user)
… and met with a great interactive stack trace page from Phoenix:
Cachex.Error at GET /admin
Exception:
** (Cachex.Error) missing terminating ] for character class at position 20
(elixir 1.19.5) lib/regex.ex:251: Regex.compile!/2
(pleroma 3.17.0-210-g4c632436-develop+dev) lib/pleroma/user.ex:1250: Pleroma.User.get_by_nickname/1
(pleroma 3.17.0-210-g4c632436-develop+dev) lib/pleroma/user.ex:1267: Pleroma.User.get_or_fetch_by_nickname/1
(pleroma 3.17.0-210-g4c632436-develop+dev) lib/pleroma/user.ex:1218: anonymous fn/2 in Pleroma.User.get_cached_by_nickname/1
…
I was shown the lib/pleroma/user.ex excerpt, and the regex is interpolated from Pleroma.Web.Endpoint.host() on that line. So I went into a REPL with iex -S mix phx.server:
[info] Access Pleroma.Web.Endpoint at https://localhost
Interactive Elixir (1.19.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Pleroma.Web.Endpoint.host()
"\e[?62;1;4clocalhost"
That’s an escape codes control sequence from the terminal. The \e[ part (^[[) is called Control Sequence Initiator (CSI).
As we can see in https://vt100.net/docs/vt220-rm/chapter4.html#S4.17, that’s a Primary Device Attributes response.
KDE Konsole can be found to report this exact string at
src/Vt102Emulation.cpp line 2653
void Vt102Emulation::reportTerminalType()
… sendString("\033[?62;1;4c"); // I'm a VT2xx with 132 columns and Sixel
We can also see it will not only report it just in the case
case token_csi_pn('c') : reportTerminalType ( ); break; //VT100
But also in case
case token_esc('Z') : reportTerminalType ( ); break;
Which maybe increases the chances this happens by accident somehow, when something either CSI c (^[[c) or ESC Z (^[[Z).
You can write the latter even by hand with Alt_L + Shift + Z.
If you run
cat > `mktemp | tee`
and then cat the file into the console, your shell will receive (CSI)62;1;4c and even Bash will just treat 62;1;4c as regular input.
If the program relies only on the echo of the console, and doesn’t do the thing to discard prior input, the control sequence may have ended up input and echoed (or not) way earlier, and still end up as input. I have not checked whether this is the case.
But ok, I look into my config/dev.secret.exs and see all “localhost” seem perfectly fine.
But now, knowing what is the issue, I know my `less` won’t show the sequence.
I check with cat -v and with LESS= less, as described above.
url: [host: "^[[?62;1;4clocalhost", scheme: "https", port: 443], name: "^[[?62;1;4clocalhost",
in LESS= less
config :pleroma, Pleroma.Web.Endpoint, url: [host: "ESC[?62;1;4clocalhost", scheme: "https", port: 443], ... config :pleroma, :instance, name: "ESC[?62;1;4clocalhost",
Another way to check is to
grep -UF $'\033' config/dev.secret.exs && echo "Unwanted escape sequences."
I edit it out in an editor (Helix amusingly has the cursor disappear on the escape character) and run Akkoma in REPL (for convenience) again:
iex -S mix phx.server
I also saw 62;1;4c in my shell input after I had a mix test fail from bad postgres user name.
The embed content-type bug
This time I see an error after Akkoma starts up,
[error] Cannot create service actor: https://localhost/internal/fetch/.
[nickname: {"has already been taken", [constraint: :unique, constraint_name: "users_nickname_index"]}]
But I still get the “Welcome to Akkoma!” alright. Now, /admin gives me “Welcome to Akkoma!” too, as it probably should without a frontend.
I still have to create a user and make a first post. I find https://docs.pleroma.social/Mix.Tasks.Pleroma.User.html
Too lazy to open another terminal, I chose to call the mix task through Mix.Task.
iex(1)> Mix.Task.run("pleroma.user", ["new", "shrimple", "shrimple@shrimple.pl", "--password", "hey"])
A user will be created with the following information:
- nickname: shrimple
- email: shrimple@shrimple.pl
- password: hey
- name: shrimple
- bio:
- moderator: false
- admin: false
Continue? [n] y
User shrimple created
nil
Through in part tabbing my way through the IEx REPL, I figured out I can do
iex(5)> me = Pleroma.User.get_by_nickname("shrimple")
and then
iex(8)> Pleroma.Web.CommonAPI.post(me, %{status: "yo", visibility: "public"})
And there, under Pleroma.Activity.data.object and under Pleroma.Activity.object→Pleroma.Object.data.id, I had a url:
"object" => "https://localhost/objects/a5490552-c715-4a43-8615-5fbc9a7081f7",
I went to http://localhost:4000/objects/a5490552-c715-4a43-8615-5fbc9a7081f7 and sure enough, I got shown the “Welcome to Akkoma!” due to a frontend route.
I went to http://localhost:4000/embed/B4FeRlONzM76KTU4u0 and a HTML file got downloaded (that’s a bug, it comes with Content-Type: application/octet-stream).
I renamed it to open it with Firefox (I could have just piped it to a simpler browser)
cd ~/Downloads ; mv B4FeRlONzM76KTU4u0 !#$.htm
and I sure saw a HTML file with the post saying “yo” and 0 replies, 0 announces [sic!], 0 likes.
I edit lib/pleroma/web/embed_controller.ex, put an additional |> put_resp_content_type("text/html") before the call to render/2 and immediately, without even needing to call recompile() in IEx, upon retry I receive a correct html page. I have no idea for now why the :accepts ["html"] that does the thing for all the rest in lib/pleroma/web/router.ex, doesn’t suffice for this one.
I think I will nonetheless post a Pull Request to Akkoma with such change, and a unit test, within a day or so.
Setting up test execution
As we would continue again with the guide I link on the very top, put the following in config/test.secret.exs.
import Config
config :pleroma, Pleroma.Repo,
username: "testoma",
password: "dupa.8",
database: "testoma",
hostname: "localhost"
Then run:
psql -c "CREATE USER testoma WITH PASSWORD 'dupa.8';" -d postgres -h /tmp sed s/akkoma/testoma/g config/setup_db.psql | grep -v USER > test_db.psql psql -f test_db.psql -d postgres -h /tmp psql -c "ALTER USER testoma WITH CREATEDB;" -d postgres -h /tmp mix test
Finished in 245.7 seconds (46.3s async, 199.3s sync)
4119 tests, 17 failures, 10 skipped (6 excluded)
You can also run a single test suite by adding a test filename to the command line. Or even a line number for single test or suite within.
My Pull Request is now live at https://akkoma.dev/AkkomaGang/akkoma/pulls/1084
I’ve just replied “:3c” in an Akkoma code review