From 9b9dd76e1e3a4f9aa6c0b4f575a0564bd82c6c16 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 21 Sep 2023 11:49:37 +0300 Subject: [PATCH 01/40] wip --- kasmvnc/main.tf | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ kasmvnc/run.sh | 38 +++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 kasmvnc/main.tf create mode 100644 kasmvnc/run.sh diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf new file mode 100644 index 00000000..65ea242e --- /dev/null +++ b/kasmvnc/main.tf @@ -0,0 +1,82 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 0.12" + } + } +} + +variable "agent_id" { + type = string + description = "The ID of a Coder agent." +} + +variable "extensions" { + type = list(string) + description = "A list of extensions to install." + default = [] +} + +variable "port" { + type = number + description = "The port to run code-server on." + default = 13337 +} + +variable "settings" { + type = map(string) + description = "A map of settings to apply to code-server." + default = {} +} + +variable "folder" { + type = string + description = "The folder to open in code-server." + default = "" +} + +variable "install_prefix" { + type = string + description = "The prefix to install code-server to." + default = "/tmp/code-server" +} + +variable "log_path" { + type = string + description = "The path to log code-server to." + default = "/tmp/code-server.log" +} + +resource "coder_script" "code-server" { + agent_id = var.agent_id + display_name = "code-server" + icon = "/icon/code.svg" + script = templatefile("${path.module}/run.sh", { + EXTENSIONS : join(",", var.extensions), + PORT : var.port, + LOG_PATH : var.log_path, + INSTALL_PREFIX : var.install_prefix, + // This is necessary otherwise the quotes are stripped! + SETTINGS : replace(jsonencode(var.settings), "\"", "\\\""), + }) + run_on_start = true +} + +resource "coder_app" "kasm_vnc" { + agent_id = var.agent_id + slug = "kasm-vnc" + display_name = "kasmVNC" + url = "http://localhost:${var.port}" + icon = "/icon/vnc.svg" + subdomain = false + share = "owner" + + healthcheck { + url = "http://localhost:${var.port}/healthz" + interval = 5 + threshold = 6 + } +} diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh new file mode 100644 index 00000000..49347f9f --- /dev/null +++ b/kasmvnc/run.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Check if LXDE is installed +if ! dpkg -s lxde &>/dev/null; then + sudo apt-get update + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y lxde +else + echo "LXDE is already installed." +fi + +# Check if vncserver is installed +if ! dpkg -s kasmvncserver &>/dev/null; then + cd /tmp + wget https://github.com/kasmtech/KasmVNC/releases/download/v1.1.0/kasmvncserver_focal_1.1.0_amd64.deb + sudo apt install -y ./kasmvncserver_focal_1.1.0_amd64.deb +else + echo "VNC Server is already installed." +fi + +sudo addgroup $USER ssl-cert + +# Coder port-forwarding from dashboard only supports HTTP +sudo bash -c 'cat > /etc/kasmvnc/kasmvnc.yaml < Date: Thu, 21 Sep 2023 15:04:56 +0300 Subject: [PATCH 02/40] add kasmVNC --- .icons/kasm.png | Bin 0 -> 29593 bytes kasmvnc/README.md | 25 +++++++++++++++++++-- kasmvnc/main.tf | 55 ++++++++++++---------------------------------- kasmvnc/run.sh | 18 ++++++++------- 4 files changed, 47 insertions(+), 51 deletions(-) create mode 100644 .icons/kasm.png diff --git a/.icons/kasm.png b/.icons/kasm.png new file mode 100644 index 0000000000000000000000000000000000000000..2da3cf151826854b6f6e91d70add534dabdabc94 GIT binary patch literal 29593 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 literal 0 HcmV?d00001 diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 1803268e..d07d8940 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -1,7 +1,7 @@ --- display_name: KasmVNC description: A modern open source VNC server -icon: ../.icons/kasmvnc.svg +icon: ../.icons/kasm.png maintainer_github: coder verified: true tags: [helper, ide] @@ -13,4 +13,25 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ## Examples -TODO \ No newline at end of file +1. Add latest version of KasmVNC with ['lxde'](https://www.lxde.org/) desktop environment: + + ```hcl + module "kasmvnc" { + source = "https://registry.coder.com/modules/kasmvnc" + agent_id = coder_agent.example.id + } + + ``` + +2. Add specific version '0.9.11' of KasmVNC with ['mate'](https://mate-desktop.org/) desktop environment and custom port: + + ```hcl + module "kasmvnc" { + source = "https://registry.coder.com/modules/kasmvnc" + agent_id = coder_agent.example.id + version = "1.0.0" + desktop_environment = "mate" + port = 6080 + } + + ``` diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 65ea242e..57023575 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -14,53 +14,32 @@ variable "agent_id" { description = "The ID of a Coder agent." } -variable "extensions" { - type = list(string) - description = "A list of extensions to install." - default = [] -} - variable "port" { type = number - description = "The port to run code-server on." - default = 13337 + description = "The port to run KasmVNC on." + default = 8443 } -variable "settings" { - type = map(string) - description = "A map of settings to apply to code-server." - default = {} -} - -variable "folder" { +variable "desktop_environment" { type = string - description = "The folder to open in code-server." - default = "" + description = "The desktop environment to for KasmVNC (xfce, lxde, mate, etc)." + default = "lxde" } -variable "install_prefix" { +variable "version" { type = string - description = "The prefix to install code-server to." - default = "/tmp/code-server" + description = "Version of KasmVNC to install." + default = "1.2.0" } -variable "log_path" { - type = string - description = "The path to log code-server to." - default = "/tmp/code-server.log" -} - -resource "coder_script" "code-server" { +resource "coder_script" "kasm_vnc" { agent_id = var.agent_id - display_name = "code-server" - icon = "/icon/code.svg" + display_name = "KasmVNC" + icon = "/icon/kasm.png" script = templatefile("${path.module}/run.sh", { - EXTENSIONS : join(",", var.extensions), PORT : var.port, - LOG_PATH : var.log_path, - INSTALL_PREFIX : var.install_prefix, - // This is necessary otherwise the quotes are stripped! - SETTINGS : replace(jsonencode(var.settings), "\"", "\\\""), + DESKTOP_ENVIRONMENT : var.desktop_environment, + VERSION : var.version }) run_on_start = true } @@ -70,13 +49,7 @@ resource "coder_app" "kasm_vnc" { slug = "kasm-vnc" display_name = "kasmVNC" url = "http://localhost:${var.port}" - icon = "/icon/vnc.svg" + icon = "/icon/kasm.png" subdomain = false share = "owner" - - healthcheck { - url = "http://localhost:${var.port}/healthz" - interval = 5 - threshold = 6 - } } diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 49347f9f..7a59580b 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,20 +1,21 @@ #!/usr/bin/env bash -# Check if LXDE is installed -if ! dpkg -s lxde &>/dev/null; then +# Check if desktop enivronment is installed +if ! dpkg -s ${DESKTOP_ENVIRONMENT} &>/dev/null; then sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y lxde + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} else - echo "LXDE is already installed." + echo "${DESKTOP_ENVIRONMENT} is already installed." fi # Check if vncserver is installed if ! dpkg -s kasmvncserver &>/dev/null; then cd /tmp - wget https://github.com/kasmtech/KasmVNC/releases/download/v1.1.0/kasmvncserver_focal_1.1.0_amd64.deb - sudo apt install -y ./kasmvncserver_focal_1.1.0_amd64.deb + wget https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_amd64.deb + sudo apt install -y ./kasmvncserver_focal_${VERSION}_amd64.deb + printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" else - echo "VNC Server is already installed." + echo "KasmVNC is already installed." fi sudo addgroup $USER ssl-cert @@ -23,6 +24,7 @@ sudo addgroup $USER ssl-cert sudo bash -c 'cat > /etc/kasmvnc/kasmvnc.yaml < Date: Thu, 21 Sep 2023 15:08:13 +0300 Subject: [PATCH 03/40] TODO --- kasmvnc/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index d07d8940..21bf6af0 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -35,3 +35,5 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and } ``` + +![Screenshot of KasmVNC]() //TODO From dec64c77f3cbdb84c6e573cee88459bd8e6d234b Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 21 Sep 2023 16:26:56 +0300 Subject: [PATCH 04/40] fixup! --- kasmvnc/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 21bf6af0..0d1d1bb9 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -13,7 +13,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ## Examples -1. Add latest version of KasmVNC with ['lxde'](https://www.lxde.org/) desktop environment: +1. Add latest version of KasmVNC with [`lxde`](https://www.lxde.org/) desktop environment: ```hcl module "kasmvnc" { @@ -23,7 +23,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ``` -2. Add specific version '0.9.11' of KasmVNC with ['mate'](https://mate-desktop.org/) desktop environment and custom port: +2. Add specific version of KasmVNC with [`mate`](https://mate-desktop.org/) desktop environment and custom port: ```hcl module "kasmvnc" { From bf90b16eaf50ec1c6239224246e44161295f4f83 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 21 Sep 2023 16:28:49 +0300 Subject: [PATCH 05/40] update tags --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 0d1d1bb9..6a85200b 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -4,7 +4,7 @@ description: A modern open source VNC server icon: ../.icons/kasm.png maintainer_github: coder verified: true -tags: [helper, ide] +tags: [helper, ide, VNC] --- # KasmVNC From 92794a23e0b00f064520803c628377f035e5988d Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 22 Sep 2023 12:17:41 +0300 Subject: [PATCH 06/40] Delete .icons/kasm.png --- .icons/kasm.png | Bin 29593 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .icons/kasm.png diff --git a/.icons/kasm.png b/.icons/kasm.png deleted file mode 100644 index 2da3cf151826854b6f6e91d70add534dabdabc94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29593 zcmYIP1yof{*9JvWqy+@&P6_Gm?(XjH?oMft5|HjL0qF+myn@svFC|_7L0`Y0wP0~! z&YsyZJD(G&ASaHD_zn>Y3JO_LLPQA)3Puk2{Rtix_<6jYBo76J$Zjbttl+F9E<_|L zD$K^j$;L*{%)kT%<&l-0>aL=^^fr95gS|r`5j86LhqZ;$3kl>7i3A23CInQe@1LMZ z*hEwuL=+Q>;F+n`0}6x_YDuC(p%rTnU~old9UU<7QYB3)ao4_i9*<|P5nlOO=XOkj z%#VHN+n_$(2fyl((Le}zou`5M3)~+O8*Od?2mSg4>ZJ|Txn7GrEO zFs`vX+TIY|+|kVN$8Z0L;>shET4H$9=&C5H7+rWrNHCNV})`X|P;7|_XzBXB8n zl*3|^Frt4=PRfF#`^P@KVUH!i`o`Ch zpv^~5sc(bMoVI**RYw{+*P5Df_xLvVjlZzI&!kc(=y==E<2;EY(S=D^kKNA9t4O48 zXkx?R=Jif)_%$KiqbtE%w0pA72*zYlk_= zMlN5Y{Yce#QAqqwz>ffmiUy4c!P|uP$FVQcfcVRs@#v|H^z6IIphsWz7MaJPw`Bft z#^NH(E$E69hoA4YUa%5Di3+^j7r@(niSZq#={s5r6w3O`7lKp~FpdUH>p_^GphbwV zF#{UE;3NlC8c>$Nx_&`p4Q6w|aS1eDXXSun2plzlS%p^m@FpjK`UG)I05v3Z2o*~y z+=WPZ2)`~=;}hQ2%U8l^3i!$JqAwy8}_Y{YhKB$lo`QEg3Gz~=lz+$uj zR5Y&q=nrUbd&GniJjf8xh|52re|=#ou>6VOD`9JtL_+b9HYTj7D3gLrGSUbkR_I24 zYMxpiTS1v3oI-X9->m8^l@;Oznyi?0{`l0yE|d!$7jAYmgP8i4%pdP}>vz$9bKGLV z2Im>aFva2c%ivRB)xW66t;d^*;|#?eh%qdx)u`Z_$3KWd?suv&vSDgM^hWhY_kP74 z=NnAA;o{K5p|8Uu7eU*nx~}Cw>7ed_(SrL8{U_>i3`+m`$>^!+wU`fzA3T3tE-@8G z3_?|igbJ?ovK&t7edW773UYzY5S zjH0@uGN&?D2`Q5|Rc@ViofX^H+~+_RW+{60L&>tR!QLXcff_3+DqE^SDn}}I#1V`7 zeIDM_%iX=-%(sTOuD9H(^s4fzo%S!R7_XJ(sA z-AmVI1T51nL#(%~4yQQEPhH;F#*N}bvJyGN!K?EjAIDiqS=B8dGx$HU=BMY+W=5vV zrnw3(R5GiM^0Lc1gzrKwzrIl&lokI{FAV-VVH}3oo0Kq7V)C1*$mOH!gDZL4MO$zi zi`RgcqF1Qbk=NC4gj>1?vWNG#9kD zcsTu!w{mZVqG6-)WYA}lGJ0)Hs|1Nnbm2yTRraWA~XHD?+2L?#_kB;NXJbp}cX! z>8bBbQ?>J_u+amE#y>1q1?yysG*L9Ec4!(Pd;){|ao-`OzTxwnh7MwKKo7W?$ep9_*V}2=h zNp0V^GTGke{Udw>V_W&ic};zieW`iQePr^dedrpse}n(0C$=X%Xf5c~fSrI+fx+)7 zfxd!Yzq}Hh6GRCb4-)O>C3cW77`pt_evS-A0=tI>{RsGRly}t=)0-OVOBjcMf>e#* zk7J0Th&t63&}J|kl=`Zgq=RIX^Znf2cr<*U243sU>Ead}2m=Ho2hJYOKJj>j5iC#EN|8dzE9EBpGlwT*BS$IWOy&Dq6{MWv z+v54cPB|pmmE22eUWyLhmuU&$^ z8D2GKoo$aLgr3NJj9j^$+$_En*ZsY{tr_DEX|Lm~NM7ek#&7l~Hb0im!9J7Odsm12 zop*eA{-;C>amR4`&92&QCAityZgN%A8QZscD`&bR>hALuo*(N&t?oV% zFW){d*NH)QFt_n)EhWF{({I0TyTmt!{UH+~=cFs*gA~4$jQo1n9`};-Ng2ic{IpLx zcVk;i?p+@D%pb70KR)XGzMrYi)Gz5;e42)s9=k05eo)7)Hq%S{rs(gyPJdwg)Sm8+ z!P0tMdrZrp?zek`^ZOK193!9W_wp*_{4U1Y#o6@f);4e0!5!I4$KWRv z?#QEizwwEQ2_N^J4uSQ@W*F%2upsh$(nC(;r;>KG=94=$pZRsMriS}*+ar6wI%#)) z;LyNV3f-4>=m12ek9mgT`z`#vb-@L~==58>~}*YH6YC2aqr^Bth`QScv~;2?mG zXi5kL4<+{CKIGM(N4_&YuPMp@5kkxg{pT-Kq%f50?*F4PgqjtQ`|p1NhJp?+{6c@g z{M{}Lxf|gc?cd3$kbno-|2_D{=J~;EepXKd(T;A84$Qu`D_k-K(Q^a{w*Z{mLB}$G{735m-g=hZaa&_!Hx|yMwba`=NYB>2G3$enEi^^PM#4oe9Wph2Eg}F;67U32 zWCVnjVh7Xe5=57r?IGMMf?f*Gz6f%v6_XWJ^eAn=gZX>vZ9pa8UI6Fx5bI;T+JJSx zRF@LM5d6K+*yKBOesj--b@9wx8A1@o$qV3-bzJ14R_O>2ErvKn6(?Nnc8a;B`OCO` zujf^&ueuRbxc;m{n^|S(^AKaOE6C3w@+uHt+{tfhQdgaQ2`noSgO~e~_$+`)3mchO z_Wi5{7Fk7=GhMZPS^AOf9Ay<0VAU5uoPko$8sagwAAP6E9>v=e;ij%qS1w{C=grWp zp~wrY3Mc~@pn2BZNzC3%arl6I&OH><=h70B;ikRxOB=50l4qF+r~-0Lfqmu^HjPB` zT&*=-K~?$FwHQ-or@ZPPLRR4bA%tf_$r3%^1o?afH3bFv=}e}(l+>Qj0|l5@|1Qmv zOAD|2VQ(9rBNDLIKk{>_XUtS-***d~J0|m9w94EwhXEHf6dY(G>dS>W`n!xNd1Vcsj{>!;&eV-Ss%1#n zIoIWK^~*f)ZmqM9L>ME#^>Vc~e%G##{vj`tMRX4b)B*MVq+jNIwC{QwI70q>b86Q; zxwew(pUe1IY!rmykcRR3gV@?UXizMRNj9zq<@q-LL}eNm=Gg2i>inh;E$IK&T8*&D zWH`}|{ExENNl~*@0ukTH-t(f;0Zi&gQY76u+pWq*{p5Z%rPO3M4&86$m=g6z=QWn_ zaz1bJA_;)&a!+ohdH2DNhYVYsil%iHa>TTS+b?w;YK|-wS1fZ*NSRh0TdDcqgY5xu*QdpXuh?f79~}M<+k@J&c-eB@4^!% z)U0b%Aq-yNW?f7B^6=HN;kfC|aMRE%(MsTJ4wOHhQZUI5laMlE?5~oZ<*paH-Y1Uwc{dQyjDC@9=G&ZxnOV3kqmH(+4R70w zvE$jl^a6z(HZcCt%W@`7WVKI=uAfuIN^1r#XK6XyGqK>n^**?N#5lloi68u_vB72K zG1zEEoa*&_=q z5pkTthfsJCu|l8ZY8Kt>5wR1bM7u^wxviK?+D@8r|EDizK)%rb*qt&t!w|GH+1d~h zCATF$WW;94sQ9aY1v7X#8vOtCFHiS&CCbVwd*R~Eep!?~7IOyo++S@u2|Flt|2yBi zckjgD24iduMP_DIv9JMsE&Qi1I{^o!ynoAz1~y5X2w5(P#Tw$vJ_q&1hPvFoQ2lc| zzViaR{@1pnJM7qEcsm|YlGto|8m8}EtfLh1I|KNbMhOw3V=`kzST znMS$Nm@eOkl0S7+wR6v9Om-F2{E0zS0qb915dGCGzbO5IikMAKPh#~_2k#EX&Am0E z^>ZK&Ac2=-EnoZ*vJ2<}YW*WXEeow(kAYc~e62P#o2IGhQTvZ?g;IFk9Vv$O{__~_ zoj4HALf4v|_xi#96dVAMP+Dy%r{N_IF2Xr=hC_Mnhavn+ysh{SjP2q6U& zotbWWH2A7L7bg@mCAnSNQAL|#rs%JMSp=<%y!_7|igyoZA#_6oVCYWkski=H3j-mUoWN3UmOLz52K8 z9Uh*w)qxoIOyO~5jm=J_y53_Q{eKF?g6fVO{kPDAhrpt&yj`0?46rWwibDvW&u}6+ zXy58t@B)Q^A0qjWU&;wiYpL`uLlHPyTAJOZkGvo_`eCp-ZTTOozDYn7Rl!lePRh;zT6u_-_(CHAR+Uoz}`+3nUxOWj6WVG{3b5L zq5h$=A=E>duT!z^NS#o>W*vE@DRkbS$YRb!Q=5gjC~=+JiGc#Cn_~3H)Y_>?+niO7 zFD`jyk*eDwji#-K{h(xer&l3I~UzxGQR(m;xP{1nu%%dzRd`JDnan6MB4mD@Pyl?>nXK za?5Y8qRT_Z)rNAr44qG%7NW48_6`qq3T|>$=eC?j@Gv4JogBGu$gkvm@_il$oWZ>D zk&0)$RbmQj-nyRGq}&g2b(ztv>o`1@|7|7=*wIA zk>DQcGyk7W444F`-TaemUiWK3^(|9Rw}DT#z3f>R{O__zB%N)?q&lcj*z^s^9*GHa zQz)kwuJ>6=q{x8mJdB4Uq5mv7mS#A0kW80%5& zr80kB@?D#=SA-`JKXLP67Nuu+>E_%I9YsG9%lqY|3`WS;U;Xqh)1a%OIqsU(-#<7A z{J0fy6oI4 zifA1KJ5gMauvG6(Okj~L?!mGZZ#ER%$7}gOS>Vg&`g5NI9Ad1#gWrH&KTqh*3>Im| ztgkTNhTch%i7=9vpEO1~zrmhug6*Ah@8Px6DOlb8ynX&IffD6zgzzfdA*#9Vg1k9F zwK*aF&K_RHVv9;U=POqrC^r(gwkgZeNN;(f%fCFDgW6mxQm16t=jr{2{hf_Fwt@WW zD1H4713T8q+j5l{^Jn($Br*FNL7kcuojbL&+R|gPEL^8ti{B%*7xqF5?L^*!$L+^_ zO%_x6?jV~U`K+r>&Ec=-zXXzp!OD*oYXa|&?z`bf`-^9X`-(=yZ~7Atda-W!*gfxD z&wL@0H@1Q~&5xzl{ZU5G>43HFYqX#w=6~TQibDA<__w!~zhoO?P{>1y5yg2)zSkFx zB-0}rdGw?+1^W49)=Y~BThtV}rm;(d3Ch5jY#f&=oEjy@k;=w?3h&3WoSggTY5*kL z6aJBvHRjEHEN_G(Q?Xl*i1K5JoVz?>@6sfMqPZTlb?JtW3mru^wqR^VLn*J|TwyI+ zRatqY3X%=F%lg8|V<;p7@pzNC5;TmvX4|U@gVn?7pG`d3ZuVgVNZ(_QBDG4{TC@2? zOx76JdiAG328DZTgqmmWsZnII=Kc+pkQ_EO`K0|64-qs&^>a8 zKSi#qxLptqU|!(Ayv52!ZX6M2SFaUENnJH-DRp?Ytcsw;_V)K)UhRtQ!dN6BUHpx# z@dG`(FU=07frVT0Q$Y2I|AM+Ze5m?xQW)G&5%-FByVj9Ur@FiIT$HmND|ymHamnCt zQtPDhnyLuF&uJW6(kJfj7DwWRCabSK?>x z!lZncjH++Is}Lk7%HN?=L29Gm-`(gKUApPxkCI?j2Y9(Kg#Xgza;A(d0(cyh892KP zhfJQKTTSAmPAOGh2l+KyGz)1+p8kw=RPNREygIICndcyp5^@5GvEw5@b@ z#ar2%7M4xT)Qp6QcC*vo@rZV zaGs@&U5*XR3(8^JtI@NSY}RJwHxrdalC6~#l(HFKva>P|MJoHPO$Cjvt&jngNUeFk zGgmLGqmW2(rM2(d1cMgI_s6wok-Tbl#ZRB^a`1kV-^Rw3E1+h*e)(V6UyvF7jJ_cT zRGrFdDnE{woim)1=U%F_YR(hr)L?9N=d+kzsI}cqnI!Uz@T|eZOs2r4p)3mNXpNaX zRMV1dhW`0ySWcL3O89f{ShB`A%mh5I0g%G z6m3LSnhRBpM+aQ>OYSOI;ttFr|H8*z|7Ma{NDrqL|4}x2P~ZJ!4kU>QDxaORKFOwj zbCwjh*dC|v^5RSv&2%Rw+KI#b(806kQ{yln3bfP>$Ba@uV(4T7C3W$zy|wFAK?X~# zm`*3`CU=MsEl@umxE?Gb%k#{iB|-+)3$j)WVxb-+?ApiMycMa)nx`3A%O3+Bi*gM9};B<=8{<_(-`|K+wK%CXw94YwI;gAuQ>TVZI|i}R990&*G=I6 zr65@t32h3Cp1#KwWkp0*jFnohUqMrWOvF3`H(zsEE*ou&WOze8jRVwuamYDOLwH)g z6&JVP;g1cmxJ(qc$qsKxI_bMIsUEA!YJaB~ddgxkg2^UtZob>%yQ~x9dcX$hLMyts zS-HRclKbj~O8`WV6_LwW7`HDjjzXE=?)a!}dDK{F_^Ml&1Ystl=XPf9E<m#)JC#1$+oNf8n$wl-)Qkx$KN}>b?_+hc3fr+! z;5k+@S9d#6UCjn+q|XtTY}$eTuA(n9XHn`oVLj2^yI;rXw86pwaodRitt2FUc3VuGJoHTh11E;aV^9TgOR==I2RNg#A1FVbRM9_`m#$D&Lp^<(Ca;Wi?$$p@p!cfzVPRoY2_|Q6TRlo3dOYz{(6B6Yt>Yj)nu{!L+4`)K zc_67EEWub{8R#l`*1-oO{+JM<-01Wj#ePIywg_@`7B~1%yS)|n-od3*M=uqKHAB*| z{aTv6eW6n&PWLbrg4l}cB6&B^q4+*SA~|zIc4!ewu8v?x*g}=$DQ75)6Qn`cR9RBm z`Ux(G5|vNWS^5)GTMM-%+qeu_oG(wBc3yj)6uK-$G3?;)_r^z6?bw8lMXZlXM5sJ; zW}0c8O*TuDDzA4nWJw}b$P~nzM==iHyIgJ1(~U&Z$7SrSHpvtTyR+kQsDBep9JWtF zYYE8`v@`sY&QhR6W(Xl&TZ^MxxWfy=uzzj?=DcmJK*FuHr=eS-x8bTt?;j&cu>l%j zoLV(3mLf;)xKmW12bGs#wWu02kNn}fH&*h+PkHURQa_SqAhsV0M1h`LJ9h3n>gI3J z6i2KVB^Jz{hy(o8@evufZ`pU5du~8KK7cPKu>0r^zBaksvVo3%>z<~5uuq8&--Yzo zSbz~|QLa(Sqig~PKr??^M_XW4*7V6Tqqxn( z-{T!&WOuK|;H3I-Tks}+D{~9E zY`^5sUCJgv9v4CBHBCA$Em= zZMkDoWKE?=q0?s#4ve6V>jW0qd_A`t`b;YzDr*55TnCp8uwsI z^7Nvj1*%EpKg!7;Ho@2oV>znn3FPZ%+=8AA-QVvP=%+h~cFn7C#{EqO>i8}mvfaJi zksvZcv!fLS93zjh4=I!|C0ctAQurAjUENsgI&X=QAQ$sZC}C3c3}C+IPWm2_vvq1C z#*uiSDsuTVsjRD%Ji0#{t4@OU>B$;+av{yEL>c6~5_boq(m zr6_noe~U>|)i-=dFNsjpib5hlL?~kPz){}LIR!uBNRz!=acX^<0mWp_Pih(dq{HSf zY)_*JE|(3XdK+zvRaI(h3NM@d=~$h;54}`<*@+&dU6s`6Gu#k{7r2*vENipVcH2=x zn)RJ66(*uR@(v>jN2v{nTrhkkJT|);m}5M*nb^T+?gX!kwl_3fRYe~!uv2}9Q)lNw z=o2W5zcCr+5SSer?Pn_XCe4pjV{czxB>LzG265&lbHnK#z+iyR$ObahQV=}XM`4f< zz-z;OR5$0RTdVrAHrzKYq|~ob!!7A>1NkRp$S%*%Rr&#szp&M7*mk!V!oI!0jQ+dK zM~Aw(IK@fZYjSCR$m{?I`wTUqXQBy6l;5@TXgwYq!_?a1L`puatayw+g^l;jQ3%hl zpKHh-^}e1lDK{B2O^7bPBCCn1kr;nk%sq@%8B7BIOZpf zFL|^}lal^Z<9qs$ht(T__rq=^^G zVH142?TD^f#%(#e)WLptp=5_$hyyuZw{c3KdiS1j!_b_iw_l9!EBc?6Wh0As{-2 z+2`v~0)m6M)32bwM`Rev6olsX~(??aafa_wVAkxYQIo%)K$QwFH#tyRM(? zED7nTW{34>ua?QWVn@J>oM?o<#85JW02>zTd{a#%2Db|-(Bf35jzJ0aqsES>AH3b) zJdJDwZspx%i&F(kSdcIOXBh@6llpk%EqPLoQl38-`j&yb%Gil;;8H>3a*l!I{M6+Z zIrQT%V-9s{5t(zHiEH0B@1-GT&)Z8>gj0js;^N*3u(vDQjDOIb#M1)qnR^qq@qP4} zzyrt4Llc*`^9M2hICAt>AV)YIe6qCP#fwNd4VlgldZg3GTDYvz^R*WjAJi&r_G8+Y z&gwJ{jB11xzgUD{J{GlY>Je94j-Af0bibt4*685$;yCvN+Dg{gZu{9%8f_>$O>XG8 zf@`VWmzWYvto)c(oUR<^dp1u6$Z$HNll@v6aDftM;gNrPx@+sK%Qjz~?>Y-{Ky9?z z)oE!M`Nf%I^1WZf{X51d@)gJYqph_y%}0>@usE3WVme0P%=Y`WFY7yyGtp)?5l1QA zA9)tZ=MubQ_w)wqfiw|EJ7o*?q;p=s_6l)v&}T|&` zK?^*oM9MELEa)q68}@*=yKmjMu8`kpBPJTI(%mgJ*VosJ8xxvNxs$8(sIc{y{Qg=a zy@t12{JHERoMZ2?nkAFYTHTY`rG%%Ox9(6GgxJ=`PZa{4I5|iFTZ_k<;;)F>I80e3 z3}5TvDL=WEI|*J$vED{Ly}k@IaDXNKIg}nTb*qg{d)m~0H1ZoEpm+^Nq*!;DaD=kAUVsl*jVz3UgvtS~QKhjHY$k?k6LLD|WzNd^%K`+~YxY z$swH!Uc2B>PaPud!Q-x5dZmX~T)_X;A!x|EV0h~>29KZE78-G--0WV2^84vMJ$LN* z4%%73;|!wIgSwsn8ZhW+MsfGSPg$PX^B;nv)VM8Wfel^{G~SZ@Z~+1z##qhyl(XF}d{J_Jte~pnMsItq^wEy0lA`iklwGsowN32p z<5Qc(x+5QhfUMo#}f;l)?Ze`Ihvt4 zk2TXKnaAbfB69oEIrKUUWPZ%eP<$AOJ@Dk|1gF}8L>=-8pC_R_p3GOqH%;fNq2$}1 zwH%GSnSK&Lx*V1Q0-XV25?l76JHY1^n&*Y6yygw}JlmM%WFvas-AgJZ*hSpufQuupNZ(67HZ&Ens&>VFwTHAi-0x||CD?d>V$8+gV*och5`(-mZ zHFdQ?SG`cre62LbiWhl0qe};LC^se&ZS~i3#@*U9%q4E&WII1Q`^lO#c@p7n;J3D0 z&w>_Uvldh8nsI|aPc+HttnjP0NcSNUFIGz=`>76@J#Fe`=V_)7^UxAbtgh7geUSPw zoHdoP1!3woIDCr`lI^?9$aV#Xnzj39=*(zUG+_{vU0qj1bov0)sCX$K4L!1`@e77$ zGh$|HVCPn1C~XZV4~DjPy!TQg^7eB%_h%z4%{VqE4g^5nbOoDuo29vKTiTC>6=t}O zqz-kN2iQSXz(Co&O;fn}afN-NLY{)L?AN`uQ^7SG>9SX}KLWt&cNS@t*AUEwwg(XuDcnI4@q(FynB)HtZR=AT`CP zFU-Yz66zaG?#$>mUT<~INW(XeutFO@yfZ6xpZYU3_fm)tQ{ptnH0kS}A|jvzZS1 zgSIIlAK{#Pju|z3t5i%KTV{zQx6k___S-q2Aqv5+W5{0Hccj4KqK0iPf~xB3$=R4p zk1(FgmQTNBC?EOc4qp(&uRS`dr(MLVvRM6|)NSEA;k_a7xS`1(z3qjU-y^iRHm^sI z)PBL^fNT7lJo|wI`lQ9+8m}Rv_8XvDV6+RxQ*F;BKVeUi(u@e-R+&C}dpo1kbwGUA zKy=!b$f7*@<3Zc*H5j{o$@?4Ix^*k(=HTq$CURr9Lv&r>70&ya#Z@0aaq9yo@{19Z zY04t58I<;m(j9(vH+SE{cU2zC8czr-lfa*ixUY3KU!a1xNF}E2exrhDr9T@ zoZje$Kp->U-Uaz8JZYE=0^>atnHv4kt8`nJiyn=&N)i4w71Ypm5#Hxq(35E<#&IB9 zn*p;kJ|guat$LP5EG32C#_A@1eTDVbuVDqg41euK*5eE8+%CJl=|Wvo`-y@qXsm;z z;Tes96| zspIc6`;2OBfueS4dtdIYXK={FoDjvifakmhC*t03pPReoOe-r$qP)3^GM;uU1(zb9 zUi0Zwz`6+i9~Oah`zI`WmY}A%&mkd0uBf$I1;@9iB#IM`yN)Y{4N~#Zm=rmEuyQA&_Qvo(uGd?TO4hmtmwfmy#>Lh%baF$8usS{UBN97*g| zjb?26F|ht8lyFg*bEtvEOMu1o{Cef~dV{su$zDne$!ej#uk`>?ca;+^S0Y|<5+_UWO2OOm zDPj4Mku$Pq-4MA>_E|>Gbd_q*L!pW2wD(fSP4Ak46nFTGij9*NjFYr{!tk;(Me z*c@dTN~`B8dGes^c)1nJV6>hxc|rQ1ZOCV%b`>%7qhR2r4x|bgizAXQ`?L6Ob#zLP z)h}7!6$^zzYa|czU`v0EODfj$Cre}0HP^wHCqR%BksUV&-Izucb8F4Wx7Asd&^)MT zj=kTp+UivDDgGp=oQ_mYlSt zpvtCUzPfk8LrpTH@uI!ms*Jw^eq9h{q3(tp~b;#$HVBreG6Mn9LcY5w#C*Esz+Ab zVhlbU%6zQ7ltR)w- z+K=AKA9dmmi&A)X!9xp2-DmE12-u?`Ryf=Od_VV$Vx5-yV^f$Zv_Kk+D%hS%9G)7+ zC-7RjiIj^+88UP6jhi~2=(0s|##s=O(3b-vzJVBt-w3l{f(^mG^sF(eovX5LK8jrD zt2LSDEkazrj$<;iYCJoV9Ahu^KgD+~p1g#ig#78^u-h&-oB(q`NLo0|9W~vGu$!fw zHd{0keVM=&_puJnJC=D|s>@ae^g;d{S;iSq5+Mi6Hxb!$x`9PryZM9z{tzD2EO@b8 zmtU{Tt{P28a~Phi@(>FxcGWX0Na~c2_GH94@y_amnznOFOnt-9lsV3^SB!yv>hjHZ z^9MM&U)8UTO&PD;X25T^S)ORLy$PDlwlj+tWYSv>-r610^Uu2<;0Iy+0qsq0X5j%9 zDcjA&uMru{Ohcs1PMsk$7GM-9Hi21mX2A03!EhxXW2&Tg)VkUMRNan1)vf&zrnY5O zy+*1_C<0-*>OPk@+BE00Dm=}Sf^ZT;>%zScQ}_=PfgMlC_>KACaS?~F~%k1-2Ehap4wRiCT}Nv=P=l_uo}qcYeLRF({bnG_pEt39gVP0(tA_#J;Q=<>no79XFOwroK_~JD2j&% z{fRhm|8(k*6lbz}ak>&P<<^>+G_OO_E#EFPXRPh*Lw~n_o?jWMjd03k94JLvP8@wm z;Zm@YcV}l8+MbkysXdF&d{JWxQrYJn$@nPkPO7H_#F6;VrEs_foIqP5MAglHa%y6| zxDD?#@guF;eZE^ypZ#z@wcP?Uj5QGqWp5aegZbnQ*KNRVPJF4jUBkxd(z`qdU%K2L zw`oJ4AQ{dO;=0pwFi}8SHj7Jy200DGevKd?C_8+Ab3z=n)41&v?b`fHvg0=?;&k5E z)80H;v>v|Z#pPRjkgrE92CFE&H36wx(n=!?#)Pe2*PMUAq3*N7vA6Ih`Cx0|h8jn& z;VRWG&%^glJ$U(4Us9oDMmPMD89A7i4DMd6QpxL+b^Sl>(1!H{!7)KUf=JaWq3uOY;Cs5 zx&F;T7ohXuAAfcJ2lx1eMRm^t)L~Ne~YdG_Rl0*(ae7m-0s+j6}ZQ{5GWpb|08h9HqgWwj`f{ ze{r4jMf416CS_e@xx4V?(LWjH)oymd4N@XF;dQ5*Koe!0GH)!|BH z)z6Pw)Q`jidbnMCke-9ZwvSzTpO=w_K}bSkW3OS|1s#|<{z%=Zc2SMg%Bud19*hCl z2fEndz6Qxuq<0&1nEZ!Yjn1OZjp=>bbrF+jJ#uv+qtq;{_~V8Tx&C?g2e7;KO|vWK zz98A_KxbF+**ZVQt6;FDt;mmk^a7;D%XJJ}Tia@}N|n!O@3+j}3!i`hW1hCi8`uscx075f!Mk>_-$&C?CsCcPbwt>@3$fC|zhG~5ubS&< z)T6x)n@ot;cQph-CAM__8Cf&j2c<||4Q(P;c1Id)yaQiKX7gT05;>;vsJnmU_%-$u z7nm`ns8w`~@OiF$Y`b#+kih}_>oT}pmLth<+eRJ0_P>%ES6eci{X(3FJ0NCIJl3E# zeV&?Cjf6mg}$DY))bPk1CPr`Pxy|!*DAJr&VE;6Uy45Q3f@l&XgREr|5gXXc;t4t|X>iF7c{#aY_BFDaFTUqeEpz zd77;RE>MGZutCe+8!90< z6L|EFsXg9@6v(*cFE49zfO7{uD4~J}CB6wmR_m0ex+7UK#m1ztwl=_^ie4ODd=_Of z?V@cG_Je>YggXDycDODlyQ5FlGv-@W4s9cCO{iUJn$@3OIxgmC8ZjuigsodXep(0_ zL68gaX3yyf|FbKA@Qq~hi-hovM51wXB+BHFV*^PKQovPBBSWReDP^;;!3=4gw0dw7 zUyL7_{0QIaGSZ~~OXHmHs2z(5qmBD^J>aYrzm!*$LAzKtS!OD88z;2HdhZH}Y<7YojNNwTpeixKv1=RRoyjaUl(Fs-od= z%>Sx*#=pQyKE6p3IollFnwnp?ysr90M`z(F=8oYvXnUu>wPTP^czM<{KhIxIqgJ^U zxbAGnR{$73)U)9O6G}HEm>BWxK(Fk!GNaJ@Ny)k$`ZLFdwl?3fB9pVbvs0sfSLpQu zn#ZQ^mpM6b0L~`b$x%GTb(_(Q&`g2Ytmu)-YY*OJ1sYht@1nl_8eE{Z zk5(t0_O@=xjow$Fp9YP$qCMQ|2mj1Gt&?Naa|n%Z(|sB7cKPy5Vl9*s@>(r!y>IZ3 zCMiajm*HXRogBSGO}%Xl34eu9OtAOcjQXC1Y$1A@Ii&Uw;D-qwUIHD^j%=pamjGs;AwNn?R24_Yv@pEZd#?7@xHa&ahok9XE+uCw+oKu1$~k=iJ?0Tv|SEqInE@ zAJgeSwm>M#BAmz8-5iv(tXE#8SwmgGZJOW$yj@9qZl(4 zi!CxKI%6!HPn6otJr@rl>|i@nO~#NhPV$$+wcLa!i&!OG0KH=oJOD8PGwUI|bf|lX zsC{_hT2LMHxpWPw&Y$wCT>b!p$ci>w`}}eQ$W{gAv@Iyw1l!%L{`#7RP=O*&Rg9N^mtE;l6P0pgIydXn0jSSkr zJClMq>aP))MogG@FPb+?x0jux*89w#c}D>PJxTWo$jQ;aF{NJ>cv)eR?W&8bc@%i@ zhqP4?X()qDgZlD8gL&y^>bTh~U=k3B-6Ra_dhLQWqVcP3r3tW}6B=+WXD#!VYI@UR|hE4A{XKS2NOLM~8=8 z3OW!)9}v4E<)2*{1CWM0-E^Lq_M5UizZkJ0P&`X(R<8~~E?{q9-C9;+ZB5D*s9e;2 zeILMF+}z%PLB^K>CHm~pl|ttERDN2l88lPS3LRPcdy?+pEF}5R7n!6mnPWbujMVW> zGCS^yqgDoea#Ntu!SyrGOzNv*7UX>Cd^Ia-1g{7YOFwVx10nM;R1k8{2Lvx@V?zLC z5YEeRjH2$kbw1gy1e${ZF!LI~?1`tGwbQh!BM8??sn26a_ao@JH^s&6%7OG_^X!X5GTwtN0XMCc zX1@>@ufDDB56fqGbEW&TrTv7)O9Zyy^u=e8eTKugtpo?61?5bEgy#&; znjstB0Xm#H%7g$q9(Zd8s!W@sk?qlU-k0*r+yMC$4_)y@P#il?vBg4}ciks_z}w=1Be8l=_goC}mC#8ND6( zp4{l(N-N09>e;b)??TLR#6})bQoOr_t%ZLnjn#35jPG21xXTmG7;^?dlH*B?IsSVP z=#glIOM4Knzzy&&ObH^Q>`$y9NUAv{r8VT`_k}I!IWW#~rdb*--JM&tu9Ry-QzyqN z*7M6O+tA-wehyo1TiBouyb}J^UJQ&h9r;w%bntYh7Z){p#pCz{Iw{^nh6urp5Xx#i zb$MKVdru<(v>E-)DbVl2W4{-itpJmDW!Ny5mI|M25#c_@gUp@uzLym$ZC&(fcmLPZ zRmVl~eeG3gl#o^g1nCgz1_420Dd}zy>COc~Nt6l-XqKv6tc zzQLw$7ikD}>z0=hg8+!Wt0=MNIe6ywmG=&xPrjNhP@B>+pa?6^%QJH~{X0X#pm3;( z-mS`(qsw}J5~GUWvA4CAFPiOL zfn-EvX|ev9Dz9!UZpLMK-mK}X_KkQ0SBl zj%}6@-Q+W7ZuM})1f{AtBF?EJV2y^ZDWMXHh1&g@T4Ta+x$nmfYHe+8!=*ecIk|*P z)RMn2Z;u-w@iXQx672Z8o;DyI@y8F)1%eE?&wwM%9ywC(^%?)On9Y)wf`IGjkvB za2fSF2k%Oji-?F!Z8_fU#|D^X-i-g=ZFAZ3`K>z7q>G<`-`i(q0;RMvLAwnBEbcLe zLRt<+r$U)-1*~aeNt08?vipR`c*bJ}IvW}6DiWoYl|!(Ft8cbE9@MMunCP>ugp(MX z=(f(g9ZubYn)*2Ks#gAl8V7?-$H9`tDFi4HAqsySgaUlbUoGV6_CW_2-`w_Ct$A%q z+19E3MynY1pa-aKKZ6C zd&Q^osPnYQE(SB2RA#Sd%yFps2Mx=^Ndn3ce#W8p9**sjZu?_GS6bsSMCwSz*v$Z% z{~JI@%cFk-c#NUGZ7^VRrEx8O+0Ow$I6n=m3|YO@XKAn0(#ya<9$*?cQv&d~gh?L1 zI?t+kgmZWy*%tz(&9s!+>Jo%1)Wa2`s9)s(v{Roa+DCThaBZN&LQ?UH;Uw|8l{a45 zn3Q)Yhtv&bK%AQxP9)TKO#7aD&;}rGvQ&pNJ*E@8Q|cYn?N?4X&d*|G_Hw|4A^FHd zWyebqpZAd!(Pds+8>Ahefb%Q9lgY8=LF4+|^$hptdE{|&ms{5Xws74SE=)Y0*+-R8 zV%F~+GsD$2bppS>?UzDu<1kS_ul)A>S#(qvKB|-c)PlO z(?{WZ_O2liP6`>g-+L6>4e;@r`Eaf1+Nc+6o0uP=wf&^Qc4 zr%_@!IwA#l44y_7JhPFiN(g4viebx4t^zhHlKi`q3l6989KA(KSVOQJ+3Nrn+JFc$Q+tf)WV=tT^<><0> zwNWY+<2lSGo0L{=JN?Ud>U+`3toiHj4SJ5wUr&M;X}bV0(WC92k4pUfI4X_HXn#nS z|JPo0I&o}lB|a7*Su`zc;M=;slyR3jSqGK{Dy3%xJ2{~^pl@}+NHi;fk>IF;CWwQ% z*u0++eJKL0M#}dv-bLKq(t4p1cI3+|5)@rv%@|yQF)$^^Om11AtVK`GcdgtUO0**k zyLgC;e)X5OXJ;CTb*k+Jt#{=gogWc9p7C>a`#Tx1H9RSaiaF62oN`$Gm~h7+b42un z^LiL<2e9S|qiYG{o+k*SQdw971*Dz4tQttD-hWDcOEZ_;SO41)3uIaf3{hkE-w+p= zUoYtXC=4uZj_vRU5Y5C56|iVsQK)z%w;>j+5cRGkSiKRNZ{%#LHS5;nqKyiyuy|{O^peJ0K9QWAA$KIU|ZK0f4 z)8(zik(N0QgcCfQ&aufGxsJ&EeTrQS#W z@y=x>vNg{PG~P>HqX3UCEILmR3DVfsR)heEqZS~~2ExMch&0Cm3p@ZeLwt;e)`@YC z=oA}%mcnttoZFd{lrzb-rRABu)A*_7_F~8h}+|F^UahvDx}i3 zwN}74_sbJqdQ`Fmv;}fYt8N=z?oG$QNBstPYsIyukkMQKnkXMA>ER}Mv^ri^V*T1C zP2P!rd;vC6HvHqw)T(S|G!r3ijuA{kLB<;}{zKG+V(4S97f%Z0zgSH_pP~Q2 z43c4vSllFTgq7ZK!CDjF+#tJ%$HlUFujqvRusuBawl>L!(N8J&*H-xj1XT$zf=k$0 zj^e-kPLvkN(pJOA!l~QZ90iIRthA6-e_m z%jTqbuBA5}byx1EkE7i}#nXr}MA4!}R$9tJ#k~-ld4XV(p)>51)=qT#O?epgjW}}@ z7j+)M-*ikIJ(~7n{KDckdqx2YiUpjoS2*A>>|eOwa^3MW2-vN81E&xX86RPTm~kIq z)eFxDwe@spmQAP?3dzacI9~w^pbKV{D?lnSI!PZ4nav*XA0N0!bDri94&Zw~UpfCt z8P>U>$oNbI(p#)}!{jq^o0}kErWZO#M@N3E$xlF~?l>xj8tQqG4jIP_f3m3;h=8{T z%}CFfa9Q$J0v#(d+`cbZ>d8Ou%A}%d)X^3B_5jXH9<_^@nmRTK^$;&$qLfH7Y?+hA zfftLXpamS$?ozhgL`rL&X)!S|8`yF&B62j)Y_8bK;_baC;#~>zi!LW3YwmkNc;U-k zm^k2meBh1AeI)(+q(I2xagwJ9csM{~k=W(vrntHD6XrMIq1{Y3rRK+`ihmdBEU|!O5ast}s)y zjp&(FHfawYvH?Y7CpJq1ec=s!Aa!kswrkV4vc*P%xkZ4A_gkGCFG0!20TcvusL)`- z0Z#x9)R%0!7wxUh=M#3NmQJX#!LoxFF4EK!xv?u?sZ!!5HPO zw;t-aym#?l)84`8QC&s#k0;;7Cj=Ej9@YN50^^QTZ5P@(rMNm535$U{NzcXoq&PnROPeGNG3rPn|gjmf18GL z62PEfAFhl56ey=Wi~E-``jILtOCR!@mYy~cnoAD)mJ8HN0mgpPonN?`gf;o{IPc7E zvSC@8Wyjf7ZuEI-tqV_O$&!)LGy5m=lKiWYz52!)x=q1fS_fL?Uj9|=4OW(iP2+%UlwzS|QSi{T!8-VPspU&GYm%m-a44YMFXJ?m41-aPo@VQ+FJqCG_^FsV`#|B15e26=0*INKKtd-HMd665}VPmc9tQuA=eQ51QV2m-O)$)ln<(mqneAiOy>&9 zR2l$+(64+RZVePovHNK&|&wh)i-eh{o^KWX=6 z%Ysw`N$4tK9IoW0PhK?>Gd;5AaDV@~?nglLldxq=BBFFn0l@Gt+p3n}tMhsgSh&Ob z;kAoi>G4o=zeeQKBo7aBOJxs>)*|Du1SSfhoHhCQ;@?weFN7-E8=4y1D0zpRh*#Ua z>Ij(k7OuhrKp;(04CZ?ues(NJ???-lL7TJ zDccoJK+(T7I*k7Od62Z6S~HHkbHx{0)EkP~Yy$`nJp2`ew{6#fk+CW5SX&&FR$$m6 z9MCazG%vmUF~QC>g^SMdqOWptAjX!WY3c!pTN6h`0!td;b$Q@HFxl9j8H0%QvGva-JeJXi*Ja406{h-?D%4Q0tZS<0351Rs8=@;c$i?Xqs!82qNK z3eFR}_qMJqd^!@*;|T225TYG{o*!AuA4V;8rtm@B_iF0;V(w0LXkwO|ttO zwFG$WFCcG1-b%ExB>dU+exm&4Gw>|aN9I7o1|6wi+F4s2JBw&bjD<%*&5k!@>Ko6n zxgK)ctELtg2Yi9~3l~&jc!f$^ZJfWViyl=DwUQ5~Y%Zy(anY8S50|XYHyw_2O&dwV z4DD~0j!3g+c+r+K?-87;Rbp3t)-F5jZLl_%FW49NoPYJs}`^r<*6v11%$vfDg^7N}qMvl2=wGmLR4##VIoG zT~-FgW2hMpeWB8`!gGmwdrK?-F#$~I*r8+PS4+yTsQVx`yx;@~4!Gg23#kBira8yoMUqKYkn;M3D5am7TN$&foQf&H*$q^#~7JE z#GXVJnVLWoF05>4P$@Z%3QnFv!%HBvMgZOeBj7#cEMQaTf7y9$hOsw0UwiBasG_Qw zkUtrnEZCuU)}aTI}dnnL&Jx3)&(isZG=e32HQk_wYp z%sAk0?+<`#9*`O+u_#7g?;`O1skK_M53YrIXX{xxf8Q&0c*UaFYDm-gaPH?0SK(}$ z-gBIKsg82G)@3az%$IjY*->gzQZ#txt+_ZXgsk-O0UwHH!Dnjs%R z3iclHj+67PvC)>Stf|q)G&J66T?nl_r5^r`51H;R6G;m5X^__2DAOu;?!g5mCVspR zO!>ECz;aUb8swc)zbRSMQJvTuiNkM>pB35N{-;Kc}ei5!}DW6 zuSv-$G7m7fttm5^f%P+b;I~Bc3j%4EQuUm9oXxT6jzrLI0F3G*(0nD|g{diLj$c|10Vvvl-01#U+ljc`ScOZ8~pmi!t*|H;v-$YB=^U87Cr zVg-_XAXnJ`%f4FU8^)9MZfX(N_UGh*)gX|}8}$waCtGP8@JFcK%MB_y@X_Q&2S0cZ zx_VXCoRhaH0X+^!9jbc~15@%jg(t02UQi(0kPMGA!D+VlOebxKbI{ARIgmd}6-U3H za+YT2EETI)xSliav<~~6OB86mWv|zs>=pYHp#)8vwH!&#fG=W)rA6saK`Wt}8csSL z0(CF0TzJ<;sYR4A&Mu#U5=%bf0#YE&!2_?YJDPVr82A4u`E^|v&;ue_AUM#W|8$5c z_xG#+kIS-w2n1>4Zi!pp8c(|&c?Mlmmd|103$B?a9M=!!I9kDagH+>@b{>%(OJl^PJ{AB%FLJ^f;zc*$))D?c?oJz~(} z{RfM42y@=B+H(+vCa69JwkBOG+Dtk=);7XWrb}Q&N`33QbC%@F%`dZfv@(|P#DdSq zlEqzc!{3uA@Vu2iVV1OE)d6*witN~fb)X$ku*e@9Jx8Y3@23R4!ac+pJZtuh6E!kc zE&CH$Cszr@4n7)XQoUg2EAzCI;W$P&y8G6|R$|U64~Pt|^(d=)a@oGw>toJ2v0MU{ ziP}^Lu5`l6{9D^GLSWaxNPUz!648BCH^-e5M<}^&V&$1n4KktIznE!H?`DX&q6;rJ z#$bM!AuOu3F2wd~}sBkqM+56m@8 zy93wxxREo};Mc+O0DL)oWYez}opWpuWkv0STah@*0QMUY$G7Cd@pq3own;-C3!|1% z30W4?{9Wcs!KWEcFZX1kPr+-W7u=bn4X&mc156J`ylbv=p>-9lk2%hpqJIDt!ehnX z(Fx8%V)3yv+w=D>Hj3f0PNy?2%>C0>!VXYUF0xtNhKjnkzD1}zDho$10d*vaVdX^SzRerzobT?YpJ{`}=ze3a!W{HX^ zUFAqzx_B(krq0<;j-Nle`FCn+N>IFv7-v*>=kp^+366b;^CH3S2Llne%!Bk+uEdOh z#^KlYjkM_nmj8_0x{Pm&^iGr5@79tQokb)a^*GJL)#nKXn6jU&FarW6X8(i zx_8x;zJ&=lHtdrEg^dY1q4%1fq=;Q9SsBR}7X#`X-L zPV@ajB%p^@2#p03UMRmDaPr=r)wFB471zgFJeAYV{i(-tPPROXZtOVVGhpip0?oI0 z?!r2IKb6!w)b(cgq0ep4(UGTLRwl1x!hbF+nh&y~$ajLIX^Q*fj$LrG9lt1AFodg4<~H)ZqCDo@tq z$i2g_SU~KO^vZe6&xc@`kF_lSKP{I+>gyZdpFd7>J^0Jw50mXZ04nyYNC>W~8EjiAvgX~7)%^hJpGG50B>O&kK=96T zmo{@5mAS(1`=7pRa;5omYza;GQCt>5CKC%1aWiKETo25#t%9Z&7hAYigan~vivBE3 zf)*EXrBAMxVi5CO#@T)DXKLeaX7kw{k%2jsO=6FrWfpx2ld&JT8?cyx$u#8|eC}(= zG)P4l&bjSGJl|#&MRej>sIe_x^}G4?GaeE9S-Zu2VTr`~?~RUa9pNHC+(N#&T{A* z+T>~NFi+j$d6Ba?U#rU91JUT*gae-#1H|$$OV>2XhE}r16*upp2!l05BxE9?ckRh6 zo(U&DNYTVJgrp+-jeo06x;It&-WCG_XS==zQfQGS_sB>U39 zYp#^hkl~YC+RizJMDmjnp-VRVSqj-F8~uiCN9S}Eioj-v>v|9nwsUTeKA;;>ohJG_ zkiF+{SS~%8jlo=;x37_9%OMbR|B&=Sk^B#e-?N#gv+B%k8WO!H9$rq(f$B_$AH$5p z3Qz2rd#X1wze^+=$rvm)&-MBO6Z`PT@`r0jgnI}BA1l)c*T^i@&6X==*A|xs{sSvk zz(;nn<@CGuY#IxfrX?#eEgeADKi3y&c!hKNWw-d%j}(>kJN4i{;_%a&aDmL##UV<# zXi>0mqb(!0rm`(rw3YZP0*%R8C5cuF5+#$}y|aGr2K{IqGIte%cd3$e*Xwk1X)>1B z)0&}W)t^NESOs@kaO4D5@Ml3(+)P9#{TdUj02FFhwC_V(J!@i+h{kA%$EixPtsctJafs zs9(!>Y12jYZt93sP8evKC4ht}G!h_|9IYvWh3;g@m7F zDV%wwE9G-;1)a|2g|YSyuXnM?aD+Pgf>bzO(vavn@nT`SM>&%(iSL8_yxutH!U)HZ z<>J^(NXdkiUgjZhXYx^_f0kiIa}J@!IWN5j)|A+IMSdwsVCZWO7fgfxzTKG_#AQoL zp7H*cP@Q#vG`Cxrf0LlnF;5il-oOQ8^OwBlck?ZDh8ozQTnr{5AaUqFAIb!|Uf(u> z9u)Qu9$-)N(cdVmcaz_Iid=XZVM@s7z>`Xr0;TVb2qx?c)l+RZoVl?+gU;lDiWa}% zJ>zE$Yf2&h1dnxpd0_$~sv@dagj`&&Z94E{rT#m9egLX+<=}4jLKKcDUE@AX+^Pc8I*PExi-wME{zIIp!Wf%bpY8?dRkwEpJ4(J8gro?_5dI$YI1@@tNb$naKV=2mE&FWlv~QJ-B;y@M#JA7 zud`=<)jMt8t;R&B9P%mIzCLR^a`m@6hmA$$xqV6qHmpUjN00@+cY&KoP**nRyx)4T z>?C%X%NhdC1xlrPab0v%gYCMn?4o1qJgZ z=^@2Tko$uCPez8y7*S@Gdl0q|-3%{;w*lMauXmFVaa0oR%Y>iC!bBX?WBXH(dGK>q z`a0+G-vOErM~-RyxKk93s+w^@LE>6tw{8&oub+jq-$_6?iBqyGzapMozp(iGfOcSt zkd}8(AJ+P#H$7xZbScs*tLtkX*NZXXC3#Gua@L$!pwBG3hgW`r*t&7%mJqKTE?ke3 zqN15rjeS#X;GNO@ux5h%HsI`;swUar`hjvxL=teeVx_r9EtJP=1duY^9|}?xk&{{+Dys;nsf*6pCk26EoD%)U=+sJVh!^b zS}dux8;fZM5Cnz-Nxpq0=`!))XIDgxy9vUpTVus`h|5HZKi}3H-fi?*xYRWg@Tm|q zv)f5L@LAwQcI|zxP9NFYE4h2wX0zHej;w*b@&fwahiHj(DBJ;@e*FJQQtsWm?F{vK zi5NUOSuYZhj`!r3QTJ}c9OaAd^*nY)6Yh)2|3k&%*_ z>r56ahj;+64phjy99fln@Uls~)-<5iWerewue(4j%t&?{?0~|VE`2*m&^{N+UJNo* zC!QLZQrO!L7@(H1bmd05ic_oT@mPQM{>>kMu$9}?7e$wv(q$5ro{h!n{oyXp2ha%$ z@N?WR6c~{s8}X4g?t%|V?NsvL#>8+k$V}?=g_{&V^m}e7*BGZ{;s9n`-*&_R`cr$*tNaAbqosAP~;l%^3kp>tU=URsKuv+rX4RpZ0k>jE&o&bR3P?^X8`P3tQ~boRKx_-`aYG6At9Kg3g+iG+*ZU{*ogvRkf^Ktj1r z+HbndN-aRNGurLUhmYJ(n?U=n+uPMK<@HK99In^d8{M4#0jFV(7*=nZ1(5+g?WY6i4hzpPYJwC#UpVx7L zbDuUBRy6i()4}H)VxWZDU=%fx#T{{}Wrw*RzHuEVs#yVd{q{p8*#1Pk0aXqroC0Pc zZW4h53Zfv&{Cj(Dz$->)~!$+R%xP9!*Vh>WtMf%3vl z{T_eF&1k|oDgLBscf%q9wP^na%o5P-{a^wvXnfwYiJKrXL^*U&&a~?8$4723m9A3# zx7_*#G|~deL|(H(u)2bWrUFkR5@LVn>`$nMNdmx1>;}B$rq4Y8J>p2X&|f# zvt`Y+AW*xO-OYrv87+$2=r`>#f!MmoLWimWHQu0PCc`*Ax;*3l_UN=nF^=d-yslH~iXTxU9T z<5kKhtsn+p)w^nsQ=CR0QBpiW%~T}xuIHgTJL?6|W?S)JHjtd`hW#)@4tpi0#Zd$) zNQ$*A7uc?Gznymtz(ql&vQ^t3Uq5rjnv7PHjJkNVOlYIEk_Xry28!p#EgdE4ZF+Hi z_VF3=_=0%z#~8xCIenBFOc4Q!i;~iiQwEx*npY4LBgUrZKVG6tA|jIzMn(hVRy@_- zhE4SmsB~&imRjh99Sqj)%&<6P8}?w8Xqvm&HD6U@KL%QPCZUG(khIg#ky~++#$*hx zbWij44A7ZIecuMU*n1X82a^CMah@btyt+Bubt2ui>hnI7n=~|uMWU)X)-?%;NIqwT z<24xr#lnI?^#TH>4#E{f<-#^PD_Y?oYEH_SxPr?^TYjpV-VdUdRGzNzSs&oM7rJwUluc+F|~O1D+7g-d|@hxw#F061a->!xu!NQx-&EkLu)>q8Vyy#le|HA;Eio)Z89y;Kjo zeU1^4&lWlcP}timIDhbV?wjLWY+?Zz^8f!F{qN@lukIMQ-@pIj#Pi&wZ$UfR-k(&c zGU%pnjQq_dWtwwWY*B7-Lg`+2%dpDHbK@M{TrVktZpTfd8$aT7d230jeWAU3FCc|km_~U;^ z`mlI0lHN?f%pIM@?6@ZRL!%`zc2F&HEKzsmNAIn+E?Mi)%eu From d44bd608f538adba98eab631add552e68cf06389 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 22 Sep 2023 12:18:47 +0300 Subject: [PATCH 07/40] Update README.md --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 6a85200b..1b16dadc 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -1,7 +1,7 @@ --- display_name: KasmVNC description: A modern open source VNC server -icon: ../.icons/kasm.png +icon: ../.icons/kasmvnc.svg maintainer_github: coder verified: true tags: [helper, ide, VNC] From 1ac4840b5d9accb19cec5448d088d36155343421 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 22 Sep 2023 12:19:35 +0300 Subject: [PATCH 08/40] Update main.tf --- kasmvnc/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 57023575..6fd0ba49 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -35,7 +35,7 @@ variable "version" { resource "coder_script" "kasm_vnc" { agent_id = var.agent_id display_name = "KasmVNC" - icon = "/icon/kasm.png" + icon = "/icon/kasmvnc.svg" script = templatefile("${path.module}/run.sh", { PORT : var.port, DESKTOP_ENVIRONMENT : var.desktop_environment, @@ -49,7 +49,7 @@ resource "coder_app" "kasm_vnc" { slug = "kasm-vnc" display_name = "kasmVNC" url = "http://localhost:${var.port}" - icon = "/icon/kasm.png" + icon = "/icon/kasmvnc.svg" subdomain = false share = "owner" } From 0fa43a7bfae8ef5ab94d5689a91bb5700199373b Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 16:28:52 +0300 Subject: [PATCH 09/40] `bun fmt` --- kasmvnc/run.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 7a59580b..875f3e9b 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,21 +1,21 @@ #!/usr/bin/env bash # Check if desktop enivronment is installed -if ! dpkg -s ${DESKTOP_ENVIRONMENT} &>/dev/null; then - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} +if ! dpkg -s ${DESKTOP_ENVIRONMENT} &> /dev/null; then + sudo apt-get update + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} else - echo "${DESKTOP_ENVIRONMENT} is already installed." + echo "${DESKTOP_ENVIRONMENT} is already installed." fi # Check if vncserver is installed -if ! dpkg -s kasmvncserver &>/dev/null; then - cd /tmp - wget https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_amd64.deb - sudo apt install -y ./kasmvncserver_focal_${VERSION}_amd64.deb - printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" +if ! dpkg -s kasmvncserver &> /dev/null; then + cd /tmp + wget https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_amd64.deb + sudo apt install -y ./kasmvncserver_focal_${VERSION}_amd64.deb + printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" else - echo "KasmVNC is already installed." + echo "KasmVNC is already installed." fi sudo addgroup $USER ssl-cert From 048cffbd2caa48f5e1b6abfa60d5fc11ccb2d3dc Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 16:33:54 +0300 Subject: [PATCH 10/40] bump version and fix typo --- kasmvnc/main.tf | 2 +- kasmvnc/run.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 6fd0ba49..75ef44aa 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -29,7 +29,7 @@ variable "desktop_environment" { variable "version" { type = string description = "Version of KasmVNC to install." - default = "1.2.0" + default = "1.3.1" } resource "coder_script" "kasm_vnc" { diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 875f3e9b..73bc3e84 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Check if desktop enivronment is installed +# Check if desktop environment is installed if ! dpkg -s ${DESKTOP_ENVIRONMENT} &> /dev/null; then sudo apt-get update DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} From 2318f31f94290b9d36751bcb2ebfd729c7f82802 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 16:42:11 +0300 Subject: [PATCH 11/40] update KasmVNC version to 1.0.15 in README.md files --- kasmvnc/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 29aec55b..0e0487b8 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -4,13 +4,15 @@ description: A modern open source VNC server icon: ../.icons/kasmvnc.svg maintainer_github: coder verified: true -tags: [helper, ide, VNC] +tags: [helper, vnc, desktop] --- # KasmVNC Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. +> **Note:** This module only works on debian-based workspaces. + ## Examples 1. Add latest version of KasmVNC with [`lxde`](https://www.lxde.org/) desktop environment: @@ -18,7 +20,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ```hcl module "kasmvnc" { source = "registry.coder.com/modules/kasmvnc/coder" - version = "1.0.0" + version = "1.0.15" agent_id = coder_agent.example.id } @@ -30,7 +32,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and module "kasmvnc" { source = "registry.coder.com/modules/kasmvnc/coder" agent_id = coder_agent.example.id - version = "1.0.0" + version = "1.0.15" desktop_environment = "mate" port = 6080 } From 6009778c31d087ee95eb0479613db83786e69c54 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 17:04:47 +0300 Subject: [PATCH 12/40] rename version to kasm_version --- kasmvnc/README.md | 27 ++++++++++++--------------- kasmvnc/main.tf | 4 ++-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 0e0487b8..5d00c72c 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -9,32 +9,29 @@ tags: [helper, vnc, desktop] # KasmVNC -Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. +Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. Add latest version of KasmVNC with [`lxde`](https://www.lxde.org/) desktop environment: + +```tf +module "kasmvnc" { + source = "registry.coder.com/modules/kasmvnc/coder" + version = "1.0.15" + agent_id = coder_agent.example.id +} +``` > **Note:** This module only works on debian-based workspaces. ## Examples -1. Add latest version of KasmVNC with [`lxde`](https://www.lxde.org/) desktop environment: - - ```hcl - module "kasmvnc" { - source = "registry.coder.com/modules/kasmvnc/coder" - version = "1.0.15" - agent_id = coder_agent.example.id - } - - ``` - -2. Add specific version of KasmVNC with [`mate`](https://mate-desktop.org/) desktop environment and custom port: +1. Add specific version of KasmVNC with [`mate`](https://mate-desktop.org/) desktop environment and custom port: - ```hcl + ```tf module "kasmvnc" { source = "registry.coder.com/modules/kasmvnc/coder" agent_id = coder_agent.example.id version = "1.0.15" + kasm_version = "1.3.1" desktop_environment = "mate" port = 6080 } - ``` diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 75ef44aa..b28cdff0 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -26,7 +26,7 @@ variable "desktop_environment" { default = "lxde" } -variable "version" { +variable "kasm_version" { type = string description = "Version of KasmVNC to install." default = "1.3.1" @@ -39,7 +39,7 @@ resource "coder_script" "kasm_vnc" { script = templatefile("${path.module}/run.sh", { PORT : var.port, DESKTOP_ENVIRONMENT : var.desktop_environment, - VERSION : var.version + VERSION : var.kasm_version }) run_on_start = true } From 3333d3a5908d92cddb230a0f09ab3a21709633fe Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 17:25:13 +0300 Subject: [PATCH 13/40] improve compatibility and cleanup --- kasmvnc/run.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 73bc3e84..e9b3b262 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -11,9 +11,12 @@ fi # Check if vncserver is installed if ! dpkg -s kasmvncserver &> /dev/null; then cd /tmp - wget https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_amd64.deb - sudo apt install -y ./kasmvncserver_focal_${VERSION}_amd64.deb + DISTRO=$(lsb_release -c -s) + ARCH=$(dpkg --print-architecture) + wget -q https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${DISTRO}_${VERSION}_$${ARCH}.deb + sudo apt-get install -y ./kasvncserver_*.deb printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" + rm ./kasvncserver_*.deb else echo "KasmVNC is already installed." fi From d6e6cb3e38da9626d4ea75d2d87c8f49f901e829 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 17:27:28 +0300 Subject: [PATCH 14/40] update README.md --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 5d00c72c..1de4a919 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -19,7 +19,7 @@ module "kasmvnc" { } ``` -> **Note:** This module only works on debian-based workspaces. +> **Note:** This module only works on debian-based workspaces. It is recommended to use an image with a desktop environment pre-installed to speed up the installation process. ## Examples From b308ea5423743f21bc30de62133051648e75eda5 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 17:32:51 +0300 Subject: [PATCH 15/40] fixup! --- kasmvnc/run.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index e9b3b262..e80edce4 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -14,9 +14,9 @@ if ! dpkg -s kasmvncserver &> /dev/null; then DISTRO=$(lsb_release -c -s) ARCH=$(dpkg --print-architecture) wget -q https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${DISTRO}_${VERSION}_$${ARCH}.deb - sudo apt-get install -y ./kasvncserver_*.deb + sudo apt-get install -y ./kasmvncserver_*.deb printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" - rm ./kasvncserver_*.deb + sudo rm -f ./kasmvncserver_*.deb else echo "KasmVNC is already installed." fi From 41ef96933723344fad4f4e3213aadd87e0215d0b Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 17:42:52 +0300 Subject: [PATCH 16/40] fixup! --- kasmvnc/main.tf | 2 +- kasmvnc/run.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index b28cdff0..b46ef36e 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -17,7 +17,7 @@ variable "agent_id" { variable "port" { type = number description = "The port to run KasmVNC on." - default = 8443 + default = 6800 } variable "desktop_environment" { diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index e80edce4..f08df149 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -24,15 +24,15 @@ fi sudo addgroup $USER ssl-cert # Coder port-forwarding from dashboard only supports HTTP -sudo bash -c 'cat > /etc/kasmvnc/kasmvnc.yaml < /etc/kasmvnc/kasmvnc.yaml < Date: Fri, 17 May 2024 17:50:56 +0300 Subject: [PATCH 17/40] Install libdatetime-perl --- kasmvnc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index f08df149..a117a41b 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -3,7 +3,7 @@ # Check if desktop environment is installed if ! dpkg -s ${DESKTOP_ENVIRONMENT} &> /dev/null; then sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} libdatetime-perl else echo "${DESKTOP_ENVIRONMENT} is already installed." fi From c8cdc958d2e19e43a5aab41c89973dd424a03fae Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 18:18:26 +0300 Subject: [PATCH 18/40] fixup! --- kasmvnc/run.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index a117a41b..38f9ee05 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -10,13 +10,12 @@ fi # Check if vncserver is installed if ! dpkg -s kasmvncserver &> /dev/null; then - cd /tmp DISTRO=$(lsb_release -c -s) ARCH=$(dpkg --print-architecture) - wget -q https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${DISTRO}_${VERSION}_$${ARCH}.deb - sudo apt-get install -y ./kasmvncserver_*.deb + wget -q https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${DISTRO}_${VERSION}_$${ARCH}.deb -O /tmp/kasmvncserver.deb + sudo apt-get install -y /tmp/kasmvncserver.deb printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" - sudo rm -f ./kasmvncserver_*.deb + sudo rm -f /tmp/kasmvncserver.deb else echo "KasmVNC is already installed." fi @@ -39,5 +38,6 @@ EOF" # and does not listen publicly on the VM echo -e "password\npassword\n" | vncpasswd -wo -u $USER -# Start the server :) -sudo -u $USER bash -c 'vncserver -select-de "${DESKTOP_ENVIRONMENT}" -disableBasicAuth' +# Start the server +printf "🚀 Starting KasmVNC server...\n" +sudo -u $USER bash -c 'vncserver -select-de "${DESKTOP_ENVIRONMENT}" -disableBasicAuth' > /tmp/kassmvncserver.log 2>&1 & From c8db45e869ebafc0a181bc4bc24cfe5db6c55691 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 18:46:16 +0300 Subject: [PATCH 19/40] fixup! --- kasmvnc/main.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index b46ef36e..51a59694 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -50,6 +50,11 @@ resource "coder_app" "kasm_vnc" { display_name = "kasmVNC" url = "http://localhost:${var.port}" icon = "/icon/kasmvnc.svg" - subdomain = false + subdomain = true share = "owner" + healthcheck { + url = "http://localhost:${var.port}" + interval = 5 + threshold = 5 + } } From a6c449eef85f70ddf4fda9fcdbba9197fdc2eb01 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 17 May 2024 19:03:51 +0300 Subject: [PATCH 20/40] add healtcheck --- kasmvnc/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 51a59694..ae367263 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -53,7 +53,7 @@ resource "coder_app" "kasm_vnc" { subdomain = true share = "owner" healthcheck { - url = "http://localhost:${var.port}" + url = "http://localhost:${var.port}/app" interval = 5 threshold = 5 } From f00f8de8f3cc5ce97e216e55824d55def529ab3f Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 17:49:37 +0300 Subject: [PATCH 21/40] chore: Update KasmVNC to use XFCE desktop environment --- kasmvnc/README.md | 2 +- kasmvnc/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 1de4a919..40bf6fc3 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -9,7 +9,7 @@ tags: [helper, vnc, desktop] # KasmVNC -Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. Add latest version of KasmVNC with [`lxde`](https://www.lxde.org/) desktop environment: +Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. Add latest version of KasmVNC with [`xfce`](https://xfce.org/) desktop environment. ```tf module "kasmvnc" { diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index ae367263..62a3c17c 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -23,7 +23,7 @@ variable "port" { variable "desktop_environment" { type = string description = "The desktop environment to for KasmVNC (xfce, lxde, mate, etc)." - default = "lxde" + default = "xfce" } variable "kasm_version" { From a254fd3e89d156bc0005ed2dee989a6c4eb2c092 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 18:25:10 +0300 Subject: [PATCH 22/40] remove options --- kasmvnc/README.md | 15 --------------- kasmvnc/main.tf | 7 ------- kasmvnc/run.sh | 8 ++++---- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 40bf6fc3..b90e1b28 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -20,18 +20,3 @@ module "kasmvnc" { ``` > **Note:** This module only works on debian-based workspaces. It is recommended to use an image with a desktop environment pre-installed to speed up the installation process. - -## Examples - -1. Add specific version of KasmVNC with [`mate`](https://mate-desktop.org/) desktop environment and custom port: - - ```tf - module "kasmvnc" { - source = "registry.coder.com/modules/kasmvnc/coder" - agent_id = coder_agent.example.id - version = "1.0.15" - kasm_version = "1.3.1" - desktop_environment = "mate" - port = 6080 - } - ``` diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 62a3c17c..02ee4519 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -20,12 +20,6 @@ variable "port" { default = 6800 } -variable "desktop_environment" { - type = string - description = "The desktop environment to for KasmVNC (xfce, lxde, mate, etc)." - default = "xfce" -} - variable "kasm_version" { type = string description = "Version of KasmVNC to install." @@ -38,7 +32,6 @@ resource "coder_script" "kasm_vnc" { icon = "/icon/kasmvnc.svg" script = templatefile("${path.module}/run.sh", { PORT : var.port, - DESKTOP_ENVIRONMENT : var.desktop_environment, VERSION : var.kasm_version }) run_on_start = true diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 38f9ee05..37153d5d 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Check if desktop environment is installed -if ! dpkg -s ${DESKTOP_ENVIRONMENT} &> /dev/null; then +if ! dpkg -s $PACKAGES &> /dev/null; then sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y ${DESKTOP_ENVIRONMENT} libdatetime-perl + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y xfce4 xfce4-goodies libdatetime-perl --no-install-recommends --no-install-suggests else - echo "${DESKTOP_ENVIRONMENT} is already installed." + echo "$PACKAGES is already installed." fi # Check if vncserver is installed @@ -40,4 +40,4 @@ echo -e "password\npassword\n" | vncpasswd -wo -u $USER # Start the server printf "🚀 Starting KasmVNC server...\n" -sudo -u $USER bash -c 'vncserver -select-de "${DESKTOP_ENVIRONMENT}" -disableBasicAuth' > /tmp/kassmvncserver.log 2>&1 & +sudo -u $USER bash -c 'vncserver -select-de xfce4 -disableBasicAuth' > /tmp/kassmvncserver.log 2>&1 & From 71a2e6c1ed3ff80ebcbc7b1206c43e9eda1bbf55 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 18:47:32 +0300 Subject: [PATCH 23/40] add wait for script --- kasmvnc/main.tf | 7 +++++++ kasmvnc/run.sh | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 02ee4519..38a3ae51 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -26,12 +26,19 @@ variable "kasm_version" { default = "1.3.1" } +variable "wait_for_script" { + type = string + description = "The script to wait for before running the KasmVNC script." + default = "" +} + resource "coder_script" "kasm_vnc" { agent_id = var.agent_id display_name = "KasmVNC" icon = "/icon/kasmvnc.svg" script = templatefile("${path.module}/run.sh", { PORT : var.port, + WAIT_FOR_SCRIPT : var.wait_for_script, VERSION : var.kasm_version }) run_on_start = true diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 37153d5d..eb8f8306 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,5 +1,15 @@ #!/usr/bin/env bash +# check if there is a WAIT_FOR_SCRIPT env variable and if so, wait for it to be available + +# Wait for the startup script to complete +if [ -n "$WAIT_FOR_SCRIPT" ]; then + # This assumes that the script will create a file called /tmp/.coder-${WAIT_FOR_SCRIPT}.done + while [ ! -f /tmp/.coder-${WAIT_FOR_SCRIPT}.done ]; do + sleep 1 + done +fi + # Check if desktop environment is installed if ! dpkg -s $PACKAGES &> /dev/null; then sudo apt-get update From 39bc74511ff994cb06f0c09687db3c2c440c63e4 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 18:56:22 +0300 Subject: [PATCH 24/40] fixup! --- kasmvnc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index eb8f8306..0dcd894c 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -3,7 +3,7 @@ # check if there is a WAIT_FOR_SCRIPT env variable and if so, wait for it to be available # Wait for the startup script to complete -if [ -n "$WAIT_FOR_SCRIPT" ]; then +if [ -n "${WAIT_FOR_SCRIPT}" ]; then # This assumes that the script will create a file called /tmp/.coder-${WAIT_FOR_SCRIPT}.done while [ ! -f /tmp/.coder-${WAIT_FOR_SCRIPT}.done ]; do sleep 1 From c2698be6dc300776e606abc7c18de7e9eaae7135 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 18:57:30 +0300 Subject: [PATCH 25/40] fixup! --- kasmvnc/run.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 0dcd894c..935821e9 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -10,12 +10,13 @@ if [ -n "${WAIT_FOR_SCRIPT}" ]; then done fi +PACKAGES="xfce4 xfce4-goodies libdatetime-perl" # Check if desktop environment is installed if ! dpkg -s $PACKAGES &> /dev/null; then sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y xfce4 xfce4-goodies libdatetime-perl --no-install-recommends --no-install-suggests + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y $PACKAGES --no-install-recommends --no-install-suggests else - echo "$PACKAGES is already installed." + echo "$PACKAGES are already installed." fi # Check if vncserver is installed From d61f14d42fff1aeb195b249899d5594be0802c18 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 19:51:12 +0300 Subject: [PATCH 26/40] fixup! --- kasmvnc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 935821e9..6cf3b020 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -51,4 +51,4 @@ echo -e "password\npassword\n" | vncpasswd -wo -u $USER # Start the server printf "🚀 Starting KasmVNC server...\n" -sudo -u $USER bash -c 'vncserver -select-de xfce4 -disableBasicAuth' > /tmp/kassmvncserver.log 2>&1 & +sudo -u $USER bash -c 'vncserver -select-de xfce -disableBasicAuth' > /tmp/kassmvncserver.log 2>&1 & From 12e4d35195c0c62a767d6bd65d10e755da45724c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 30 May 2024 20:11:45 +0300 Subject: [PATCH 27/40] `bun fmt` --- kasmvnc/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 38a3ae51..6634b89c 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -29,7 +29,7 @@ variable "kasm_version" { variable "wait_for_script" { type = string description = "The script to wait for before running the KasmVNC script." - default = "" + default = "" } resource "coder_script" "kasm_vnc" { From 6017b05bc1120126f3ed6847f78dc8bc4b53bd3a Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 20 Sep 2024 18:25:48 +0500 Subject: [PATCH 28/40] Refactor KasmVNC installation script logic - Simplify and modularize the installation process - Add mapping for different Linux distributions and architectures - Validate the desktop environment to ensure compatibility --- kasmvnc/README.md | 4 +- kasmvnc/main.tf | 11 ++-- kasmvnc/run.sh | 155 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 136 insertions(+), 34 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index b90e1b28..676d4cc0 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -9,7 +9,7 @@ tags: [helper, vnc, desktop] # KasmVNC -Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. Add latest version of KasmVNC with [`xfce`](https://xfce.org/) desktop environment. +Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and create an app to access it via the dashboard. ```tf module "kasmvnc" { @@ -19,4 +19,4 @@ module "kasmvnc" { } ``` -> **Note:** This module only works on debian-based workspaces. It is recommended to use an image with a desktop environment pre-installed to speed up the installation process. +> **Note:** This module only works on workspaces with a pre-installed desktop environment. diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 6634b89c..4b36eb28 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -26,10 +26,13 @@ variable "kasm_version" { default = "1.3.1" } -variable "wait_for_script" { +variable "desktop_environment" { type = string - description = "The script to wait for before running the KasmVNC script." - default = "" + description = "Specifies the desktop environment of the workspace. This should be pre-installed on the workspace." + validation { + condition = contains(["xfce", "kde", "gnome", "lxde", "lxqt", "xfce"], var.desktop_environment) + error_message = "Invalid desktop environment. Please specify a valid desktop environment." + } } resource "coder_script" "kasm_vnc" { @@ -38,7 +41,7 @@ resource "coder_script" "kasm_vnc" { icon = "/icon/kasmvnc.svg" script = templatefile("${path.module}/run.sh", { PORT : var.port, - WAIT_FOR_SCRIPT : var.wait_for_script, + DESKTOP_ENVIRONMENT : var.desktop_environment, VERSION : var.kasm_version }) run_on_start = true diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 6cf3b020..cbde54d5 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -1,38 +1,137 @@ #!/usr/bin/env bash -# check if there is a WAIT_FOR_SCRIPT env variable and if so, wait for it to be available - -# Wait for the startup script to complete -if [ -n "${WAIT_FOR_SCRIPT}" ]; then - # This assumes that the script will create a file called /tmp/.coder-${WAIT_FOR_SCRIPT}.done - while [ ! -f /tmp/.coder-${WAIT_FOR_SCRIPT}.done ]; do - sleep 1 - done -fi +#!/bin/bash + +# Function to check if vncserver is already installed +check_installed() { + if command -v vncserver &> /dev/null; then + echo "vncserver is already installed." + return 0 # Don't exit, just indicate it's installed + else + return 1 # Indicates not installed + fi +} + +# Function to install kasmvncserver for debian-based distros +install_deb() { + local url=$1 + wget $url -O /tmp/kasmvncserver.deb + sudo apt-get install ./kasmvncserver_*.deb -y + sudo adduser $USER ssl-cert + rm /tmp/kasmvncserver.deb +} + +# Function to install kasmvncserver for Oracle 8 +install_rpm_oracle8() { + local url=$1 + wget $url -O /tmp/kasmvncserver.rpm + sudo dnf config-manager --set-enabled ol8_codeready_builder + sudo dnf install oracle-epel-release-el8 -y + sudo dnf localinstall ./kasmvncserver_*.rpm -y + sudo usermod -a -G kasmvnc-cert $USER + rm /tmp/kasmvncserver.rpm +} + +# Function to install kasmvncserver for CentOS 7 +install_rpm_centos7() { + local url=$1 + wget $url -O /tmp/kasmvncserver.rpm + sudo yum install epel-release -y + sudo yum install ./kasmvncserver_*.rpm -y + sudo usermod -a -G kasmvnc-cert $USER + rm /tmp/kasmvncserver.rpm +} -PACKAGES="xfce4 xfce4-goodies libdatetime-perl" -# Check if desktop environment is installed -if ! dpkg -s $PACKAGES &> /dev/null; then - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y $PACKAGES --no-install-recommends --no-install-suggests +# Function to install kasmvncserver for rpm-based distros +install_rpm() { + local url=$1 + wget $url -O /tmp/kasmvncserver.rpm + sudo rpm -i /tmp/kasmvncserver.rpm + rm /tmp/kasmvncserver.rpm +} + +# Function to install kasmvncserver for Alpine Linux +install_alpine() { + local url=$1 + wget $url -O /tmp/kasmvncserver.tgz + tar -xzf /tmp/kasmvncserver.tgz -C /usr/local/bin/ + rm /tmp/kasmvncserver.tgz +} + +# Detect system information +distro=$(grep "^ID=" /etc/os-release | awk -F= '{print $2}') +version=$(grep "^VERSION_ID=" /etc/os-release | awk -F= '{print $2}' | tr -d '"') +arch=$(uname -m) + +echo "Detected Distribution: $distro" +echo "Detected Version: $version" +echo "Detected Architecture: $arch" + +# Map arch to package arch +if [[ "$arch" == "x86_64" ]]; then + arch="x86_64" +elif [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then + arch="aarch64" else - echo "$PACKAGES are already installed." + echo "Unsupported architecture: $arch" + exit 1 fi -# Check if vncserver is installed -if ! dpkg -s kasmvncserver &> /dev/null; then - DISTRO=$(lsb_release -c -s) - ARCH=$(dpkg --print-architecture) - wget -q https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${DISTRO}_${VERSION}_$${ARCH}.deb -O /tmp/kasmvncserver.deb - sudo apt-get install -y /tmp/kasmvncserver.deb - printf "🥳 KasmVNC v${VERSION} has been successfully installed!\n\n" - sudo rm -f /tmp/kasmvncserver.deb +# Check if vncserver is installed, and install if not +if ! check_installed; then + case $distro in + ubuntu | debian | kali) + case $version in + "18.04") + install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_bionic_${VERSION}_$${arch}.deb" + ;; + "20.04") + install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_$${arch}.deb" + ;; + "22.04") + install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_jammy_${VERSION}_$${arch}.deb" + ;; + *) + echo "Unsupported Ubuntu/Debian/Kali version: $${version}" + exit 1 + ;; + esac + ;; + oracle) + if [[ "$version" == "8" ]]; then + install_rpm_oracle8 "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_oracle_8_${VERSION}_$${arch}.rpm" + else + echo "Unsupported Oracle version: $${version}" + exit 1 + fi + ;; + centos) + if [[ "$version" == "7" ]]; then + install_rpm_centos7 "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_centos_core_${VERSION}_$${arch}.rpm" + else + install_rpm "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_centos_core_${VERSION}_$${arch}.rpm" + fi + ;; + alpine) + if [[ "$version" == "3.17" || "$version" == "3.18" || "$version" == "3.19" ]]; then + install_alpine "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvnc.alpine_$${version}_$${arch}.tgz" + else + echo "Unsupported Alpine version: $${version}" + exit 1 + fi + ;; + fedora | opensuse) + install_rpm "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_$${distro}_$${version}_${VERSION}_$${arch}.rpm" + ;; + *) + echo "Unsupported distribution: $${distro}" + exit 1 + ;; + esac else - echo "KasmVNC is already installed." + echo "vncserver already installed. Skipping installation." fi -sudo addgroup $USER ssl-cert - # Coder port-forwarding from dashboard only supports HTTP sudo bash -c "cat > /etc/kasmvnc/kasmvnc.yaml < /tmp/kassmvncserver.log 2>&1 & +sudo -u $USER bash -c "vncserver -select-de ${DESKTOP_ENVIRONMENT} -disableBasicAuth" > /tmp/kasmvncserver.log 2>&1 & From 2ee02a38e5df3739f63d91189e5b0e0fd7f6fb07 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 20 Sep 2024 18:01:27 +0000 Subject: [PATCH 29/40] fix: remove duplicate validation value --- kasmvnc/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 4b36eb28..83b55a3f 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -30,7 +30,7 @@ variable "desktop_environment" { type = string description = "Specifies the desktop environment of the workspace. This should be pre-installed on the workspace." validation { - condition = contains(["xfce", "kde", "gnome", "lxde", "lxqt", "xfce"], var.desktop_environment) + condition = contains(["xfce", "kde", "gnome", "lxde", "lxqt"], var.desktop_environment) error_message = "Invalid desktop environment. Please specify a valid desktop environment." } } From 59041b35657aaae8cc689f5fc215e71d33b27e9e Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 20 Sep 2024 18:02:02 +0000 Subject: [PATCH 30/40] chore: get basic tests in place --- kasmvnc/main.test.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 kasmvnc/main.test.ts diff --git a/kasmvnc/main.test.ts b/kasmvnc/main.test.ts new file mode 100644 index 00000000..870a15ed --- /dev/null +++ b/kasmvnc/main.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from "bun:test"; +import { + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "../test"; + +const allowedDesktopEnvs = ["xfce", "kde", "gnome", "lxde", "lxqt"] as const; +type AllowedDesktopEnv = (typeof allowedDesktopEnvs)[number]; + +type TestVariables = Readonly<{ + agent_id: string; + desktop_environment: AllowedDesktopEnv; + port?: string; + kasm_version?: string; +}>; + +describe("Kasm VNC", async () => { + await runTerraformInit(import.meta.dir); + testRequiredVariables(import.meta.dir, { + agent_id: "foo", + desktop_environment: "gnome", + }); + + it("Successfully installs for all expected Kasm versions", async () => { + for (const v of allowedDesktopEnvs) { + const applyWithEnv = () => { + runTerraformApply(import.meta.dir, { + agent_id: "foo", + desktop_environment: v, + }); + }; + + expect(applyWithEnv).not.toThrow(); + } + }); +}); From 3ce7ef56b1a51a4226051af33fc6dbaf3d560894 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 20 Sep 2024 18:27:25 +0000 Subject: [PATCH 31/40] fix: update test text for more clarity --- kasmvnc/main.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/main.test.ts b/kasmvnc/main.test.ts index 870a15ed..0116d053 100644 --- a/kasmvnc/main.test.ts +++ b/kasmvnc/main.test.ts @@ -22,7 +22,7 @@ describe("Kasm VNC", async () => { desktop_environment: "gnome", }); - it("Successfully installs for all expected Kasm versions", async () => { + it("Successfully installs for all expected Kasm desktop versions", async () => { for (const v of allowedDesktopEnvs) { const applyWithEnv = () => { runTerraformApply(import.meta.dir, { From c10a2bab3200ec83b1863a5bf05d370fe4107f33 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Mon, 30 Sep 2024 11:51:21 +0500 Subject: [PATCH 32/40] Bump KasmVNC module version to 1.0.20 --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 676d4cc0..53365abd 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -14,7 +14,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ```tf module "kasmvnc" { source = "registry.coder.com/modules/kasmvnc/coder" - version = "1.0.15" + version = "1.0.20" agent_id = coder_agent.example.id } ``` From cf3159cb5c41cdba0b5eb2adbfb00b719229d5d8 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 2 Oct 2024 22:39:08 +0500 Subject: [PATCH 33/40] Update README.md --- kasmvnc/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 53365abd..6fea1d65 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -13,9 +13,10 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ```tf module "kasmvnc" { - source = "registry.coder.com/modules/kasmvnc/coder" - version = "1.0.20" - agent_id = coder_agent.example.id + source = "registry.coder.com/modules/kasmvnc/coder" + version = "1.0.20" + agent_id = coder_agent.example.id + desktop_environment = "xfce" } ``` From c6895b5f5b99210a7497b13dbaf2472d2963b41c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 4 Oct 2024 18:14:05 +0500 Subject: [PATCH 34/40] Update KasmVNC to version 1.3.2 and add support --- kasmvnc/main.tf | 2 +- kasmvnc/run.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kasmvnc/main.tf b/kasmvnc/main.tf index 83b55a3f..3a730ff5 100644 --- a/kasmvnc/main.tf +++ b/kasmvnc/main.tf @@ -23,7 +23,7 @@ variable "port" { variable "kasm_version" { type = string description = "Version of KasmVNC to install." - default = "1.3.1" + default = "1.3.2" } variable "desktop_environment" { diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index cbde54d5..0a41301a 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -82,15 +82,15 @@ if ! check_installed; then case $distro in ubuntu | debian | kali) case $version in - "18.04") - install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_bionic_${VERSION}_$${arch}.deb" - ;; "20.04") install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_focal_${VERSION}_$${arch}.deb" ;; "22.04") install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_jammy_${VERSION}_$${arch}.deb" ;; + "24.04") + install_deb "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvncserver_noble_${VERSION}_$${arch}.deb" + ;; *) echo "Unsupported Ubuntu/Debian/Kali version: $${version}" exit 1 @@ -113,7 +113,7 @@ if ! check_installed; then fi ;; alpine) - if [[ "$version" == "3.17" || "$version" == "3.18" || "$version" == "3.19" ]]; then + if [[ "$version" == "3.17" || "$version" == "3.18" || "$version" == "3.19" || "$version" == "3.20" ]]; then install_alpine "https://github.com/kasmtech/KasmVNC/releases/download/v${VERSION}/kasmvnc.alpine_$${version}_$${arch}.tgz" else echo "Unsupported Alpine version: $${version}" From 4020ec05e6d23bbfcbf9ecdbe3d674f20bd5e37b Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 4 Oct 2024 18:36:43 +0500 Subject: [PATCH 35/40] Refine architecture mapping for specific distros --- kasmvnc/run.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 0a41301a..b21a44b1 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -69,9 +69,17 @@ echo "Detected Architecture: $arch" # Map arch to package arch if [[ "$arch" == "x86_64" ]]; then - arch="x86_64" + if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then + arch="amd64" + else + arch="x86_64" + fi elif [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then - arch="aarch64" + if [[ "$distro" == "ubuntu" || "$distro" == "debian" || "$distro" == "kali" ]]; then + arch="arm64" + else + arch="aarch64" + fi else echo "Unsupported architecture: $arch" exit 1 From f4cdb152feee81c9e82ddbd244a9f41bde84ee50 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 4 Oct 2024 18:40:02 +0500 Subject: [PATCH 36/40] fix(kasmvnc): correct .deb file installation path --- kasmvnc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index b21a44b1..65be1a33 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -16,7 +16,7 @@ check_installed() { install_deb() { local url=$1 wget $url -O /tmp/kasmvncserver.deb - sudo apt-get install ./kasmvncserver_*.deb -y + sudo apt-get install /tmp/kasmvncserver_*.deb -y sudo adduser $USER ssl-cert rm /tmp/kasmvncserver.deb } From 18570aa6298aaa091453cc23bb39808de53c5eb7 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 4 Oct 2024 18:49:00 +0500 Subject: [PATCH 37/40] Improve Debian package installation command By refining the package manager options, this change prevents the installation of unnecessary recommended and suggested packages, streamlining the process. --- kasmvnc/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index 65be1a33..acfb46a6 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -16,7 +16,7 @@ check_installed() { install_deb() { local url=$1 wget $url -O /tmp/kasmvncserver.deb - sudo apt-get install /tmp/kasmvncserver_*.deb -y + sudo apt-get install --yes --no-install-recommends --no-install-suggests /tmp/kasmvncserver.deb sudo adduser $USER ssl-cert rm /tmp/kasmvncserver.deb } From a63c365dfa528f8cc46a6933e587b22705c6eee3 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 4 Oct 2024 18:52:05 +0500 Subject: [PATCH 38/40] Fix RPM installation path in kasmvnc script Simplify and unify the RPM installation process by using the consistent temporary directory path for downloading RPM files. This reduces potential errors and ensures uniform script behavior between different OS installations. --- kasmvnc/run.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kasmvnc/run.sh b/kasmvnc/run.sh index acfb46a6..0390ea10 100644 --- a/kasmvnc/run.sh +++ b/kasmvnc/run.sh @@ -27,8 +27,8 @@ install_rpm_oracle8() { wget $url -O /tmp/kasmvncserver.rpm sudo dnf config-manager --set-enabled ol8_codeready_builder sudo dnf install oracle-epel-release-el8 -y - sudo dnf localinstall ./kasmvncserver_*.rpm -y - sudo usermod -a -G kasmvnc-cert $USER + sudo dnf localinstall /tmp/kasmvncserver.rpm -y + sudo usermod -aG kasmvnc-cert $USER rm /tmp/kasmvncserver.rpm } @@ -37,8 +37,8 @@ install_rpm_centos7() { local url=$1 wget $url -O /tmp/kasmvncserver.rpm sudo yum install epel-release -y - sudo yum install ./kasmvncserver_*.rpm -y - sudo usermod -a -G kasmvnc-cert $USER + sudo yum install /tmp/kasmvncserver.rpm -y + sudo usermod -aG kasmvnc-cert $USER rm /tmp/kasmvncserver.rpm } From 43a353c1ef9b9142d7505ba145946cb142ab6e02 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 17 Oct 2024 06:51:49 +0500 Subject: [PATCH 39/40] Update README.md --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index 6fea1d65..a220bea4 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -20,4 +20,4 @@ module "kasmvnc" { } ``` -> **Note:** This module only works on workspaces with a pre-installed desktop environment. +> **Note:** This module only works on workspaces with a pre-installed desktop environment. As an example base image you can use `codercom/enterprise-desktop` image. From 457621c93f0e0ffe296429b2438ae3127ba8d996 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 17 Oct 2024 07:02:07 +0500 Subject: [PATCH 40/40] update version --- kasmvnc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kasmvnc/README.md b/kasmvnc/README.md index a220bea4..845cbc23 100644 --- a/kasmvnc/README.md +++ b/kasmvnc/README.md @@ -14,7 +14,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and ```tf module "kasmvnc" { source = "registry.coder.com/modules/kasmvnc/coder" - version = "1.0.20" + version = "1.0.21" agent_id = coder_agent.example.id desktop_environment = "xfce" }