LDEDQ57E4TRB3XN43A2FAOSWYKDTDF6J6ECBDTDERZ7GZJ2EATBQC `fly`-ing `huginn` close to the ground===konami are remaking MGS3. some people are trying to sell [electricekranoplans](https://www.regentcraft.com/seagliders/viceroy#specifications). andhere i am being a freeloader nerd for the 2nd decade. ingredients:- [huginn/huginn image](https://ghcr.io/huginn/huginn) (sponsor [co-author & maintainer knu](https://github.com/sponsors/knu))- [sentry DSN](https://sentry.io/pricing/) and/or [GlitchTip](https://glitchtip.com/pricing) ([donation page](https://liberapay.com/GlitchTip/donate))- [fly.io dashboard](https://fly.io/docs/about/pricing/)- [inoreader](https://jp.inoreader.com/pricing) and/or [feedly](https://feedly.com/i/pro) and/or [feedbin](https://feedbin.com/)i use its agent to crawl comic/blogs' syndication feeds, then reformat & augment them to read easily in [feedme](https://github.com/seazon/feedme). The comics update at most daily ([SMBC](https://www.smbc-comics.com/comic/archive) has been running since 2002), or thrice-weekly (Ryan North's [dinosaurs](https://qwantz.com/index.php?comic=1) have been talkin' since 2003 (lovingly crafted in [XP's MS Paint](https://www.qwantz.com/index.php?comic=4005)). and the blogs update less frequently than that. there's no need to keep huginn web-part running 24/7, and we can also reduce the scheduler wake-up frequency.Getting `flyctl` on MediaTek ramips mt7621---it's a softfloat Little-Endian MIPS cpu, we'll build `flyctl` like this:```shellscalar clone http://github.com/superfly/flyctlcd flyctl/srcgit sparse-checkout disableenv GOARCH=mipsle GOMIPS=softfloat make buildgzip bin/flyctl# deliver flyctl.gz to the mips```Making sentry crons and/or glitchtip uptime monitor---on sentry, SMBC will have a daily check-in schedule. Dinosaur Comics posts on Mon-Wed-Fri, accounting for TZ & scheduling delay, we'll have a Tue-Thu-Sat check-in regimen. both will allow some further ~2h slack time. the monitoring slugs are readable text now, not UUIDv4 anymore. but that's guessable. along with the project's `SENTRY_DSN` and quickstart for rails, we're good to go.on glitchtip, set up a 86399-second interval uptime heartbeat (they don't accept >=86400s). we'll use the URL later.Launch pad---we start simple with the `supervisord`-based image. that'd keep a 1GB fly machine running all the time.Fly people use docker images as a packaging format, they define theenvironment around that. here, we bake in postgresql and the sentrySDK gems. remember to [load `stackprof`first](https://docs.sentry.io/platforms/ruby/profiling/#enable-profiling):```bashmkdir hugcd hugecho -e '.dockerignore\nDockerfile\nfly.toml\nhug-db.toml\nsentry.rb' | tee .dockerignoretee Dockerfile <<-EODFROM ghcr.io/huginn/huginn:cbeb5c293ec3394dcd202b132b80e14398da8a11ENV ADDITIONAL_GEMS=stackprof,sentry-ruby,sentry-railsRUN APP_SECRET_TOKEN=nbd DATABASE_ADAPTER=postgresql bundle install -j 4# we tune this oftenCOPY sentry.rb /app/config/initializers/sentry.rbEODtee sentry.rb <<-EORSentry.init do |config|config.breadcrumbs_logger = [:active_support_logger, :http_logger]config.traces_sample_rate = 0.5config.profiles_sample_rate = 1.0endEOR```generate random for `APP_SECRET_TOKEN`:```shpodman run --rm -it --entrypoint sh ghcr.io/huginn/huginn:cbeb5c293ec3394dcd202b132b80e14398da8a11 rake secret```Build initial fly config, along with a managed postgres:```bashflyctl launch \--org personal \--name hug \--region fra \--push \--vm-cpukind shared \--vm-cpus 1 \--vm-memory 1024```for the postgres, you can use development, 256MB, auto scale to zero (default after 1h, but [you can be more aggressive/conservative](https://fly.io/docs/postgres/managing/scale-to-zero/#turn-off-the-scale-to-zero-feature)). let's write down its config file here too:```bashflyctl config save \--app hug-db \--config hug-db.toml```and it's a good idea to save the running postgres image for later use:```bashflyctl image show -a hug-db```load some more secrets into the app:```bashflyctl secrets import <<-EOSSENTRY_DSN=your_dsnAPP_SECRET_TOKEN=your_randomINVITATION_CODE=your_knock_passwordEOS```and put more app config```bashtee -a fly.toml <<-EOT[[statics]]guest_path = "/app/public"url_prefix = "/public"[env]RAILS_SERVE_STATIC_FILES="false"TIMEZONE="Hanoi"TZ="Asia/Phnom_Penh"DOMAIN="hug.fly.dev"FORCE_SSL="true"DATABASE_ADAPTER="postgresql"RACK_ENV="production"RAILS_LOG_TO_STDOUT="enabled"DO_NOT_SEED="true"IMPORT_DEFAULT_SCENARIO_FOR_ALL_USERS="true"AGENT_LOG_LENGTH="10" # used to fit heroku 10_000 rows limitSCHEDULER_FREQUENCY="5"DELAYED_JOB_SLEEP_DELAY="900" # sUSE_GRAPHVIZ_DOT="dot"DIAGRAM_DEFAULT_LAYOUT="neato"EOT```now you try to `flyctl launch` it, see the resulting 2.0GB image starts on fly regino `fra`if you get context deadline exceeded for build, try wesockets mode```bashflyctl wg websockets enable```to attach in for debugging```bashflyctl ssh console -s```in there, multi-process img has `pstree` to view supervisor's treeand tail the logs```bashflyctl logs```here, you can open the public URL, and create an account with the invitation code. there's no `admin` account because we didn't run SEED job. huginn will have created sample agents for you, explore them for idea
Mythical 0-link readable file---
{// "layer": "top", // Waybar at top layer// "position": "bottom", // Waybar position (top|bottom|left|right)// "height": 30, // Waybar height (to be removed for auto height)// "width": 1280, // Waybar width"spacing": 0, // Gaps between modules (4px)// Choose the order of the modules"modules-left": ["sway/workspaces", "sway/mode", "sway/scratchpad", "custom/media"],"modules-center": ["sway/window"],"modules-right": ["idle_inhibitor", "pulseaudio", "network", "cpu", "memory", "temperature", "battery", "battery#bat2", "tray","clock"],// Modules configuration// "sway/workspaces": {// "disable-scroll": true,// "all-outputs": true,// "format": "{name}: {icon}",// "format-icons": {// "1": "",// "2": "",// "3": "",// "4": "",// "5": "",// "urgent": "",// "focused": "",// "default": ""// }// },"keyboard-state": {"numlock": true,"capslock": true,"format": "{name} {icon}","format-icons": {"locked": "","unlocked": ""}},"sway/mode": {"format": "<span style=\"italic\">{}</span>"},"sway/scratchpad": {"format": "{icon} {count}","show-empty": false,"format-icons": ["", ""],"tooltip": true,"tooltip-format": "{app}: {title}"},"mpd": {"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ","format-disconnected": "Disconnected ","format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ","unknown-tag": "N/A","interval": 2,"consume-icons": {"on": " "},"random-icons": {"off": "<span color=\"#f53c3c\"></span> ","on": " "},"repeat-icons": {"on": " "},"single-icons": {"on": "1 "},"state-icons": {"paused": "","playing": ""},"tooltip-format": "MPD (connected)","tooltip-format-disconnected": "MPD (disconnected)"},"idle_inhibitor": {"format": "{icon}","format-icons": {"activated": "","deactivated": ""}},"tray": {// "icon-size": 21,"spacing": 0},"clock": {// "timezone": "America/New_York","tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>","format-alt": "{:%Y-%m-%d}"},"cpu": {"format": "{usage}% ","tooltip": false},"memory": {"format": "{}% "},"temperature": {// "thermal-zone": 2,// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input","critical-threshold": 80,// "format-critical": "{temperatureC}°C {icon}","format": "{temperatureC}°C {icon}","format-icons": ["", "", ""]},"backlight": {// "device": "acpi_video1","format": "{percent}% {icon}","format-icons": ["", "", "", "", "", "", "", "", ""]},"battery": {"states": {// "good": 95,"warning": 30,"critical": 15},"format": "{capacity}% {icon}","format-charging": "{capacity}% ","format-plugged": "{capacity}% ","format-alt": "{time} {icon}",// "format-good": "", // An empty format will hide the module// "format-full": "","format-icons": ["", "", "", "", ""]},"battery#bat2": {"bat": "BAT2"},"network": {"interface": "wl*", // (Optional) To force the use of this interface"format-wifi": "{essid} ({signalStrength}%) ","format-ethernet": "{ipaddr}/{cidr} ","tooltip-format": "{ifname} via {gwaddr} ","format-linked": "{ifname} (No IP) ","format-disconnected": "Disconnected ⚠","format-alt": "{ifname}: {ipaddr}/{cidr}"},"pulseaudio": {// "scroll-step": 1, // %, can be a float"format": "{volume}% {icon} {format_source}","format-bluetooth": "{volume}% {icon} {format_source}","format-bluetooth-muted": " {icon} {format_source}","format-muted": " {format_source}","format-source": "{volume}% ","format-source-muted": "","format-icons": {"headphone": "","hands-free": "","headset": "","phone": "","portable": "","car": "","default": ["", "", ""]},"on-click": "pavucontrol"},"custom/media": {"format": "{icon} {}","return-type": "json","max-length": 40,"format-icons": {"spotify": "","default": "🎜"},"escape": true,"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name}}
output 'Dell Inc. DELL P2422H BHFBMQ3' transform 270input "type:keyboard" {xkb_layout usxkb_variant dvorakxkb_options ctrl:nocaps}set $mod Mod4# Font for window titles. Will also be used by the bar unless a different font# is used in the bar {} block below.font pango:monospace 8exec --no-startup-id makoexec --no-startup-id ibus-daemon -drxexec --no-startup-id firefoxexec --no-startup-id emacsexec --no-startup-id flatpak run org.telegram.desktopexec --no-startup-id flatpak run com.skype.Clientexec --no-startup-id $TERMINALexec --no-startup-id org.keepassxc.KeePassXC# Use Mouse+$mod to drag floating windows to their wanted positionfloating_modifier $mod# start a terminalbindsym $mod+Return exec $TERMINAL# kill focused windowbindsym $mod+Shift+apostrophe kill# start dmenu (a program launcher)#bindsym $mod+d exec --no-startup-id dmenu_run -fn sansdefault_border pixel 1hide_edge_borders smartset $main LVDS-1# Virtual1set $side HDMI-A-1# Virtual2workspace 1 output $side $mainworkspace 2 output $mainworkspace 8 output $mainworkspace 4 output $main# assign [class="(?i)navigator"] 4assign [class="(?i)firefox"] 4assign [app_id="(?i)firefox"] 4workspace 3 output $mainassign [class="(?i)emacs"] 3assign [app_id="(?i)emacs"] 3workspace 6 output $side $mainassign [class="(?i)skype"] 7for_window [class="(?i)skype"] floating disableworkspace 7 output $mainassign [class="(?i)telegram"] 7assign [app_id="(?i)org.telegram.desktop"] 7workspace 9 output $side $mainassign [class="(?i)keepassxc"] 9assign [app_id="(?i)org.keepassxc.KeePassXC"] 9# change focusbindsym $mod+h focus leftbindsym $mod+t focus downbindsym $mod+c focus upbindsym $mod+n focus right# move focused window# bindsym $mod+Shift+h move left# bindsym $mod+Shift+t move down# bindsym $mod+Shift+c move up# bindsym $mod+Shift+n move right# enter fullscreen mode for the focused containerbindsym $mod+u fullscreen toggle# change container layout (stacked, tabbed, toggle split)bindsym $mod+o layout stackingbindsym $mod+comma layout tabbedbindsym $mod+period layout toggle split# toggle tiling / floating# bindsym $mod+Shift+space floating toggle# change focus between tiling / floating windows# bindsym $mod+space focus mode_toggle# focus the parent container#bindsym $mod+a focus parent# focus the child container#bindsym $mod+d focus child# Define names for default workspaces for which we configure key bindings later on.# We use variables to avoid repeating the names in multiple places.set $ws1 "1"set $ws2 "2"set $ws3 "3"set $ws4 "4"set $ws5 "5"set $ws6 "6"set $ws7 "7"set $ws8 "8"set $ws9 "9"set $ws10 "10"# switch to workspacebindsym $mod+1 workspace number $ws1bindsym $mod+2 workspace number $ws2bindsym $mod+3 workspace number $ws3bindsym $mod+4 workspace number $ws4bindsym $mod+5 workspace number $ws5bindsym $mod+6 workspace number $ws6bindsym $mod+7 workspace number $ws7bindsym $mod+8 workspace number $ws8bindsym $mod+9 workspace number $ws9bindsym $mod+0 workspace number $ws10# move focused container to workspacebindsym $mod+Shift+1 move container to workspace number $ws1bindsym $mod+Shift+2 move container to workspace number $ws2bindsym $mod+Shift+3 move container to workspace number $ws3bindsym $mod+Shift+4 move container to workspace number $ws4bindsym $mod+Shift+5 move container to workspace number $ws5bindsym $mod+Shift+6 move container to workspace number $ws6bindsym $mod+Shift+7 move container to workspace number $ws7bindsym $mod+Shift+8 move container to workspace number $ws8bindsym $mod+Shift+9 move container to workspace number $ws9bindsym $mod+Shift+0 move container to workspace number $ws10# reload the configuration filebindsym $mod+Shift+j reloadbindsym $mod+Shift+p restart# bindsym $mod+Shift+period exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"bar {# status_command i3status-rs}
SSH_AUTH_SOCK=/run/user/1000/keyring/sshEDITOR=emacsclientALTERNATE_EDITOR=""BAT_THEME=ansiKUBECTL_EXTERNAL_DIFF=difftXDG_DATA_DIRS=/home/hieuhg/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/sharePATH=/sbin/:/bin/:/home/hieuhg/run/:/home/hieuhg/.cargo/bin/:/home/hieuhg/.local/share/flatpak/exports/bin/BROWSER=firefoxTERMINAL=wezterm#TERMINAL=org.wezfurlong.wezterm#TERMINAL=terminatorGTK_IM_MODULE=ibusQT_IM_MODULE=ibusXMODIFIERS=@im=ibusPKG_CONFIG_PATH=/home/hieuhg/.local/lib/pkgconfigLD_LIBRARY_PATH=/home/hieuhg/.local/lib/