Skip to content

Commit

Permalink
add hybrid deployments via rsync (#8)
Browse files Browse the repository at this point in the history
* implement hybrid deployments via rsync

* final fixes

* missing awaits
  • Loading branch information
nomo-app authored Feb 21, 2024
1 parent cad0145 commit 3b9ff6f
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 25 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,19 @@ const nomoCliConfig = {
/**
* sshBaseDir is a remote-directory for deploying your WebOn.
*/
sshBaseDir: "/var/www/production_webons/${webon_id}",
sshBaseDir: "/var/www/production_webons/my_webon",

/**
* publicBaseUrl is a URL where sshBaseDir gets exposed to the Internet.
* publicBaseUrl is needed to generate a deeplink for installing your WebOn.
* For example, you could configure an nginx-server to map sshBaseDir to a publicBaseUrl.
*/
publicBaseUrl: "https://w.nomo.app/${webon_id}",
publicBaseUrl: "https://w.nomo.app/my_webon",

/**
* If true, the WebOn will be deployed both as a tar.gz as well as a normal website.
*/
hybrid: true,
},
},
staging: {
Expand All @@ -82,8 +87,8 @@ const nomoCliConfig = {
* sshHost could be taken from an environment-variable to hide your target IP address.
*/
sshHost: process.env.SSH_TARGET,
sshBaseDir: "/var/www/staging_webons/${webon_id}",
publicBaseUrl: "https://staging.nomo.app/${webon_id}",
sshBaseDir: "/var/www/staging_webons/my_webon",
publicBaseUrl: "https://staging.nomo.app/my_webon",

/**
* Optional. The default sshPort is 22.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nomo-webon-cli",
"version": "0.1.8",
"version": "0.1.9",
"description": "A CLI for building and deploying Nomo WebOns",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion src/deploy-webon/deploy-webon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function deployWebOn(args: {
await logs();
await connectAndDeploy({ rawSSH, deployTarget, archive });
} catch (e) {
logFatal("Failed to connect to SSH" + e);
logFatal("SSH-deployment failed: " + e);
}

async function logs() {
Expand Down
1 change: 1 addition & 0 deletions src/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function generateNomoCliConfigContent({
sshHost: "root@<IP-address>",
sshBaseDir: `/var/www/production_webons/${pathSuggestion}/`,
publicBaseUrl: `https://w.nomo.app/${pathSuggestion}`,
hybrid: true,
},
},
staging: {
Expand Down
3 changes: 2 additions & 1 deletion src/init/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export interface RawSSHConfig {
sshHost: string;
sshBaseDir: string;
publicBaseUrl: string;
sshPort?: number; // Make the sshPort optional
sshPort?: number;
hybrid?: boolean;
}

export interface DeployTargetConfig {
Expand Down
17 changes: 15 additions & 2 deletions src/services/ssh-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getCachedNomoIconPath,
getCachedNomoManifestPath,
clearCache,
getCachedOutDirectory,
} from "../util/extract-tar-gz";
import { NomoConfigValidator } from "../util/validate-nomo-config";
import { manifestChecks } from "../util/validate-manifest";
Expand Down Expand Up @@ -51,9 +52,21 @@ export async function connectAndDeploy(args: {
}
}

if (args.rawSSH.hybrid) {
console.log(
"Finished tar.gz-deployment. Starting hybrid deployment via rsync..."
);
const webAssetsPath = getCachedOutDirectory();
const cmd = sshOperations.rsyncDeployment({
webAssetsPath,
sshConfig: args.rawSSH,
});
await runCommand({ cmd });
}

const deploymentText = `Deployment successful! Your WebOn has been deployed to the following deeplink:`;

const webonUrl = `${publicBaseUrl.trim()}/nomo.tar.gz`;
const webonUrl = `${publicBaseUrl.trim()}`;
const deeplink = webonUrl
.replace("http://", "http://nomo.app/webon/")
.replace("https://", "https://nomo.app/webon/");
Expand Down Expand Up @@ -111,7 +124,7 @@ async function validateDeploymentConfig(deployTarget: string, rawSSH: any) {
}
}

manifestChecks({
await manifestChecks({
manifestFilePath: manifestPath,
serverWebOnVersion,
serverWebOnId,
Expand Down
25 changes: 13 additions & 12 deletions src/services/ssh-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class SSHOperations {
sshConfig: RawSSHConfig;
}) {
const manifestDeployCommand = this.scpCommand({
filePath: filePath,
filePath,
sshConfig,
});
// Rename the file to "manifest" on the remote server
Expand All @@ -77,8 +77,16 @@ export class SSHOperations {
return `${manifestDeployCommand} && ${renameManifestCommand}`;
}

public executeCommand({ command }: { command: string }): string {
return command;
public rsyncDeployment({
webAssetsPath,
sshConfig,
}: {
webAssetsPath: string;
sshConfig: RawSSHConfig;
}) {
const rsyncSourcePath = webAssetsPath + "/"; // the behavior of rsync is different with and without trailing slash!
const rsyncTargetPath = sshConfig.sshBaseDir;
return `rsync -avz --progress ${rsyncSourcePath} ${sshConfig.sshHost}:${rsyncTargetPath}`;
}

public getRemoteManifest({
Expand All @@ -87,18 +95,11 @@ export class SSHOperations {
remoteManifestPath: string;
}) {
const catManifestCommand = `${this.sshConnect} "[ -e ${remoteManifestPath} ] && cat ${remoteManifestPath} || echo 'not_found'"`;
return this.executeCommand({ command: catManifestCommand });
return catManifestCommand;
}

public checkSshBaseDirExists({ sshBaseDir }: { sshBaseDir: string }) {
const checkDirCommand = `${this.sshConnect} "[ -d ${sshBaseDir} ] && echo 'sshDir exists' || echo 'not_found'"`;
return this.executeCommand({ command: checkDirCommand });
return checkDirCommand;
}
}

export function executeCommand(
command: string,
sshCommands: SSHOperations
): string {
return sshCommands.executeCommand({ command });
}
7 changes: 6 additions & 1 deletion src/util/extract-tar-gz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export function getCachedIndexHtmlPath(): string {
return path;
}

export function getCachedOutDirectory(): string {
const path = resolve(cacheOutDirectory);
return path;
}

export function getCachedNomoIconPath(): string {
const path = join(resolve(cacheOutDirectory), "nomo_icon.svg");
return path;
Expand All @@ -72,7 +77,7 @@ export function clearCache() {
const cacheOutPath = resolve(cacheOutDirectory);

if (!existsSync(cachePath)) {
mkdirSync(cachePath);
return;
}

try {
Expand Down
2 changes: 1 addition & 1 deletion src/util/validate-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export async function manifestChecks({
}): Promise<void> {
const nomoManifestContent = fs.readFileSync(manifestFilePath, "utf-8");
const nomoManifest: NomoManifest = JSON.parse(nomoManifestContent);
validateManifest({
await validateManifest({
manifest: nomoManifest,
serverWebOnVersion,
serverWebOnId,
Expand Down

0 comments on commit 3b9ff6f

Please sign in to comment.