Skip to content

Commit

Permalink
cvm: Add pre_launch_script in app-compose
Browse files Browse the repository at this point in the history
  • Loading branch information
kvinwang committed Jan 13, 2025
1 parent e14dfc8 commit a6cbf4a
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 46 deletions.
43 changes: 35 additions & 8 deletions basefiles/app-compose.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
#!/bin/sh
tdxctl notify-host -e "boot.progress" -d "starting containers" || true
#!/bin/bash

docker compose up --remove-orphans -d || true
chmod +x /usr/bin/containerd-shim-runc-v2
systemctl restart docker
if [ $(jq 'has("pre_launch_script")' app-compose.json) == true ]; then
echo "Running pre-launch script"
tdxctl notify-host -e "boot.progress" -d "pre-launch" || true
source <(jq -r '.pre_launch_script' app-compose.json)
fi

RUNNER=$(jq -r '.runner' app-compose.json)
case "$RUNNER" in
"docker-compose")
echo "Starting containers"
tdxctl notify-host -e "boot.progress" -d "starting containers" || true
if ! [ -f docker-compose.yaml ]; then
jq -r '.docker_compose_file' app-compose.json >docker-compose.yaml
fi
docker compose up --remove-orphans -d || true
chmod +x /usr/bin/containerd-shim-runc-v2
systemctl restart docker

if ! docker compose up --remove-orphans -d; then
tdxctl notify-host -e "boot.error" -d "failed to start containers"
if ! docker compose up --remove-orphans -d; then
tdxctl notify-host -e "boot.error" -d "failed to start containers"
exit 1
fi
;;
"bash")
chmod +x /usr/bin/containerd-shim-runc-v2
echo "Running main script"
tdxctl notify-host -e "boot.progress" -d "running main script" || true
jq -r '.bash_script' app-compose.json | bash
;;
*)
echo "ERROR: unsupported runner: $RUNNER" >&2
tdxctl notify-host -e "boot.error" -d "unsupported runner: $RUNNER"
exit 1
fi
;;
esac

tdxctl notify-host -e "boot.progress" -d "done" || true
16 changes: 0 additions & 16 deletions tdxctl/src/tboot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ impl<'a> Setup<'a> {
nc.notify_q("boot.progress", "setting up docker").await;
self.setup_docker_registry()?;
self.setup_docker_account()?;
self.prepare_docker_compose()?;
Ok(())
}

Expand Down Expand Up @@ -263,21 +262,6 @@ impl<'a> Setup<'a> {
cmd!(docker login -u $username -p $token)?;
Ok(())
}

fn prepare_docker_compose(&self) -> Result<()> {
info!("Preparing docker compose");
if self.app_compose.runner == "docker-compose" {
let docker_compose = self
.app_compose
.docker_compose_file
.as_ref()
.context("Missing docker_compose_file")?;
fs::write(self.resolve("/tapp/docker-compose.yaml"), docker_compose)?;
} else {
bail!("Unsupported runner: {}", self.app_compose.runner);
}
Ok(())
}
}

pub async fn tboot(args: &TbootArgs) -> Result<()> {
Expand Down
67 changes: 49 additions & 18 deletions teepod/src/console.html
Original file line number Diff line number Diff line change
Expand Up @@ -521,10 +521,16 @@ <h2>Deploy a new instance</h2>

<div class="form-group">
<label for="composeFile">Docker Compose File</label>
<textarea id="composeFile" v-model="vmForm.compose_file"
<textarea id="composeFile" v-model="vmForm.dockerComposeFile"
placeholder="Paste your docker-compose.yml here" required></textarea>
</div>

<div class="form-group">
<label for="preLaunchScript">Pre-launch Script</label>
<textarea id="preLaunchScript" v-model="vmForm.preLaunchScript"
placeholder="Optional: Bash script to run before starting containers"></textarea>
</div>

<div class="form-group full-width" v-if="config.portMappingEnabled">
<label>Port Mappings</label>
<div v-for="(port, index) in vmForm.ports" :key="index"
Expand Down Expand Up @@ -779,6 +785,9 @@ <h4 style="margin: 0 0 12px 0;">App Information</h4>
<h4 style="margin: 0 0 12px 0;">Docker Compose File</h4>
<pre
style="background: #f1f1f1; padding: 12px; border-radius: 4px; overflow-x: auto;">{{ vm.appCompose?.docker_compose_file }}</pre>
<h4 style="margin: 0 0 12px 0;">Pre-launch Script</h4>
<pre
style="background: #f1f1f1; padding: 12px; border-radius: 4px; overflow-x: auto;">{{ vm.appCompose?.pre_launch_script }}</pre>
</div>
</div>
</td>
Expand Down Expand Up @@ -818,14 +827,25 @@ <h3>Update VM Config</h3>
</select>
</div>

<div class="form-group">
<label for="upgradeFile">Upload New Compose File</label>
<input id="upgradeFile" type="file" @change="loadUpgradeFile" accept=".yml,.yaml,.txt">
<div style="display: flex; align-items: center; margin-top: 16px;">
<input type="checkbox" v-model="upgradeDialog.updateCompose" style="width: 16px; height: 16px;">
<span style="margin-left: 8px;">Update App Compose</span>
</div>
<div class="form-group">
<label for="upgradeCompose">Docker Compose File</label>
<textarea id="upgradeCompose" v-model="upgradeDialog.compose_file"
placeholder="Paste your new docker-compose.yml here" required></textarea>
<div v-if="upgradeDialog.updateCompose">
<div class="form-group">
<label for="upgradeFile">Upload New Compose File</label>
<input id="upgradeFile" type="file" @change="loadUpgradeFile" accept=".yml,.yaml,.txt">
</div>
<div class="form-group">
<label for="upgradeCompose">Docker Compose File</label>
<textarea id="upgradeCompose" v-model="upgradeDialog.dockerComposeFile"
placeholder="Paste your new docker-compose.yml here" required></textarea>
</div>
<div class="form-group">
<label for="upgradePrelauncher">Pre-launch Script</label>
<textarea id="upgradePrelauncher" v-model="upgradeDialog.preLaunchScript"
placeholder="Optional: Bash script to run before starting containers"></textarea>
</div>
</div>
<div style="display: flex; align-items: center; margin-top: 16px;">
<input type="checkbox" v-model="upgradeDialog.resetSecrets" style="width: 16px; height: 16px;">
Expand Down Expand Up @@ -931,7 +951,8 @@ <h3>Derive VM</h3>
const vmForm = ref({
name: '',
image: '',
compose_file: '',
dockerComposeFile: '',
preLaunchScript: '',
vcpu: 1,
memory: 1024,
disk_size: 20,
Expand All @@ -951,7 +972,9 @@ <h3>Derive VM</h3>
const upgradeDialog = ref({
show: false,
vm: null,
compose_file: '',
updateCompose: false,
dockerComposeFile: '',
preLaunchScript: '',
encrypted_envs: [],
resetSecrets: false,
vcpu: 0,
Expand Down Expand Up @@ -1035,7 +1058,7 @@ <h3>Derive VM</h3>
"manifest_version": 2,
"name": vmForm.value.name,
"runner": "docker-compose",
"docker_compose_file": vmForm.value.compose_file,
"docker_compose_file": vmForm.value.dockerComposeFile,
"docker_config": vmForm.value.docker_config.enabled ? {
"username": vmForm.value.docker_config.username,
"token_key": vmForm.value.docker_config.token_key,
Expand All @@ -1045,6 +1068,11 @@ <h3>Derive VM</h3>
"public_logs": vmForm.value.public_logs,
"public_sysinfo": vmForm.value.public_sysinfo
};

if (vmForm.value.preLaunchScript?.trim()) {
app_compose.pre_launch_script = vmForm.value.preLaunchScript;
}

const imgFeatures = imageVersionFeatures(imageVersion(vmForm.value.image));
if (imgFeatures.compose_version < 2) {
// Compatibility with old images
Expand All @@ -1058,7 +1086,7 @@ <h3>Derive VM</h3>
return JSON.stringify(app_compose);
};

const appIdOf = async (composeFile) => {
const calcAppId = async () => {
const app_compose = makeAppComposeFile();
const sha256Hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(app_compose));
return Array.from(new Uint8Array(sha256Hash)).map(b => b.toString(16).padStart(2, '0')).join('').slice(0, 40);
Expand Down Expand Up @@ -1101,7 +1129,7 @@ <h3>Derive VM</h3>
const makeEncryptedEnv = async (envs, kmsEnabled, appId) => {
if (!kmsEnabled || envs.length === 0) return '';
if (!appId) {
appId = await appIdOf(vmForm.value.compose_file);
appId = await calcAppId();
}
const response = await rpcCall('GetAppEnvEncryptPubKey', {
app_id: appId
Expand Down Expand Up @@ -1233,7 +1261,7 @@ <h3>Derive VM</h3>
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
vmForm.value.compose_file = e.target.result;
vmForm.value.dockerComposeFile = e.target.result;
};
reader.readAsText(file);
}
Expand All @@ -1253,7 +1281,9 @@ <h3>Derive VM</h3>
upgradeDialog.value = {
show: true,
vm: vm,
compose_file: '',
updateCompose: false,
dockerComposeFile: vm.appCompose.docker_compose_file,
preLaunchScript: vm.appCompose.pre_launch_script,
resetSecrets: false,
vcpu: vm.configuration?.vcpu,
memory: vm.configuration?.memory,
Expand All @@ -1268,7 +1298,7 @@ <h3>Derive VM</h3>
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
upgradeDialog.value.compose_file = e.target.result;
upgradeDialog.value.dockerComposeFile = e.target.result;
};
reader.readAsText(file);
}
Expand All @@ -1294,12 +1324,13 @@ <h3>Derive VM</h3>
const body = {
id: upgradeDialog.value.vm.id,
};
if (upgradeDialog.value.compose_file) {
if (upgradeDialog.value.updateCompose) {
const currentAppCompose = upgradeDialog.value.vm.appCompose;
const app_compose = {
...currentAppCompose,
docker_compose_file: upgradeDialog.value.compose_file
docker_compose_file: upgradeDialog.value.dockerComposeFile || currentAppCompose.docker_compose_file
};
app_compose.pre_launch_script = upgradeDialog.value.preLaunchScript?.trim();
body.compose_file = JSON.stringify(app_compose);
}

Expand Down
5 changes: 1 addition & 4 deletions teepod/src/main_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,8 @@ impl TeepodRpc for RpcHandler {
runner: String,
docker_compose_file: Option<String>,
}
let app_compose: AppCompose =
let _app_compose: AppCompose =
serde_json::from_str(&request.compose_file).context("Invalid compose file")?;
if app_compose.docker_compose_file.is_none() {
bail!("Docker compose file cannot be empty");
}
}
let compose_file_path = self.compose_file_path(&request.id);
if !compose_file_path.exists() {
Expand Down

0 comments on commit a6cbf4a

Please sign in to comment.