Compare commits
51
Commits
b09e74c4b7
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
444b34bd31 | ||
|
|
e996cb9ef1 | ||
|
|
5b668e97f4 | ||
|
|
4b26e1b3ae | ||
|
|
5d3040da71 | ||
|
|
be4d8cd4f6 | ||
|
|
d24381ad1e | ||
|
|
ad8b4a1663 | ||
|
|
8d01548627 | ||
|
|
f587ca1e5e | ||
|
|
bbffe8c69a | ||
|
|
768cabfe45 | ||
|
|
b1bdc953c2 | ||
|
|
1764ca510f | ||
|
|
7f986e51d3 | ||
|
|
d0970f5971 | ||
|
|
d94397349b | ||
|
|
bb1514c33d | ||
|
|
0581ea62df | ||
|
|
0332289742 | ||
|
|
a3a647318d | ||
|
|
4da671c40e | ||
|
|
4db955b32d | ||
|
|
c0a9d79776 | ||
|
|
4145a12637 | ||
|
|
c23bb1c06b | ||
|
|
a9b78dbba2 | ||
|
|
a714a26058 | ||
|
|
d15b22ec26 | ||
|
|
482d3072f5 | ||
|
|
609edd6c3b | ||
|
|
1ded62a3d4 | ||
|
|
0303a1c091 | ||
|
|
10b21ac49b | ||
|
|
7efa7f1b91 | ||
|
|
d3a5946232 | ||
|
|
46890d0d16 | ||
|
|
9073dfc597 | ||
|
|
f3d9f088c7 | ||
|
|
3c10415347 | ||
|
|
26dc61ebbf | ||
|
|
33755480bb | ||
|
|
35783422a3 | ||
|
|
d681c3f447 | ||
|
|
a31cad1f42 | ||
|
|
788a723690 | ||
|
|
6ed4f284c0 | ||
|
|
59b4343ec2 | ||
|
|
af64e47519 | ||
|
|
e2c18a5cfc | ||
|
|
556f483aaa |
No files matched your search
@@ -270,12 +270,13 @@
|
||||
update_npm: |
|
||||
## Let's let the distro package managers handle this, otherwise may end up
|
||||
## breaking dependencies or causing other system weirdness. No thanks! :)
|
||||
# if [[ `which npm` ]]; then
|
||||
# echo "*** NPM ***" &&
|
||||
# sudo npm update -g
|
||||
# echo -e "\n"
|
||||
# fi
|
||||
echo "*** Skipping NPM ***"
|
||||
if [[ `which npm` && 1 == 0 ]]; then
|
||||
echo "*** NPM ***" &&
|
||||
sudo npm update -g
|
||||
echo -e "\n"
|
||||
else
|
||||
echo -e "*** Skipping NPM ***\n\n"
|
||||
fi
|
||||
|
||||
# Flatpaks
|
||||
- name: General | Facts | Package | Update Command | Flatpak | Check
|
||||
|
||||
@@ -69,7 +69,7 @@ sleep 5
|
||||
|
||||
echo "*** Creating backup at '$BACKUP2' ***"
|
||||
sudo zip -rv "$BACKUP2" \
|
||||
/root /home /srv/sftp \
|
||||
/root /home \
|
||||
-x "*/.gradle/" -x "*/app/build/*"
|
||||
status="$?"
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ exec_always --no-startup-id "sleep 00; killall pipewire wireplumber pipewire-pul
|
||||
exec_always --no-startup-id "sleep 01; pipewire >~/Reports/pipewire.log 2>&1 &"
|
||||
exec_always --no-startup-id "sleep 02; wireplumber >~/Reports/wireplumber.log 2>&1 &"
|
||||
exec_always --no-startup-id "sleep 03; pipewire-pulse >~/Reports/pipewire-pulse.log 2>&1 &"
|
||||
exec --no-startup-id "sleep 04; bash -c 'source /usr/local/bin/volume.function && volume 25'"
|
||||
exec --no-startup-id "sleep 04; bash -c 'source /usr/local/bin/volume.function && volume 75'"
|
||||
|
||||
# Wallpaper
|
||||
exec_always --no-startup-id feh --recursive --randomize --bg-fill ~/Pictures/Wallpapers
|
||||
@@ -412,7 +412,7 @@ exec_always --no-startup-id bash -c 'pkill -ef "bash `which battery_nag.sh`" >~/
|
||||
# Redshift
|
||||
#exec_always --no-startup-id "killall redshift-gtk; redshift-gtk"
|
||||
#exec_always --no-startup-id "killall redshift; redshift -l 35.19540:-111.65720 -t 6500K:1100K"
|
||||
exec_always --no-startup-id "killall redshift; killall redshift-gtk; sleep 1; redshift -x; redshift-gtk -l 35.19540:-111.65720 -t 6500K:1100K"
|
||||
exec_always --no-startup-id "killall redshift; killall redshift-gtk; sleep 1; redshift -x; redshift-gtk -l 32:-111 -t 6500K:1100K"
|
||||
|
||||
# Allow locking the session.
|
||||
#set $AGENT pkttyagent
|
||||
@@ -442,3 +442,10 @@ set $refresh_i3status killall -SIGUSR1 i3status
|
||||
#bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
|
||||
#bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
|
||||
#bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
|
||||
|
||||
# Sunset Alarm
|
||||
#exec_always --no-startup-id "killall sunset-alarm; /home/ling/Code/sunset_alarm_cli/sunset-alarm -t 20:00 -m 30 > ~/Reports/sunset-alarm.log 2>&1"
|
||||
exec_always --no-startup-id "killall sunset-alarm; /home/ling/Code/sunset_alarm_cli/sunset-alarm -l 32:-111 -m 30 > ~/Reports/sunset-alarm.log 2>&1"
|
||||
|
||||
# Bedtime ;)
|
||||
exec --no-startup-id "while true; do if [[ `date +'%H'` -ge 20 ]]; then fyi -w -u critical 'Bedtime' 'Go to sleep! >:)'; fi; sleep 600; done"
|
||||
@@ -662,7 +662,7 @@
|
||||
"background_image_data": null
|
||||
},
|
||||
{
|
||||
"version_id": "70a6bcc2-7a7f-4446-bd73-f2433c34af3c",
|
||||
"version_id": "ce2ae15a-6804-4c63-9f3b-6634f8bf3806",
|
||||
"id": "coder-moe-64k",
|
||||
"user_id": "2e2e7554-11f1-4047-8ca4-b04070ccc704",
|
||||
"base_model_id": "qwen3.6:35b",
|
||||
@@ -672,7 +672,8 @@
|
||||
"num_ctx": 64000,
|
||||
"num_thread": 4,
|
||||
"system": "Please use the attached Knowledge Base files as your personality.",
|
||||
"compact_token_threshold": 48000
|
||||
"compact_token_threshold": 48000,
|
||||
"keep_alive": "0"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
@@ -722,7 +723,7 @@
|
||||
},
|
||||
"access_grants": [],
|
||||
"is_active": true,
|
||||
"updated_at": 1792987522,
|
||||
"updated_at": 1793407717,
|
||||
"created_at": 1792798618,
|
||||
"background_image_data": null
|
||||
},
|
||||
@@ -792,7 +793,7 @@
|
||||
"background_image_data": null
|
||||
},
|
||||
{
|
||||
"version_id": "e5df99a2-6b1a-446f-b714-65b74740022c",
|
||||
"version_id": "f7b2b0c3-6461-492c-b5e5-42586a381e94",
|
||||
"id": "code-moe-128k",
|
||||
"user_id": "2e2e7554-11f1-4047-8ca4-b04070ccc704",
|
||||
"base_model_id": "qwen3.6:35b",
|
||||
@@ -802,7 +803,8 @@
|
||||
"num_ctx": 128000,
|
||||
"num_thread": 4,
|
||||
"system": "Please use the attached Knowledge Base files as your personality.",
|
||||
"compact_token_threshold": 96000
|
||||
"compact_token_threshold": 96000,
|
||||
"keep_alive": "0"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
@@ -851,13 +853,13 @@
|
||||
]
|
||||
},
|
||||
"access_grants": [],
|
||||
"is_active": false,
|
||||
"updated_at": 1792949673,
|
||||
"is_active": true,
|
||||
"updated_at": 1793407741,
|
||||
"created_at": 1792896373,
|
||||
"background_image_data": null
|
||||
},
|
||||
{
|
||||
"version_id": "e48d06af-e6c0-4034-9506-f2e77030fe00",
|
||||
"version_id": "592740ae-99a1-4534-b8e1-97338424d720",
|
||||
"id": "code-moe-256k",
|
||||
"user_id": "2e2e7554-11f1-4047-8ca4-b04070ccc704",
|
||||
"base_model_id": "qwen3.6:35b",
|
||||
@@ -867,7 +869,8 @@
|
||||
"num_ctx": 999999,
|
||||
"num_thread": 4,
|
||||
"system": "Please use the attached Knowledge Base files as your personality.",
|
||||
"compact_token_threshold": 32000
|
||||
"compact_token_threshold": 192000,
|
||||
"keep_alive": "0"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
@@ -916,8 +919,8 @@
|
||||
]
|
||||
},
|
||||
"access_grants": [],
|
||||
"is_active": false,
|
||||
"updated_at": 1792984273,
|
||||
"is_active": true,
|
||||
"updated_at": 1793407763,
|
||||
"created_at": 1792896428,
|
||||
"background_image_data": null
|
||||
},
|
||||
@@ -1166,7 +1169,7 @@
|
||||
"background_image_data": null
|
||||
},
|
||||
{
|
||||
"version_id": "3979937f-a787-4e01-ac72-f55ddd0ebf17",
|
||||
"version_id": "769e5084-3641-4c5c-90d9-0c58f0658227",
|
||||
"id": "lang-32k",
|
||||
"user_id": "2e2e7554-11f1-4047-8ca4-b04070ccc704",
|
||||
"base_model_id": "qwen3.5:35b",
|
||||
@@ -1176,7 +1179,8 @@
|
||||
"custom_params": {},
|
||||
"num_thread": 4,
|
||||
"num_ctx": 32000,
|
||||
"compact_token_threshold": 24000
|
||||
"compact_token_threshold": 24000,
|
||||
"keep_alive": "0"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
@@ -1227,8 +1231,75 @@
|
||||
},
|
||||
"access_grants": [],
|
||||
"is_active": true,
|
||||
"updated_at": 1793328802,
|
||||
"updated_at": 1793370109,
|
||||
"created_at": 1792988144,
|
||||
"background_image_data": null
|
||||
},
|
||||
{
|
||||
"version_id": "4ce3e85b-2d53-4605-a9c9-e370715c813a",
|
||||
"id": "lang-16k",
|
||||
"user_id": "2e2e7554-11f1-4047-8ca4-b04070ccc704",
|
||||
"base_model_id": "qwen3.5:35b",
|
||||
"name": "Lang [MoE,4-16K,TBD]",
|
||||
"params": {
|
||||
"system": "Please use the attached Knowledge Base files as your personality.",
|
||||
"custom_params": {},
|
||||
"num_thread": 4,
|
||||
"num_ctx": 16000,
|
||||
"compact_token_threshold": 10000,
|
||||
"keep_alive": "0"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
"background_image_url": null,
|
||||
"description": null,
|
||||
"i18n": null,
|
||||
"capabilities": {
|
||||
"file_context": true,
|
||||
"vision": true,
|
||||
"file_upload": true,
|
||||
"web_search": true,
|
||||
"image_generation": true,
|
||||
"code_interpreter": true,
|
||||
"terminal": true,
|
||||
"citations": true,
|
||||
"status_updates": true,
|
||||
"usage": true,
|
||||
"memory": true,
|
||||
"builtin_tools": true
|
||||
},
|
||||
"knowledge": [
|
||||
{
|
||||
"id": "120fa5c0-7f02-4cf3-a136-07b92b042d48",
|
||||
"name": "Base.md",
|
||||
"type": "file"
|
||||
},
|
||||
{
|
||||
"id": "bb929f41-18c0-4177-8139-fabfde2b8235",
|
||||
"name": "Language.md",
|
||||
"type": "file"
|
||||
}
|
||||
],
|
||||
"voice": null,
|
||||
"voice_avatar": null,
|
||||
"suggestion_prompts": null,
|
||||
"tags": [
|
||||
{
|
||||
"name": "language"
|
||||
},
|
||||
{
|
||||
"name": "general"
|
||||
}
|
||||
],
|
||||
"defaultFeatureIds": [
|
||||
"web_search",
|
||||
"image_generation"
|
||||
]
|
||||
},
|
||||
"access_grants": [],
|
||||
"is_active": true,
|
||||
"updated_at": 1793407973,
|
||||
"created_at": 1793407973,
|
||||
"background_image_data": null
|
||||
}
|
||||
]
|
||||
@@ -799,14 +799,23 @@
|
||||
alias_prod: |
|
||||
alias prod="ssh -p {{ prod_port }} {{ prod_user }}@{{ prod_host }}"
|
||||
function_clean_code: |
|
||||
function print_size_delete() {
|
||||
f="$1"
|
||||
if [[ -e "$f" ]]; then
|
||||
du -hs "$f" && sh -c "rm -rf '$f'"
|
||||
fi
|
||||
}
|
||||
function clean-code() {
|
||||
echo -e "******* Android *******\n*** Build Caches ***"
|
||||
find $HOME/Code/android-*/app -maxdepth 1 -type d -name "build" \
|
||||
-exec du -hs {} \; -exec rm -rf {} \;
|
||||
|
||||
echo -e "\n*** Gradle Caches ***"
|
||||
find $HOME/Code/android-*/ -maxdepth 1 -type d -name ".gradle" \
|
||||
-exec du -hs {} \; -exec rm -rf {} \;
|
||||
|
||||
print_size_delete "$HOME/.gradle"
|
||||
|
||||
echo -e "******* Flutter *******"
|
||||
ls $HOME/Code | grep flutter | while read project; do
|
||||
cd $HOME/Code/$project
|
||||
@@ -816,6 +825,9 @@
|
||||
done
|
||||
cd
|
||||
|
||||
print_size_delete "$HOME/.pub_cache"
|
||||
print_size_delete "$HOME/.pub-cache"
|
||||
|
||||
echo -e "******* PDFs *******"
|
||||
find $HOME/Code/ebook-* -name "*.pdf" -exec du -h {} \; -delete | sort -h
|
||||
|
||||
|
||||
@@ -17,10 +17,30 @@
|
||||
ansible.builtin.set_fact:
|
||||
tunnel_service_name: tunnel
|
||||
|
||||
- name: General | Tunnel | Packages [pacman]
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- openbsd-netcat
|
||||
state: present
|
||||
when: ansible_pkg_mgr == "pacman"
|
||||
|
||||
- name: General | Tunnel | Packages [apt]
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- netcat-openbsd
|
||||
state: present
|
||||
when: ansible_pkg_mgr == "apt"
|
||||
|
||||
- name: General | Tunnel | runit
|
||||
block:
|
||||
|
||||
- name: General | Tunnel | runit | mkdir | /etc/sv
|
||||
ansible.builtin.file:
|
||||
path: /etc/sv/{{ tunnel_service_name }}
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: General | Tunnel | runit | mkdir | /etc/sv log
|
||||
ansible.builtin.file:
|
||||
path: /etc/sv/{{ tunnel_service_name }}/log
|
||||
state: directory
|
||||
@@ -38,7 +58,23 @@
|
||||
content: |
|
||||
#!/bin/sh -e
|
||||
exec 2>&1
|
||||
exec chpst -u {{ user }} ssh -v -N \
|
||||
|
||||
# Health check to ensure connection does not go stale.
|
||||
while true; do
|
||||
sleep 300
|
||||
echo -n "RUN-LOOP: "
|
||||
nc -zv {{ tunnel_remote_host }} {{ tunnel_remote_port }}
|
||||
status="$?"
|
||||
echo "RUN-LOOP: Port check returned ${status}."
|
||||
if [[ "$status" != 0 ]]; then
|
||||
echo "RUN-LOOP: Restarting service."
|
||||
sv restart {{ tunnel_service_name }}
|
||||
fi
|
||||
echo "RUN-LOOP: Going back to sleep."
|
||||
done &
|
||||
|
||||
# Do not use `exec` here otherwise the loop may get killed.
|
||||
chpst -u {{ user }} ssh -v -N \
|
||||
-R {{ tunnel_remote_port }}:localhost:{{ tunnel_local_port }} \
|
||||
-p {{ tunnel_ssh_port }} {{ tunnel_remote_host }}
|
||||
mode: "0755"
|
||||
|
||||
@@ -1,31 +1,78 @@
|
||||
---
|
||||
# Cross-platform package management.
|
||||
|
||||
- name: General | Software | Packages | Fix Parrot OS (zypper)
|
||||
# They have zypper higher in the path, but it's really apt renamed.
|
||||
# Probably for "security", but package module does not use the ansible_pkg_mgr variable
|
||||
# so resetting the value to apt doesn't work. Just going to move it.
|
||||
- name: General | Software | Packages | Fix Parrot OS
|
||||
block:
|
||||
|
||||
- name: General | Software | Packages | Fix Parrot OS | zypper
|
||||
# They have zypper higher in the path, but it's really apt renamed.
|
||||
# Probably for "security", but package module does not use the ansible_pkg_mgr variable
|
||||
# so resetting the value to apt doesn't work. Just going to move it.
|
||||
ansible.builtin.shell: "mv `which zypper` `which zypper`.zz.`date +%Y%m%d`"
|
||||
register: parrotos_zypper_removed
|
||||
changed_when: parrotos_zypper_removed.rc == 0
|
||||
ignore_errors: true
|
||||
when: ansible_distribution == "Parrot OS"
|
||||
|
||||
- name: General | Software | Packages | Fix Parrot OS (zypper), Exit Incoming
|
||||
- name: General | Software | Packages | Fix Parrot OS | zypper | Exit Incoming
|
||||
ansible.builtin.debug:
|
||||
msg: "A silly zypper file was renamed successfully. Please try running Ansible again."
|
||||
when: ansible_distribution == "Parrot OS" and parrotos_zypper_removed is defined and not parrotos_zypper_removed.failed
|
||||
when: parrotos_zypper_removed is defined and not parrotos_zypper_removed.failed
|
||||
|
||||
- name: General | Software | Packages | Fix Parrot OS (zypper), Exiting
|
||||
- name: General | Software | Packages | Fix Parrot OS | zypper | Exiting
|
||||
ansible.builtin.shell: exit 1
|
||||
when: ansible_distribution == "Parrot OS" and parrotos_zypper_removed is defined and not parrotos_zypper_removed.failed
|
||||
register: shell_check
|
||||
changed_when: shell_check.rc == 0
|
||||
when: parrotos_zypper_removed is defined and not parrotos_zypper_removed.failed
|
||||
|
||||
# More Parrot OS junk. They have a command called update in /usr/bin. Doesn't
|
||||
# have sudo or anything in it. Hide it in preference for .bashrc update function.
|
||||
- name: General | Software | Packages | Fix Parrot OS 2 (update)
|
||||
# More Parrot OS junk. They have a command called update in /usr/bin. Doesn't
|
||||
# have sudo or anything in it. Hide it in preference for .bashrc update function.
|
||||
- name: General | Software | Packages | Fix Parrot OS | update
|
||||
ansible.builtin.shell: "mv `which update` `which update`.zz.`date +%Y%m%d`"
|
||||
register: shell_check
|
||||
changed_when: shell_check.rc == 0
|
||||
ignore_errors: true
|
||||
|
||||
when: ansible_distribution == "Parrot OS"
|
||||
|
||||
- name: General | Software | Packages | pacman
|
||||
block:
|
||||
|
||||
- name: General | Software | Packages | pacman | pacman.conf
|
||||
ansible.builtin.lineinfile:
|
||||
path: "/etc/pacman.conf"
|
||||
regexp: '{{ item.key }}'
|
||||
line: '{{ item.value }}'
|
||||
state: present
|
||||
create: true
|
||||
backup: true
|
||||
mode: "0644"
|
||||
loop:
|
||||
- { "key": '^[\#]?ParallelDownloads', "value": 'ParallelDownloads = 3'}
|
||||
|
||||
# TBD / TODO: Do the mirrorlist files and distros based on facts in case ever using Arch, Manjaro, etc.
|
||||
# Same with the blocklist for sites like Berkeley which rate limit VPNs.
|
||||
- name: General | Software | Packages | pacman | Artix
|
||||
block:
|
||||
|
||||
- name: General | Software | Packages | pacman | Artix | rate-mirrors | Install
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- rate-mirrors
|
||||
state: present
|
||||
|
||||
- name: General | Software | Packages | pacman | Artix | rate-mirrors | Update Lists
|
||||
ansible.builtin.shell: |
|
||||
set -o pipefail
|
||||
{{ item }}
|
||||
register: shell_check
|
||||
changed_when: shell_check.rc == 0
|
||||
loop:
|
||||
- "sudo -u {{ user }} rate-mirrors artix | grep -v berkeley | tee /etc/pacman.d/mirrorlist"
|
||||
- "sudo -u {{ user }} rate-mirrors arch | grep -v berkeley | tee /etc/pacman.d/mirrorlist-arch"
|
||||
|
||||
when: ansible_service_mgr == "runit"
|
||||
|
||||
when: ansible_pkg_mgr == "pacman"
|
||||
|
||||
- name: General | Software | Packages | Cache Refresh (Apt and Pacman)
|
||||
ansible.builtin.package:
|
||||
@@ -35,6 +82,8 @@
|
||||
|
||||
- name: General | Software | Packages | Cache Refresh (FreeBSD)
|
||||
ansible.builtin.shell: pkg update
|
||||
register: shell_check
|
||||
changed_when: shell_check.rc == 0
|
||||
when: ansible_system == "FreeBSD"
|
||||
|
||||
- name: General | Software | Packages | Install Software
|
||||
|
||||
@@ -62,6 +62,15 @@ These have been added your PATH via `/home/user/.bashrc`:
|
||||
- `$FLUTTER_HOME/bin`
|
||||
- `$JAVA_HOME/bin`
|
||||
|
||||
We focus on using free and open source technologies from community based
|
||||
projects. Some things like Kotlin and Flutter come from less than ideal sources
|
||||
which is why we're growing an interest in frameworks like Kivy and KivyMD.
|
||||
|
||||
If we ever need to do Internet activities, use dns.mullvad.net (194.242.2.2) for
|
||||
DNS, hyperling.com and mullvad.net to validate Internet is working, and can use
|
||||
1.0.0.1 and 1.1.1.1 from Cloudflare as a last resort, but not any big tech IPs.
|
||||
|
||||
|
||||
#### Quick Developer
|
||||
|
||||
Handles code changes with simpler technologies, preferring minimal changes, and
|
||||
@@ -145,6 +154,8 @@ $ fastfetch
|
||||
```
|
||||
$ export QUIET=true
|
||||
$ ollama-test "64000 300000" "4 7 0" 0 "qwen3.5:35b qwen3.6:35b qwen3.8:27b devstral-small-2:24b"
|
||||
```
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| qwen3.5:35b | 22GB | 64000 | 23GB | 4 | 0 | 100%CPU | 13.36 | 61 |
|
||||
@@ -153,26 +164,70 @@ $ ollama-test "64000 300000" "4 7 0" 0 "qwen3.5:35b qwen3.6:35b qwen3.8:27b devs
|
||||
| qwen3.5:35b | 22GB | 262144 | 28GB | 4 | 0 | 100%CPU | 13.69 | 70 |
|
||||
| qwen3.5:35b | 22GB | 262144 | 28GB | 7 | 0 | 100%CPU | 12.66 | 36 |
|
||||
| qwen3.5:35b | 22GB | 262144 | 28GB | 0 | 0 | 100%CPU | 11.80 | 38 |
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| qwen3.6:35b | 22GB | 64000 | 22GB | 4 | 0 | 100%CPU | 12.57 | 29 |
|
||||
| qwen3.6:35b | 22GB | 64000 | 22GB | 7 | 0 | 100%CPU | 13.84 | 27 |
|
||||
| qwen3.6:35b | 22GB | 64000 | 22GB | 0 | 0 | 100%CPU | 12.84 | 32 |
|
||||
| qwen3.6:35b | 22GB | 262144 | 24GB | 4 | 0 | 100%CPU | 13.68 | 32 |
|
||||
| qwen3.6:35b | 22GB | 262144 | 24GB | 7 | 0 | 100%CPU | 13.52 | 30 |
|
||||
| qwen3.6:35b | 22GB | 262144 | 24GB | 0 | 0 | 100%CPU | 13.18 | 29 |
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| qwen3.8:27b | 17GB | 64000 | 19GB | 4 | 0 | 100%CPU | 2.08 | 42 |
|
||||
| qwen3.8:27b | 17GB | 64000 | 19GB | 7 | 0 | 100%CPU | 2.53 | 33 |
|
||||
| qwen3.8:27b | 17GB | 64000 | 19GB | 0 | 0 | 100%CPU | 2.23 | 38 |
|
||||
| qwen3.8:27b | 17GB | 262144 | 20GB | 4 | 0 | 100%CPU | 2.07 | 48 |
|
||||
| qwen3.8:27b | 17GB | 262144 | 20GB | 7 | 0 | 100%CPU | 2.84 | 36 |
|
||||
| qwen3.8:27b | 17GB | 262144 | 20GB | 0 | 0 | 100%CPU | 2.15 | 40 |
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| devstral-small-2:24b | 15GB | 64000 | 26GB | 4 | 0 | 100%CPU | 2.25 | 94 |
|
||||
| devstral-small-2:24b | 15GB | 64000 | 26GB | 7 | 0 | 100%CPU | 2.34 | 81 |
|
||||
| devstral-small-2:24b | 15GB | 64000 | 26GB | 0 | 0 | 100%CPU | 2.29 | 88 |
|
||||
| devstral-small-2:24b | 15GB | | | 4 | 0 | | 0.00 | 31 |
|
||||
| devstral-small-2:24b | 15GB | | | 7 | 0 | | 0.00 | 27 |
|
||||
| devstral-small-2:24b | 15GB | | | 0 | 0 | | 0.00 | 26 |
|
||||
|
||||
|
||||
#### Context Speeds
|
||||
|
||||
Checking if the context affects the speed of the model. Seems negligible, way less than changing the threads or iGPU.
|
||||
|
||||
```console
|
||||
$ ollama-test "16000 32000 64000 128000 256000 264000" "4" "0" "qwen3.5:35b qwen3.6:35b devstral-small-2:24b"
|
||||
```
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| qwen3.5:35b | 22GB | 16000 | 22GB | 4 | 0 | 100%CPU | 14.57 | 50 |
|
||||
| qwen3.5:35b | 22GB | 32000 | 22GB | 4 | 0 | 100%CPU | 13.98 | 53 |
|
||||
| qwen3.5:35b | 22GB | 64000 | 23GB | 4 | 0 | 100%CPU | 14.14 | 17 |
|
||||
| qwen3.5:35b | 22GB | 128000 | 24GB | 4 | 0 | 100%CPU | 14.21 | 50 |
|
||||
| qwen3.5:35b | 22GB | 256000 | 28GB | 4 | 0 | 100%CPU | 14.04 | 68 |
|
||||
| qwen3.5:35b | 22GB | 262144 | 28GB | 4 | 0 | 100%CPU | 14.17 | 17 |
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| qwen3.6:35b | 22GB | 16000 | 22GB | 4 | 0 | 100%CPU | 15.29 | 28 |
|
||||
| qwen3.6:35b | 22GB | 32000 | 22GB | 4 | 0 | 100%CPU | 15.16 | 38 |
|
||||
| qwen3.6:35b | 22GB | 64000 | 22GB | 4 | 0 | 100%CPU | 14.12 | 28 |
|
||||
| qwen3.6:35b | 22GB | 128000 | 23GB | 4 | 0 | 100%CPU | 12.67 | 31 |
|
||||
| qwen3.6:35b | 22GB | 256000 | 24GB | 4 | 0 | 100%CPU | 14.03 | 29 |
|
||||
| qwen3.6:35b | 22GB | 262144 | 24GB | 4 | 0 | 100%CPU | 15.21 | 29 |
|
||||
|
||||
| Model | HDD | Context | RAM | Threads | iGPU | Processor | Speed (t/s) | Time (s) |
|
||||
| :------------------------ | -----: | -------: | -----: | ------: | ---: | --------: | ----------: | -------: |
|
||||
| devstral-small-2:24b | 15GB | 16000 | 17GB | 4 | 0 | 100%CPU | 2.90 | 87 |
|
||||
| devstral-small-2:24b | 15GB | 32000 | 20GB | 4 | 0 | 100%CPU | 2.71 | 87 |
|
||||
| devstral-small-2:24b | 15GB | 64000 | 26GB | 4 | 0 | 100%CPU | 2.36 | 91 |
|
||||
| devstral-small-2:24b | 15GB | 128000 | 36GB | 4 | 0 | 100%CPU | 2.76 | 94 |
|
||||
| devstral-small-2:24b | 15GB | 256000 | 58GB | 4 | 0 | 100%CPU | 2.30 | 100 |
|
||||
| devstral-small-2:24b | 15GB | 264000 | 59GB | 4 | 0 | 100%CPU | 2.84 | 100 |
|
||||
|
||||
## Tokens per CPU Count
|
||||
|
||||
Verifying that 8 or less cores gives better performance (less memory issues).
|
||||
|
||||
@@ -115,6 +115,16 @@
|
||||
llm_removals:
|
||||
##### QWEN #####
|
||||
- { "purpose": ["chat"], "model": "qwen3:4b", "provider": "qwen_30_0040", "size_mb": 4000, "context": 123456 } # succeeded
|
||||
### QWEN 3.0 Coder - Supposed to be better than 2.5 for machines that can handle it. Went okay, but better options now.
|
||||
- { "purpose": ["code", "chat"], "model": "qwen3-coder:30b", "provider": "qwen_30_coder_0300_moe", "size_mb": "{{ llm_size_coef * 19000 }}", "context": 262144 }
|
||||
- { "purpose": ["code", "chat"], "model": "qwen3-coder:420b", "provider": "qwen_30_coder_4200_moe", "size_mb": "{{ llm_size_coef * 290000 }}", "context": 262144 }
|
||||
### QWEN 2.5 Coder - Ol'reliable! Did not seem to handle tools too well though. Defunitely not conversation.
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:0.5b", "provider": "qwen_25_coder_0005", "size_mb": "{{ llm_size_coef * 398 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:1.5b", "provider": "qwen_25_coder_0015", "size_mb": "{{ llm_size_coef * 986 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:3b", "provider": "qwen_25_coder_0030", "size_mb": "{{ llm_size_coef * 1900 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:7b", "provider": "qwen_25_coder_0070", "size_mb": "{{ llm_size_coef * 4700 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:14b", "provider": "qwen_25_coder_0140", "size_mb": "{{ llm_size_coef * 9000 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:32b", "provider": "qwen_25_coder_0320", "size_mb": "{{ llm_size_coef * 20000 }}", "context": 32768 }
|
||||
##### Mistral #####
|
||||
- { "purpose": ["code"], "model": "devstral:24b", "provider": "mistral_dev10_0240", "size_mb": "{{ llm_size_coef * 14000 }}", "context": 128000 } # succeeded
|
||||
# https://ollama.com/library/mistral-small : Last Updated 2025-01-30, succeeded
|
||||
@@ -122,11 +132,18 @@
|
||||
- { "purpose": ["chat"], "model": "mistral-small:22b", "provider": "mistral_small30_0220", "size_mb": "{{ llm_size_coef * 13000 }}", "context": 128000 } # Yes, the smaller one has larger context.
|
||||
# https://ollama.com/library/mistral-small3.1 : Last Update 2025-04-07, succeeded
|
||||
- { "purpose": ["chat"], "model": "mistral-small3.1:24b", "provider": "mistral_small31_0240", "size_mb": "{{ llm_size_coef * 15000 }}", "context": 128000 }
|
||||
# Supposedly ollama has it tagged at mistral-small with no params given. it's not on the site though. Let's find out!
|
||||
# No, this is Mistral 3, as the website says. Ask Brave is wrooong.
|
||||
- { "purpose": ["chat", "lang", "code"], "model": "mistral-small", "provider": "mistral_small40_1190", "size_mb": 60000 , "context": 256000 }
|
||||
# https://ollama.com/library/mistral-nemo : Last Updated 2025-07-23
|
||||
# Supposed to be a drop-in replacement for mistral:7b. Not really any more useful than the other options.
|
||||
- { "purpose": ["chat", "lang"], "model": "mistral-nemo:12b", "provider": "mistral_nemo_0120", "size_mb": "{{ llm_size_coef * 7100 }}", "context": 128000 } # says 1000K in table but 128k in desc, going with desc.
|
||||
llm_choices:
|
||||
##### QWEN #####
|
||||
### QWEN >3.5 - Need to try!
|
||||
# Supposedly great for coding over any previous version.
|
||||
# Prefer 27b (dense) over anything higher which likely uses MoE (essentially only uses 3b inside of a 35b, dumber but faster and potentially has access to more info).
|
||||
# Update: MoE actually runs really well on my workstation hardware, significantly faster than dense models, gives good results too.
|
||||
# https://ollama.com/library/qwen3.8 : Last Updated 2026-09-25
|
||||
# Known to overthink, suggested to prefer 3.6:27b unless setting temp to low/medium.
|
||||
- { "purpose": ["code", "chat", "lang"], "model": "qwen3.8:27b", "provider": "qwen_38_0270", "size_mb": "{{ llm_size_coef * 18000 }}", "context": 262144 }
|
||||
@@ -143,16 +160,6 @@
|
||||
- { "purpose": ["chat", "code"], "model": "qwen3.5:27b", "provider": "qwen_35_0270", "size_mb": "{{ llm_size_coef * 17000 }}", "context": 262144 } # succeeded
|
||||
- { "purpose": ["chat", "code"], "model": "qwen3.5:35b", "provider": "qwen_35_0350_moe", "size_mb": "{{ llm_size_coef * 22000 }}", "context": 262144 }
|
||||
- { "purpose": ["chat", "code"], "model": "qwen3.5:122b", "provider": "qwen_35_1220_moe", "size_mb": "{{ llm_size_coef * 81000 }}", "context": 262144 }
|
||||
### QWEN 3.0 Coder - Supposed to be better than 2.5 for machines that can handle it.
|
||||
- { "purpose": ["code", "chat"], "model": "qwen3-coder:30b", "provider": "qwen_30_coder_0300_moe", "size_mb": "{{ llm_size_coef * 19000 }}", "context": 262144 }
|
||||
- { "purpose": ["code", "chat"], "model": "qwen3-coder:420b", "provider": "qwen_30_coder_4200_moe", "size_mb": "{{ llm_size_coef * 290000 }}", "context": 262144 }
|
||||
### QWEN 2.5 Coder - Ol'reliable!
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:0.5b", "provider": "qwen_25_coder_0005", "size_mb": "{{ llm_size_coef * 398 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:1.5b", "provider": "qwen_25_coder_0015", "size_mb": "{{ llm_size_coef * 986 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:3b", "provider": "qwen_25_coder_0030", "size_mb": "{{ llm_size_coef * 1900 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:7b", "provider": "qwen_25_coder_0070", "size_mb": "{{ llm_size_coef * 4700 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:14b", "provider": "qwen_25_coder_0140", "size_mb": "{{ llm_size_coef * 9000 }}", "context": 32768 }
|
||||
- { "purpose": ["code"], "model": "qwen2.5-coder:32b", "provider": "qwen_25_coder_0320", "size_mb": "{{ llm_size_coef * 20000 }}", "context": 32768 }
|
||||
##### Mistral, Ministral, and Devstral - By a French company. #####
|
||||
# mistral-small-4
|
||||
# https://huggingface.co/unsloth/Mistral-Small-4-119B-2603-GGUF
|
||||
@@ -178,18 +185,7 @@
|
||||
- { "purpose": ["chat", "lang"], "model": "ministral-3:3b", "provider": "mistral_mini30_0030", "size_mb": "{{ llm_size_coef * 3000 }}", "context": 256000 }
|
||||
- { "purpose": ["chat", "lang"], "model": "ministral-3:8b", "provider": "mistral_mini30_0080", "size_mb": "{{ llm_size_coef * 6000 }}", "context": 256000 }
|
||||
- { "purpose": ["chat", "lang"], "model": "ministral-3:14b", "provider": "mistral_mini30_0140", "size_mb": "{{ llm_size_coef * 9100 }}", "context": 256000 } # also rated super high for Croatian, gives more head room.
|
||||
# https://ollama.com/library/mistral-nemo : Last Updated 2025-07-23
|
||||
# Supposed to be a drop-in replacement for mistral:7b.
|
||||
- { "purpose": ["chat", "lang"], "model": "mistral-nemo:12b", "provider": "mistral_nemo_0120", "size_mb": "{{ llm_size_coef * 7100 }}", "context": 128000 } # says 1000K in table but 128k in desc, going with desc.
|
||||
##### TBD #####
|
||||
### QWEN 2.5 - Older, but does not have "thinking", tempting!
|
||||
#- qwen2.5:0.5b
|
||||
#- qwen2.5:1.5b
|
||||
#- qwen2.5:3b
|
||||
#- qwen2.5:7b
|
||||
#- qwen2.5:14b
|
||||
#- qwen2.5:32b
|
||||
#- qwen2.5:72b
|
||||
### Z.ai
|
||||
#- GLM-5.x
|
||||
#- glm4-flash
|
||||
@@ -215,9 +211,9 @@
|
||||
- name: Workstation | Linux | Software | LLMs | Facts | Choices | Sort
|
||||
ansible.builtin.set_fact:
|
||||
llm_installs: >-
|
||||
{{ llm_choices | selectattr('size_mb', 'le', ansible_memtotal_mb) | list }}
|
||||
{{ llm_installs | union(llm_choices | selectattr('size_mb', 'le', ansible_memtotal_mb) | list) }}
|
||||
llm_removals: >-
|
||||
{{ llm_choices | selectattr('size_mb', 'gt', ansible_memtotal_mb) | list }}
|
||||
{{ llm_removals | union(llm_choices | selectattr('size_mb', 'gt', ansible_memtotal_mb) | list) }}
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | Facts | Merge | Print
|
||||
ansible.builtin.debug:
|
||||
@@ -448,18 +444,12 @@
|
||||
# Ensure cleanup on any exit (normal or signal from runit).
|
||||
trap 'kill "$LOOP_PID" 2>/dev/null; wait "$LOOP_PID" 2>/dev/null' EXIT
|
||||
|
||||
# Create a network for associated programs.
|
||||
net={{ llm_docker_network }}
|
||||
docker network inspect $net >/dev/null 2>&1 || \
|
||||
docker network create $net
|
||||
|
||||
# Start the open-webui program.
|
||||
set -e
|
||||
docker run \
|
||||
--name open-webui --network $net \
|
||||
-e PORT={{ open_webui_port }} \
|
||||
-p {{ open_webui_port }}:{{ open_webui_port }} \--add-host=host.docker.internal:host-gateway \
|
||||
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
|
||||
--name open-webui \
|
||||
--network host -e PORT={{ open_webui_port }} \
|
||||
-e OLLAMA_BASE_URL=http://0.0.0.0:11434 \
|
||||
{{ ("-e HF_TOKEN=" ~ hf_token) if hf_token else '' }} \
|
||||
-e WEBUI_SECRET_KEY={{ open_webui_key }} \
|
||||
-e ENABLE_QUERIES_CACHE=True \
|
||||
@@ -505,6 +495,17 @@
|
||||
|
||||
# Open Terminal - Start #
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | Sandbox
|
||||
ansible.builtin.import_tasks: tasks/workstation/linux/software/ai/sandbox.yml
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | Facts
|
||||
ansible.builtin.set_fact:
|
||||
jdk_jvm: "{{ jdk_jvm | default('/usr/lib/jvm') }}"
|
||||
jdk_etc: "{{ jdk_etc | default('/etc/java-openjdk') }}"
|
||||
jdk_etc17: "{{ jdk_etc17 | default('/etc/java17-openjdk') }}"
|
||||
jdk_etc21: "{{ jdk_etc21 | default('/etc/java21-openjdk') }}"
|
||||
jdk_etc25: "{{ jdk_etc25 | default('/etc/java25-openjdk') }}"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | Dir | /etc/sv
|
||||
ansible.builtin.file:
|
||||
name: "/etc/sv/open-terminal/log"
|
||||
@@ -526,210 +527,18 @@
|
||||
owner: root
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | AI-Sandbox | Dir
|
||||
ansible.builtin.file:
|
||||
dest: "{{ user_user.home }}/AI-Sandbox"
|
||||
state: directory
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | AI-Sandbox | Env
|
||||
ansible.builtin.blockinfile:
|
||||
path: "{{ user_user.home }}/AI-Sandbox/{{ item }}"
|
||||
marker: "# {mark} | MANAGE BY ANSIBLE | Env Vars"
|
||||
content: |
|
||||
if [[ -d "$HOME/bin" ]]; then
|
||||
export PATH="$HOME/bin:$PATH"
|
||||
fi
|
||||
|
||||
export ANDROID_HOME="{{ user_user.home }}/SDKs/Android/Sdk"
|
||||
export GRADLE_USER_HOME={{ user_user.home }}/.gradle
|
||||
export PATH="$ANDROID_HOME/platform-tools:$PATH"
|
||||
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
|
||||
|
||||
export FLUTTER_HOME="{{ user_user.home }}/SDKs/Flutter/flutter"
|
||||
export PUB_CACHE={{ user_user.home }}/.pub-cache
|
||||
export PATH="$FLUTTER_HOME/bin:$PATH"
|
||||
|
||||
export JAVA_HOME="{{ user_user.home }}/SDKs/Java"
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
create: false
|
||||
backup: false
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- ".bashrc"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | AI-Sandbox | Defaults
|
||||
ansible.builtin.set_fact:
|
||||
jdk_jvm: "{{ jdk_jvm | default('/usr/lib/jvm') }}"
|
||||
jdk_etc: "{{ jdk_etc | default('/etc/java-openjdk') }}"
|
||||
jdk_etc17: "{{ jdk_etc17 | default('/etc/java17-openjdk') }}"
|
||||
jdk_etc21: "{{ jdk_etc21 | default('/etc/java21-openjdk') }}"
|
||||
jdk_etc25: "{{ jdk_etc25 | default('/etc/java25-openjdk') }}"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | AI-Sandbox | AGENTS.md
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ user_user.home }}/AI-Sandbox/AGENTS.md"
|
||||
content: |
|
||||
# Environment
|
||||
|
||||
You are running in a Docker container called Open Terminal. We are
|
||||
communicating via Open WebUI, also being run in a Docker
|
||||
container. You are the user `user` and have been granted access to
|
||||
the designer's Code and SDKs via mount at `{{ user_user.home }}`.
|
||||
|
||||
Host system is typically (but not always) a systemd-free distro
|
||||
such as Artix or Devuan. User likes the `runit` service manager.
|
||||
`elogind` is used rather than systemd's logind. Desktop is i3 and
|
||||
display manager is lightdm. Servers are run on Debian and Docker
|
||||
containers are typically debian:trixie-slim with a Dockerfile
|
||||
called by compose.yml which adds the necessary packages, sometimes
|
||||
building from source if the Debian executable is too old.
|
||||
|
||||
If the `$GOT_EM` environment variable is `true` then all the
|
||||
necessary packages for compiling Android and Flutter were
|
||||
installed. If it is `false` then they were not installed, and
|
||||
compiling will fail. Please check this before trying and alert me
|
||||
if they need added. If we don't have Internet, then ask me to
|
||||
compile or run whatever command is needed on the host system.
|
||||
|
||||
# Rules
|
||||
|
||||
Never use any `git` subcommands that change the repo, including
|
||||
but not limited to `add`, `commit`, `pull`, `push`, `branch`,
|
||||
`switch`, etc. The user is who controls the respository changes.
|
||||
You may use informational git subcommands such as `git status`,
|
||||
and may occasionally be asked to run `git clone` type commands.
|
||||
|
||||
If any programs need installed in order to work on a project, we
|
||||
need to document that in an `install.sh` script, as well as add it
|
||||
to `~/PACKAGES.txt` so that we can ensure they stay installed.
|
||||
`install.sh` scripts should be for both `apt` systems (Debian,
|
||||
Ubuntu) and pacman system (Arch, Artix). using distribution
|
||||
package managers is preferable over `pip` and `npm` when
|
||||
possible, unless the project is actually Python or Node.js.
|
||||
|
||||
The user manages the `{{ user_user.home }}/SDKs` directory. Do not
|
||||
modify it. Instead, ask if anything needs updated or added.
|
||||
|
||||
Never manually edit, modify, delete, alter, replace, etc any
|
||||
files under system folders such as `/usr`. Anything under `/` is
|
||||
managed by the system. If you need assistance changing anything
|
||||
such as `/usr/lib/jvm`, please ask the user and halt all further
|
||||
operations until you have received feedback.
|
||||
|
||||
# Effort
|
||||
|
||||
It is never okay to brute force a solution if something is not
|
||||
working well. it is better to ask the user for assistance or alert
|
||||
them that you've encountered blockers and then cease the process
|
||||
until you've received feedback. This especially relates to when
|
||||
system errors occur which are not related to the source code, such
|
||||
as a compiler failing to be found or an SDK version mismatch. If
|
||||
the error is with the source code though, troubleshooting and code
|
||||
changes should continue until the program is compiling properly.
|
||||
|
||||
For CLI projects such as script languages, the final result should
|
||||
always be tested both to run successfully and have the proper
|
||||
output. All test cases should be analyzed and walked through,
|
||||
which will help ensure all the requirements have been met.
|
||||
|
||||
For GUI programs (such as Android, Flutter, Kotlin Multiplatform,
|
||||
Kivy, etc), the project should be tested to both compile & build
|
||||
successfully and also generate the proper installation file (APK,
|
||||
Linux Bundle). Once that is confirmed, the user/desginer will test
|
||||
that the application meets the proper requirements.
|
||||
|
||||
# Preferences
|
||||
|
||||
You have free reign over your home directory. Feel free to
|
||||
create memory files or anything else which would benefit you.
|
||||
|
||||
Everything we create should have both Desktop Linux and Android
|
||||
in mind. Windows, MacOS, and iOS will never be compiled for, but
|
||||
if we can do things in a way which makes it easy for others to
|
||||
fork the project and add the support themselves, then that's best.
|
||||
|
||||
# Versions
|
||||
|
||||
These are the versions of plugins and languages we need to use.
|
||||
If you know of an important upgrade from them, please let me know.
|
||||
|
||||
## Android / Flutter
|
||||
|
||||
- Gradle: 9.8.0
|
||||
- AGP: 9.4.1
|
||||
- Kotlin: 2.4.20
|
||||
- Java: JDK 17
|
||||
- Flutter (plugin loader): 1.0.0
|
||||
|
||||
Regardless of whether AGP bundles Kotlin, we need to specify it to
|
||||
avoid things like "Your project's Kotlin version (2.2.10) is lower
|
||||
than Flutter's minimum supported version of 2.2.20. Please upgrade
|
||||
your Kotlin version." This is exactly why we use these versions,
|
||||
plus it helps document what's actually being used over guessing.
|
||||
backup: false
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | LLMs | runit | open-terminal | Script | Compose YAML
|
||||
ansible.builtin.copy:
|
||||
dest: /usr/local/etc/open-terminal/compose.yml
|
||||
content: |
|
||||
#exec docker run \
|
||||
# --name open-terminal \
|
||||
# --network=host \
|
||||
# -v {{ user_user.home }}/AI-Sandbox:/home/user \
|
||||
# -v {{ user_user.home }}/Code:{{ user_user.home }}/Code \
|
||||
# -v {{ user_user.home }}/SDKs:{{ user_user.home }}/SDKs \
|
||||
# -v {{ jdk_jvm }}:{{ jdk_jvm }}:ro \
|
||||
# -v {{ jdk_etc }}:{{ jdk_etc }}:ro \
|
||||
# -v {{ jdk_etc17 }}:{{ jdk_etc17 }}:ro \
|
||||
# -v {{ jdk_etc21 }}:{{ jdk_etc21 }}:ro \
|
||||
# -v {{ jdk_etc25 }}:{{ jdk_etc25 }}:ro \
|
||||
# -v /etc/hosts:/etc/hosts:ro \
|
||||
# -v {{ user_user.home }}/.gradle:{{ user_user.home }}/.gradle \
|
||||
# -v {{ user_user.home }}/.pub-cache:{{ user_user.home }}/.pub-cache \
|
||||
# -e OPEN_TERMINAL_FILE_BROWSER_ROOT="/home/user" \
|
||||
# -e OPEN_TERMINAL_API_KEY="{{ open_terminal_key }}" \
|
||||
# -e OPEN_TERMINAL_PACKAGES="$packages" \
|
||||
# -e GOT_EM="$GOT_EM" \
|
||||
# $image run --port {{ open_terminal_port }}
|
||||
networks:
|
||||
{{ llm_docker_network }}:
|
||||
name: {{ llm_docker_network }}
|
||||
external: true
|
||||
|
||||
services:
|
||||
open-terminal:
|
||||
container_name: open-terminal
|
||||
build:
|
||||
context: ./
|
||||
image: hyperling-open-terminal:latest
|
||||
container_name: open-terminal
|
||||
ports:
|
||||
- {{ open_terminal_port }}:{{ open_terminal_port }}
|
||||
networks:
|
||||
- {{ llm_docker_network }}
|
||||
#dns:
|
||||
# ## Mullvad
|
||||
# ## (https://mullvad.net/en/help/dns-over-https-and-dns-over-tls)
|
||||
# #- 194.242.2.9 # all.dns.mullvad.net
|
||||
# ##- 194.242.2.8 # not real (yet?)
|
||||
# ##- 194.242.2.7 # not real (yet?)
|
||||
# #- 194.242.2.6 # family.dns.mullvad.net
|
||||
# #- 194.242.2.5 # extended.dns.mullvad.net
|
||||
# #- 194.242.2.4 # base.dns.mullvad.net
|
||||
# #- 194.242.2.3 # adblock.dns.mullvad.net
|
||||
# - 194.242.2.2 # dns.mullvad.net
|
||||
# #- 194.242.2.1 # not real (yet?)
|
||||
# #- 194.242.2.0 # not real (yet?)
|
||||
# ## Cloudflare
|
||||
# - 1.0.0.1
|
||||
# - 1.1.1.1
|
||||
image: hyperling/open-terminal:latest
|
||||
pull_policy: never
|
||||
network_mode: host
|
||||
command: run --port {{ open_terminal_port }}
|
||||
environment:
|
||||
- OPEN_TERMINAL_FILE_BROWSER_ROOT=/home/user
|
||||
@@ -747,7 +556,6 @@
|
||||
- {{ jdk_etc17 }}:{{ jdk_etc17 }}:ro
|
||||
- {{ jdk_etc21 }}:{{ jdk_etc21 }}:ro
|
||||
- {{ jdk_etc25 }}:{{ jdk_etc25 }}:ro
|
||||
#- /etc/resolv.conf:/etc/resolv.conf:ro
|
||||
- {{ user_user.home }}/.gradle:{{ user_user.home }}/.gradle
|
||||
- {{ user_user.home }}/.pub-cache:{{ user_user.home }}/.pub-cache
|
||||
owner: root
|
||||
@@ -991,7 +799,6 @@
|
||||
loop:
|
||||
- { 'name': "{{ ollama }}" , 'status': "{{ ollama_enabled }}" }
|
||||
- { 'name': "{{ zeroclaw }}" , 'status': "{{ zeroclaw_enabled }}" }
|
||||
- { 'name': 'docker' , 'status': true }
|
||||
- { 'name': 'open-webui' , 'status': "{{ open_webui_enabled }}" }
|
||||
- { 'name': 'open-terminal' , 'status': "{{ open_terminal_enabled }}" }
|
||||
- { 'name': 'swap-stopper' , 'status': true }
|
||||
@@ -1034,17 +841,24 @@
|
||||
path: "{{ user_user.home }}/{{ item }}"
|
||||
marker: "# {mark} ANSIBLE MANAGED BLOCK | ollama | Manual Script"
|
||||
content: |
|
||||
function ollama_llms() {
|
||||
function llm_installs() {
|
||||
{% for llm in llm_installs %}
|
||||
|
||||
echo "{{ llm.model }}"
|
||||
|
||||
{% endfor %}
|
||||
}
|
||||
function llm_removals() {
|
||||
{% for llm in llm_removals %}
|
||||
|
||||
echo "{{ llm.model }}"
|
||||
|
||||
{% endfor %}
|
||||
}
|
||||
function ollama_pull() {
|
||||
echo "Manually Pulling Models"
|
||||
|
||||
for model in `ollama_llms`; do
|
||||
for model in `llm_installs`; do
|
||||
echo -e "\n\n Starting 'ollama pull $model' \n\n"
|
||||
ollama pull $model
|
||||
status=$?
|
||||
@@ -1057,6 +871,22 @@
|
||||
alias pull-models="ollama_pull "
|
||||
alias pull-ai="ollama_pull "
|
||||
|
||||
function ollama_clean() {
|
||||
echo "Cleaning Models"
|
||||
|
||||
for model in `llm_removals`; do
|
||||
echo -e "\n Removing '$model'"
|
||||
ollama rm $model
|
||||
done
|
||||
|
||||
echo "Done!"
|
||||
}
|
||||
alias ollama-clean="ollama_clean "
|
||||
alias clean-ollama="ollama_clean "
|
||||
alias clean-llms="ollama_clean "
|
||||
alias clean-models="ollama_clean "
|
||||
alias clean-ai="ollama_clean "
|
||||
|
||||
function ollama_chat() {
|
||||
ollama run {{ 'qwen3.8:27b' if ansible_memtotal_mb > 32000 else 'qwen3.5:4b' }}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,496 @@
|
||||
---
|
||||
# Move the plays related to AGENTS.md to its own file since it is now so large.
|
||||
|
||||
- name: Workstation | Linux | Software | AI | Sandbox | Dir
|
||||
ansible.builtin.file:
|
||||
dest: "{{ user_user.home }}/AI-Sandbox"
|
||||
state: directory
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | AI | Sandbox | Env
|
||||
ansible.builtin.blockinfile:
|
||||
path: "{{ user_user.home }}/AI-Sandbox/{{ item }}"
|
||||
marker: "# {mark} | MANAGE BY ANSIBLE | Env Vars"
|
||||
content: |
|
||||
if [[ -d "$HOME/bin" ]]; then
|
||||
export PATH="$HOME/bin:$PATH"
|
||||
fi
|
||||
|
||||
export ANDROID_HOME="{{ user_user.home }}/SDKs/Android/Sdk"
|
||||
export GRADLE_USER_HOME={{ user_user.home }}/.gradle
|
||||
export PATH="$ANDROID_HOME/platform-tools:$PATH"
|
||||
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
|
||||
|
||||
export FLUTTER_HOME="{{ user_user.home }}/SDKs/Flutter/flutter"
|
||||
export PUB_CACHE={{ user_user.home }}/.pub-cache
|
||||
export PATH="$FLUTTER_HOME/bin:$PATH"
|
||||
|
||||
export JAVA_HOME="{{ user_user.home }}/SDKs/Java"
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
create: true
|
||||
backup: false
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- ".bashrc"
|
||||
|
||||
- name: Workstation | Linux | Software | AI | Sandbox | AGENTS.md
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ user_user.home }}/AI-Sandbox/AGENTS.md"
|
||||
content: |
|
||||
# Environment
|
||||
|
||||
You are running in a Docker container called Open Terminal. We are
|
||||
communicating via Open WebUI, also being run in a Docker
|
||||
container. You are the user `user` and have been granted access to
|
||||
the designer's Code and SDKs via mount at `{{ user_user.home }}`.
|
||||
|
||||
Host system is typically (but not always) a systemd-free distro
|
||||
such as Artix or Devuan. User likes the `runit` service manager.
|
||||
`elogind` is used rather than systemd's logind. Desktop is i3 and
|
||||
display manager is lightdm. Servers are run on Debian and Docker
|
||||
containers are typically debian:trixie-slim with a Dockerfile
|
||||
called by compose.yml which adds the necessary packages, sometimes
|
||||
building from source if the Debian executable is too old.
|
||||
|
||||
If the `$GOT_EM` environment variable is `true` then all the
|
||||
necessary packages for compiling Android and Flutter were
|
||||
installed. If it is `false` then they were not installed, and
|
||||
compiling will fail. Please check this before trying and alert me
|
||||
if they need added. If we don't have Internet, then ask me to
|
||||
compile or run whatever command is needed on the host system.
|
||||
|
||||
# Rules
|
||||
|
||||
Never use any `git` subcommands that change the repo, including
|
||||
but not limited to `add`, `commit`, `pull`, `push`, `branch`,
|
||||
`switch`, etc. The user is who controls the respository changes.
|
||||
You may use informational git subcommands such as `git status`,
|
||||
and may occasionally be asked to run `git clone` type commands.
|
||||
|
||||
If any programs need installed in order to work on a project, we
|
||||
need to document that in an `install.sh` script, as well as add it
|
||||
to `~/PACKAGES.txt` so that we can ensure they stay installed.
|
||||
`install.sh` scripts should be for both `apt` systems (Debian,
|
||||
Ubuntu) and pacman system (Arch, Artix). using distribution
|
||||
package managers is preferable over `pip` and `npm` when
|
||||
possible, unless the project is actually Python or Node.js.
|
||||
|
||||
The user manages the `{{ user_user.home }}/SDKs` directory. Do not
|
||||
modify it. Instead, ask if anything needs updated or added.
|
||||
|
||||
Never manually edit, modify, delete, alter, replace, etc any
|
||||
files under system folders such as `/usr`. Anything under `/` is
|
||||
managed by the system. If you need assistance changing anything
|
||||
such as `/usr/lib/jvm`, please ask the user and halt all further
|
||||
operations until you have received feedback.
|
||||
|
||||
# Effort
|
||||
|
||||
It is never okay to brute force a solution if something is not
|
||||
working well. it is better to ask the user for assistance or alert
|
||||
them that you've encountered blockers and then cease the process
|
||||
until you've received feedback. This especially relates to when
|
||||
system errors occur which are not related to the source code, such
|
||||
as a compiler failing to be found or an SDK version mismatch. If
|
||||
the error is with the source code though, troubleshooting and code
|
||||
changes should continue until the program is compiling properly.
|
||||
|
||||
For CLI projects such as script languages, the final result should
|
||||
always be tested both to run successfully and have the proper
|
||||
output. All test cases should be analyzed and walked through,
|
||||
which will help ensure all the requirements have been met.
|
||||
|
||||
For GUI programs (such as Android, Flutter, Kotlin Multiplatform,
|
||||
Kivy, etc), the project should be tested to both compile & build
|
||||
successfully and also generate the proper installation file (APK,
|
||||
Linux Bundle). Once that is confirmed, the user/desginer will test
|
||||
that the application meets the proper requirements.
|
||||
|
||||
# Preferences
|
||||
|
||||
You have free reign over your home directory. Feel free to
|
||||
create memory files or anything else which would benefit you.
|
||||
|
||||
Everything we create should have both Desktop Linux and Android
|
||||
in mind. Windows, MacOS, and iOS will never be compiled for, but
|
||||
if we can do things in a way which makes it easy for others to
|
||||
fork the project and add the support themselves, then that's best.
|
||||
|
||||
# Versions
|
||||
|
||||
These are the versions of plugins and languages we need to use.
|
||||
If you know of an important upgrade from them, please let me know.
|
||||
|
||||
If you find that an application is already a newer version than
|
||||
those listed here, that is acceptable, never attempt to downgrade
|
||||
without explicitly asking the user first and having a good reason.
|
||||
|
||||
## Android / Flutter
|
||||
|
||||
- Gradle 9.8.2
|
||||
- AGP 9.5.0
|
||||
- Kotlin 2.4.21
|
||||
- Java JDK 17
|
||||
- Flutter Plugin Loader 1.0.0
|
||||
- compileSdk 37
|
||||
- targetSDK 37
|
||||
|
||||
Regardless of whether AGP bundles Kotlin, we need to specify it to
|
||||
avoid things like "Your project's Kotlin version (2.2.10) is lower
|
||||
than Flutter's minimum supported version of 2.2.20. Please upgrade
|
||||
your Kotlin version." This is exactly why we use these versions,
|
||||
plus it helps document what's actually being used over guessing.
|
||||
|
||||
Only the arm-v8a architecture needs included in the release
|
||||
builds. x86 and others should continue to exist in the debug run.
|
||||
This will help save space on local servers like Gitea and F-Droid.
|
||||
If code for this does not exist, please add splitting or filtering
|
||||
so that when the designer generates a signed APK it's only v8a.
|
||||
|
||||
Android : paths are from the project root.
|
||||
Flutter : paths are under the folder `android`.
|
||||
|
||||
### All Android Project Types
|
||||
|
||||
#### ./gradle/wrapper/grade-wrapper.properties
|
||||
|
||||
```
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip
|
||||
```
|
||||
|
||||
#### ./settings.gradle.kts
|
||||
|
||||
```
|
||||
id("com.android.application") version "9.5.0" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.4.21" apply false
|
||||
```
|
||||
|
||||
#### ./app/build.gradle.kts
|
||||
|
||||
```
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Also enable minify and shrink while in there.
|
||||
|
||||
```
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
...
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Flutter Projects
|
||||
|
||||
#### ./settings.gradle.kts
|
||||
|
||||
```
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
```
|
||||
|
||||
### Native Kotlin Apps
|
||||
|
||||
These only apply to Android apps which are not Flutter, Kivy, etc.
|
||||
|
||||
#### Plugin Versions
|
||||
|
||||
##### ./gradle/libs.versions.toml
|
||||
|
||||
```
|
||||
[versions]
|
||||
agp = "9.5.0"
|
||||
kotlin = "2.4.21"
|
||||
coreKtx = "1.19.1"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.3.0"
|
||||
espressoCore = "3.7.0"
|
||||
lifecycleRuntimeKtx = "2.11.0"
|
||||
activityCompose = "1.13.0"
|
||||
composeBom = "2026.09.00"
|
||||
```
|
||||
|
||||
#### Kotlin Compose Fix
|
||||
|
||||
Also ensure Kotlin is coming from Compose and not Jetbrains.
|
||||
|
||||
##### ./gradle/libs.versions.toml
|
||||
|
||||
```
|
||||
[plugins]
|
||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||
#jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
kotlinCompose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||
```
|
||||
|
||||
##### ./build.gradle.kts
|
||||
|
||||
```
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication) apply false
|
||||
//alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
||||
alias(libs.plugins.kotlinCompose) apply false
|
||||
}
|
||||
```
|
||||
|
||||
##### ./app/build.gradle.kts
|
||||
|
||||
```
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
//alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||
alias(libs.plugins.kotlinCompose)
|
||||
}
|
||||
```
|
||||
|
||||
# Build Processes
|
||||
|
||||
How to compile certain projects. Tools to prefer. If a language
|
||||
or framework is not mentioned, then use the typical commands.
|
||||
|
||||
## Kotlin Multiplatform (KMP)
|
||||
|
||||
Used to create small native Android apps with the ability to also
|
||||
run against Desktop Linux. APK size is the greatest benefit for
|
||||
using KMP over something like Flutter or KivyMD.
|
||||
|
||||
### Kotlin Toolchain
|
||||
|
||||
This is the preferred build type when setting up new projects.
|
||||
|
||||
Please use `kotlin` rather than any `amper` commands. `amper` has
|
||||
been deprecated and is intentionally not present on the system.
|
||||
Examples:
|
||||
|
||||
```
|
||||
# 1. Compile + link ALL targets (JVM, iOS, Android, native, etc.)
|
||||
./kotlin build
|
||||
|
||||
# 2. (Optional) Run tests across all targets
|
||||
./kotlin test
|
||||
|
||||
# 3. (Optional) Run all quality checks (tests + registered linters)
|
||||
./kotlin check
|
||||
```
|
||||
|
||||
### Gradle KMP
|
||||
|
||||
This is a legacy method, new projects will not be set up with it.
|
||||
Examples:
|
||||
|
||||
```
|
||||
# Compile all targets
|
||||
./gradlew assemble
|
||||
|
||||
# Or more explicitly (if you want to be sure nothing is skipped):
|
||||
./gradlew jvmJar assembleDebug assembleIosSimulatorArm64 # etc. per target
|
||||
|
||||
# Run all tests
|
||||
./gradlew allTests
|
||||
```
|
||||
|
||||
# Coding Conventions
|
||||
|
||||
Preferences related to how code should be written.
|
||||
|
||||
## All languages
|
||||
|
||||
If a value is going to be used more than once, even a small path or file
|
||||
name, it should exist in a variable.
|
||||
|
||||
Relative shebangs such as `#!/usr/bin/env bash` and `#!/usr/bin/env node`
|
||||
are always preferred over static shebangs such as `#!/bin/bash`, since
|
||||
scripts are run across a multitude of different systems.
|
||||
|
||||
### Layout
|
||||
|
||||
Programs should be laid out in 5 sections.
|
||||
|
||||
- Variables
|
||||
- Instantiate global variables and defaults used for parameters which
|
||||
do not get passed an explicit value by the user.
|
||||
- Functions
|
||||
- Functions to be used throughout the program, including the Usage.
|
||||
- Parameters / Validation
|
||||
- Parse the parameters, validate the input, and assign any defaults.
|
||||
- Main
|
||||
- The primary logic of the program, completes the task at hand.
|
||||
- Finish / Cleanup
|
||||
- Typically just `exit 0`, but sometimes a summary of what was done.
|
||||
|
||||
All sections may not always apply, such as with Hugo websites. With
|
||||
projects like Android apps this would apply to each individual function,
|
||||
method, and class. If a section does not need anything, it can be blank.
|
||||
|
||||
```
|
||||
public static void doThing(String thingName) {
|
||||
// Variables //
|
||||
String thingPrefix = "/place/for/thing/"
|
||||
|
||||
// Functions //
|
||||
|
||||
// Parameters //
|
||||
if (thingName.isEmpty) {
|
||||
Exception e = new Exception("No name passed!");
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Main //
|
||||
runStuff(thingPrefix + thingName);
|
||||
|
||||
// Finish //
|
||||
}
|
||||
```
|
||||
|
||||
The comments do not need to be included, this example is just as valid,
|
||||
what maytters most is that the 5 section are done in order rather than
|
||||
instantiating variable mid-scope.
|
||||
|
||||
```
|
||||
public static void doThing(String thingName) {
|
||||
String thingPrefix = "/place/for/thing/"
|
||||
|
||||
if (thingName.isEmpty) {
|
||||
Exception e = new Exception("No name passed!");
|
||||
throw e;
|
||||
}
|
||||
|
||||
runStuff(thingPrefix + thingName);
|
||||
}
|
||||
```
|
||||
|
||||
`if` statements and loops start new scope, so they also need the layout
|
||||
applied to them. Loops may sometimes require a variable assignment before
|
||||
it begins which is completely okay and does not break the layout rule.
|
||||
This example has a Variables, Validation, Main, and Finish section without
|
||||
the use of labels or comments since the code itself is simple and small.
|
||||
|
||||
```
|
||||
count=0
|
||||
array="cats dogs giraffes rhinos horses"
|
||||
last_animal=""
|
||||
for animal in $array; do
|
||||
if (( count >= 3 )); then
|
||||
echo "That's enough! We finished at the ${last_animal}."
|
||||
break;
|
||||
fi
|
||||
|
||||
echo "We're looking at ${animal}."
|
||||
|
||||
last_animal=$animal
|
||||
(( count++ ))
|
||||
done
|
||||
```
|
||||
|
||||
Providing the user's input in error messages is really helpful and can aid
|
||||
their troubleshooting if things are not going according to expectations.
|
||||
|
||||
Example using Bash:
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
### Variables ###
|
||||
|
||||
declare A B
|
||||
typeset -i a b
|
||||
|
||||
### Functions ###
|
||||
|
||||
function usage() {
|
||||
status="$1"
|
||||
cat << EOF
|
||||
Usage: add.sh -a NUM -b NUM [-h]
|
||||
|
||||
Adds two numbers and prints out the full equation.
|
||||
|
||||
Example:
|
||||
|
||||
$ add.sh -a 5 -b 25
|
||||
5 + 25 = 30
|
||||
EOF
|
||||
exit $status
|
||||
}
|
||||
function add() {
|
||||
num1="$1"
|
||||
num2="$2"
|
||||
sum=""
|
||||
|
||||
if [[ -z $num1 || -z $num2 ]]; then
|
||||
echo "ERROR: Two numnbers must be passed."
|
||||
fi
|
||||
|
||||
sum=$(( num1 + num2 ))
|
||||
echo "${num1} + ${num2} = ${sum}"
|
||||
}
|
||||
|
||||
### Parameters ###
|
||||
|
||||
while getopts ':a:b:h' opt; do
|
||||
case $opt in
|
||||
a) A="$OPTARG" ;;
|
||||
b) B="$OPTARG" ;;
|
||||
h) usage 0 ;;
|
||||
*) echo "ERROR: Option $OPTARG not recognized." >&2 && usage 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$A" || -z "$B" ]]; then
|
||||
echo "ERROR: Both numbers need to be passed. A=${A} B=${B}" >&2
|
||||
usage 2
|
||||
fi
|
||||
a="$A" b="$B"
|
||||
if [[ "$a" != "$A" || "$b" != "$B" ]]; then
|
||||
echo "ERROR: Values contain non-numeric data, please try again." >&2
|
||||
echo "A=${A} B=${B}" >&2
|
||||
usage 3
|
||||
fi
|
||||
|
||||
### Main ###
|
||||
|
||||
add "$a" "$b"
|
||||
|
||||
### Finish ###
|
||||
|
||||
unset A B usage add
|
||||
exit 0
|
||||
```
|
||||
|
||||
## Bash
|
||||
|
||||
`[[ ]]` are preferred over `[ ]`, `test`, etc. `(( ))` are always fine.
|
||||
|
||||
When defining a function please use both the keyword `function` as well as
|
||||
the `()`, such as `function myfunc() {}`.
|
||||
|
||||
When instantiating global variables, please use `typeset` or `declare`
|
||||
rather than just `VAR1=""; VAR2=""`, such as:
|
||||
|
||||
```
|
||||
declare VAR1="" VAR2="" BOOL="true" BOOL2="false"
|
||||
typeset -i INT1=0 INT2=99
|
||||
```
|
||||
|
||||
When doing colored output, `tput` is always preferred over literal values.
|
||||
backup: false
|
||||
owner: "{{ user }}"
|
||||
group: "{{ user }}"
|
||||
mode: "0755"
|
||||
@@ -33,22 +33,84 @@
|
||||
owner: root
|
||||
mode: '0755'
|
||||
|
||||
# This was causing the docker daemon to fail. Was trying to fix ports mappings.
|
||||
#- name: Workstation | Linux | Software | Docker | Config | File
|
||||
# ansible.builtin.copy:
|
||||
# dest: /etc/docker/daemon.json
|
||||
# content: |
|
||||
# {
|
||||
# "firewall-backend": "nftables"
|
||||
# }
|
||||
# backup: false
|
||||
# owner: root
|
||||
# mode: '0644'
|
||||
# when: ansible_pkg_mgr == "pacman"
|
||||
- name: Workstation | Linux | Software | Socker | Services | Enable
|
||||
ansible.builtin.service:
|
||||
name: "{{ item.name }}"
|
||||
state: "{{ 'started' if item.status else 'stopped' }}"
|
||||
enabled: "{{ item.status }}"
|
||||
loop:
|
||||
- { 'name': 'docker' , 'status': true }
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Config | File
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Facts
|
||||
ansible.builtin.set_fact:
|
||||
docker_network_sync: "docker-network-sync"
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Block
|
||||
block:
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | /etc/sv
|
||||
ansible.builtin.file:
|
||||
name: /etc/docker/daemon.json
|
||||
state: absent
|
||||
name: "/etc/sv/{{ docker_network_sync }}/log"
|
||||
state: directory
|
||||
owner: root
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | /var/log
|
||||
ansible.builtin.file:
|
||||
name: "/var/log/{{ docker_network_sync }}"
|
||||
state: directory
|
||||
owner: "{{ user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Run
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/sv/{{ docker_network_sync }}/run
|
||||
content: |
|
||||
#!/bin/sh
|
||||
# Ensure all containers using host network keep a correct resolv.conf.
|
||||
exec 2>&1
|
||||
set -e
|
||||
|
||||
while true; do
|
||||
for c in $(docker container ls --filter network=host -q); do
|
||||
echo "RUN: Container ID $c"
|
||||
docker exec -i -u root $c sh -c 'tee /etc/resolv.conf' < /etc/resolv.conf
|
||||
done
|
||||
echo "RUN: Done, sleeping."
|
||||
sleep 20
|
||||
done
|
||||
backup: false
|
||||
owner: root
|
||||
mode: '0755'
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Finish
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/sv/{{ docker_network_sync }}/finish
|
||||
content: |
|
||||
{{ runit_finish_sleep }}
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Log
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/sv/{{ docker_network_sync }}/log/run
|
||||
content: |
|
||||
#!/bin/sh -e
|
||||
exec svlogd -tt /var/log/{{ docker_network_sync }}
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | Docker | Network Sync | runit | Log Config
|
||||
ansible.builtin.copy:
|
||||
dest: /var/log/{{ docker_network_sync }}/config
|
||||
content: |
|
||||
{{ runit_log_config_1mb }}
|
||||
mode: "0755"
|
||||
|
||||
- name: Workstation | Linux | Software | Socker | Services | Enable
|
||||
ansible.builtin.service:
|
||||
name: "{{ item.name }}"
|
||||
state: "{{ 'started' if item.status else 'stopped' }}"
|
||||
enabled: "{{ item.status }}"
|
||||
loop:
|
||||
- { 'name': '{{ docker_network_sync }}', 'status': true }
|
||||
|
||||
when: ansible_service_mgr == "runit"
|
||||
@@ -21,12 +21,6 @@
|
||||
- name: TEST | LLMs
|
||||
block:
|
||||
|
||||
- name: Java
|
||||
ansible.builtin.include_tasks: tasks/workstation/linux/software/java.yml
|
||||
|
||||
- name: Docker
|
||||
ansible.builtin.include_tasks: tasks/workstation/linux/software/docker.yml
|
||||
|
||||
- name: LLM
|
||||
ansible.builtin.include_tasks: tasks/workstation/linux/software/ai/llm.yml
|
||||
|
||||
|
||||
Reference in new issue
Block a user