Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add cyclecloud configuration scripts for web interface and agent hostname #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Thinlinc CycleCloud Project

This project is used for Azure CycleCloud integrated with Thinlinc to allow thinlinc work smoothly on Cyclecloud cluster nodes.
ThinLinc is a powerful remote desktop server solution for Linux environments, offering seamless access to applications from various clients with robust security and high performance. See the [ThinLinc site](https://www.cendio.com/) and [documentation](https://www.cendio.com/thinlinc/docs/) for an overview and detailed information.

This project integrates Azure CycleCloud with ThinLinc to ensure seamless operation of ThinLinc on CycleCloud cluster nodes.

Please reference the [CycleCloud Projects page](https://docs.microsoft.com/en-us/azure/cyclecloud/projects) dives into
greater detail on the concepts and examples.
Expand Down Expand Up @@ -46,7 +48,7 @@ Prepare the credentials to access the blob container associated with the locker:
matches = az://cendiocyclecloud/cyclecloud
```

*You can locate your Subscription ID using the Azure CLI (`az` command) to list the accounts:* `az account list -o table`
_You can locate your Subscription ID using the Azure CLI (`az` command) to list the accounts:_ `az account list -o table`

* Your `~/.cycle/config.ini` should now look something like this

Expand Down Expand Up @@ -84,11 +86,43 @@ Prepare the credentials to access the blob container associated with the locker:

### 1.3 Create a new Cluster with the Thinlinc Project

*Note: /tempplates/signle-nodearray_teampate_1.0.0.2.txt is a sample signle nodearray cluster template, please make the necessary adjustment when using it.*

Having uploaded the Thinlinc project into the CycleCloud locker, you can now create a new cluster in CycleCloud and specify that each node should use the `cyclecloud-thinlinc:default` spec.

* From the Cluster page of your Azure CycleCloud web portal, navigate to the *Advanced Settings* section. Under the *Software* section, click on the "Browse" button which will open a file selector dialog, You will see a folder named `cyclecloud-thinlinc/`. Open it by double-clicking it. Then open the `1.0.0/` folder. Finally, select the `default/` folder by clicking on it once and pressing the "Select" button on the bottom of the dialog window. After pressing "Select" the file selector dialog will close. This selects the `default` spec of version `1.0.0` of the project `cyclecloud-thinlinc`.
![Browse Specs](images/cluster-init.png)
* Import cluster template by referencing the sample template located at /templates/single-nodearray_template_1.0.0.3.txt. Make the necessary adjustments accordingly.

```sh
(venv) xuan@dhcp-130:~/cyclecloud-thinlinc$ cyclecloud import_template single-nodearray -f ./templates/single-nodearray_template_1.0.0.3.txt
Importing template single-nodearray....
-----------------------------
single-nodearray : *template*
-----------------------------
Resource group:
Cluster nodes:
my-tl: Off -- --
Total nodes: 1
(venv) xuan@dhcp-130:~/cyclecloud-thinlinc$
```


* From the Cluster page of your Azure CycleCloud web portal, use the "+" symbol in the bottom-left-hand corner of the page to add a new cluster, select "single-nodearray" template created in the last step:
![Browse Specs](images/cluster-template.png)


* Input the cluster name and complete the other required fields.

* Navigate to the *Advanced Settings* section. Under the *Software* section, click on the "Browse" button for "Cluster-Init" which will open a file selector dialog, You will see a folder named `cyclecloud-thinlinc/`. Open it by double-clicking it. Then open the `1.0.0/` folder. Finally, select the `default/` folder by clicking on it once and pressing the "Select" button on the bottom of the dialog window. After pressing "Select" the file selector dialog will close. This selects the `default` spec of version `1.0.0` of the project `cyclecloud-thinlinc`.

* Under the *Thinlinc* section, for `Enable Web Interface` choose to enable or disable ThinLinc web interface access (default is disabled), we recommend to enable it. Once selected, input your web interface port number in the `Web Port` field (default is 443).

*Note: Please ensure your network security or firewall rules allow inbound access on this port.*

* In the `Connection Mode` dropdown, select the mode for the client connect from, the three options are:
**Public IP**: Connect trhough a public IP address.

**Private IP**: Connect through a VPN with direct connectivity to the Cluster.

**SSH Tunnel**: Connect through a bastion host.

![Browse Specs](images/advanced-settings.png)

* Save the cluster and start it. When the master node turns green, log into it and verify that Thinlinc web interface configured correctly.
* Save the cluster and start it. When the master node turns green, connet to it using Thinlinc client to verify that it is configured correctly.
Binary file added images/advanced-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/cluster-init.png
Binary file not shown.
Binary file added images/cluster-template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 33 additions & 18 deletions specs/default/cluster-init/scripts/01_configure_tlwebaccess.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
#!/bin/bash

# Define the path to the configuration file
CONFIG_FILE="/opt/thinlinc/etc/conf.d/webaccess.hconf"
# Fetch thinlinc web access parameters
enable_web=$(jetpack config thinlinc.enable_web False)
thinlinc_web_port=$(jetpack config thinlinc.web_port 443)

# Update the /opt/thinlinc/etc/conf.d/webaccess.hconf file
if [ -f "$CONFIG_FILE" ]; then
sed -i 's/^listen_port=300$/listen_port=443/' "$CONFIG_FILE"
else
echo "Configuration file not found: $CONF_FILE"
exit 1
fi
# Function to restart tlwebaccess service
restart_tlwebaccess() {
if ! systemctl restart tlwebaccess; then
echo "Failed to restart tlwebaccess service."
exit 1
fi
echo "Thinlinc tlwebaccess service restarted successfully."
}

echo "listen_port updated successfully."
# Function to disable tlwebaccess service
disable_tlwebaccess() {
if ! systemctl disable --now tlwebaccess; then
echo "Failed to disable tlwebaccess service."
exit 1
fi
echo "Thinlinc tlwebaccess service disable successfully."
}

# Restart the tlwebaccess service
systemctl restart tlwebaccess;
if [ $? -ne 0 ]; then
echo "Failed to restart tlwebaccess service"
exit 1
if [[ "$enable_web" == "True" ]]; then
# Update the listen_port
/opt/thinlinc/bin/tl-config /webaccess/listen_port=$thinlinc_web_port
if [[ $? -ne 0 ]]; then
echo "Failed to configure Thinlinc Web Access port number."
exit 1
fi
# Restart the tlwebaccess service to apply changes
restart_tlwebaccess
echo "Thinlinc Web Access port number configurations completed."
else
# Disable the tlwebaccess service
disable_tlwebaccess
echo "Disable Thinlinc Web access completed."
fi

echo "tlwebaccess service restarted successfully."
echo "tlwebaccess configurations completed."
37 changes: 37 additions & 0 deletions specs/default/cluster-init/scripts/02_configure_vsmagent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Fetch the connection mode
connection_mode=$(jetpack config thinlinc.connection_mode private_ip)

# Determine the agent_hostname based on the connection mode
case "$connection_mode" in
"private_ip")
thinlinc_agent_hostname=$(jetpack config cloud.local_ipv4)
;;
"public_ip")
thinlinc_agent_hostname=$(jetpack config cloud.public_ipv4)
;;
"ssh_tunnel")
thinlinc_agent_hostname="localhost"
;;
*)
echo "Unknown connection mode: $connection_mode. Exiting script."
exit 1
;;
esac

# Update the agent_hostname
/opt/thinlinc/bin/tl-config /vsmagent/agent_hostname=$thinlinc_agent_hostname
if [[ $? -ne 0 ]]; then
echo "Failed to configure Thinlinc agent_hostname."
exit 1
fi

# Restart the vsmagent service to apply changes
systemctl restart vsmagent
if [[ $? -ne 0 ]]; then
echo "Failed to restart Thinlinc vsmagent service"
exit 1
fi

echo "Thinlinc agent_hostname configurations completed."
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ Category = Infrastructure
PublicPort = 443
Protocol = tcp

[[[configuration]]]
thinlinc.enable_web = $EnableWeb
thinlinc.web_port = $WebPort
thinlinc.connection_mode = $ConnectionMode

[[[cluster-init cyclecloud-thinlinc:default:1.0.1]]]

[[nodearray login]]
Expand Down Expand Up @@ -132,6 +137,28 @@ Order = 20
Description = Cluster init specs to apply to the node
ParameterType = Cloud.ClusterInitSpecs

[[parameters Thinlinc]]
[[[parameter EnableWeb]]]
Label = Enable Web Interface
DefaultValue = false
ParameterType = Boolean
Config.Label = Enable HTML Remote Desktop

[[[parameter WebPort]]]
Label = Web Port
Description = Web Port to connect to the Web Interface²
DefaultValue = 443
ParameterType = Integer
Conditions.Excluded := EnableWeb isnt true

[[[parameter ConnectionMode]]]
Label = Connection Mode
ParameterType = StringList
Config.Label = The connection mode from the client
Config.Plugin = pico.form.Dropdown
Config.Entries := {[Label="Private IP"; Value="private_ip"], [Label="Public IP"; Value="public_ip"], [Label="SSH Tunnel"; Value="ssh_tunnel"]}
DefaultValue = private_ip

[[parameters Advanced Networking]]
Description = Advanced networking settings

Expand Down