Skip to content

Commit

Permalink
Simple implementation for a workspace sync (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
Derroylo authored Dec 31, 2023
1 parent 97b0136 commit 4eae5b7
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 2 deletions.
20 changes: 19 additions & 1 deletion Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Security.Cryptography;
using System.Text;
using Gitpod.Tool.Commands.Persist;
using Gitpod.Tool.Commands.Sync;

namespace Gitpod.Tool
{
Expand Down Expand Up @@ -87,9 +88,10 @@ static void Main(string[] args)
config.AddBranch("php", branch => AddPhpCommandBranch(branch, additionalCommands));
config.AddBranch("restore", branch => AddRestoreCommandBranch(branch, additionalCommands));
config.AddBranch("services", branch => AddServicesCommandBranch(branch, additionalCommands));
config.AddBranch("sync", branch => AddSyncCommandBranch(branch, additionalCommands));
config.AddCommand<SelfUpdateCommand>("update").WithDescription("Update this tool to the latest version");

List<string> reservedBranches = new() { "default", "config", "php", "nodejs", "apache", "mysql", "services", "restore", "environment" };
List<string> reservedBranches = new() { "default", "config", "php", "nodejs", "apache", "mysql", "services", "restore", "environment", "sync" };

// Add branches that haven´t been added yet via custom commands
foreach (KeyValuePair<string, CustomBranch> entry in additionalCommands.Where(x => !reservedBranches.Contains(x.Key))) {
Expand Down Expand Up @@ -357,5 +359,21 @@ private static void AddPersistCommandBranch(IConfigurator<CommandSettings> branc
}
}
}

private static void AddSyncCommandBranch(IConfigurator<CommandSettings> branch, Dictionary<string, CustomBranch> additionalCommands)
{
branch.SetDescription("Sync files from your local machine with a workspace or between workspaces.");

branch.AddCommand<SyncWorkspaceCommand>("workspace")
.WithDescription("Connect to another workspace and sync the content of a folder");

if (additionalCommands.TryGetValue("sync", out CustomBranch customBranch)) {
foreach (CustomCommand cmd in customBranch.Commands) {
branch.AddCommand<ShellFileCommand>(cmd.Command)
.WithData(cmd)
.WithDescription(cmd.Description);
}
}
}
}
}
154 changes: 154 additions & 0 deletions commands/sync/SyncWorkspaceCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using System.IO;
using Gitpod.Tool.Helper;
using Spectre.Console;
using Spectre.Console.Cli;

namespace Gitpod.Tool.Commands.Sync
{
class SyncWorkspaceCommand : Command<SyncWorkspaceCommand.Settings>
{
public class Settings : CommandSettings
{
}

public override int Execute(CommandContext context, Settings settings)
{
AnsiConsole.MarkupLine("Sync a folder from this machine to another workspace.");
AnsiConsole.MarkupLine("");

if (!ExecCommand.Exec("which rclone").Contains("rclone")) {
if (!AnsiConsole.Confirm("rclone needs to be installed for this function. Do you want to install it now?")) {
return 1;
}

ExecCommand.Exec("sudo -v ; curl https://rclone.org/install.sh | sudo bash");

if (!ExecCommand.Exec("which rclone").Contains("rclone")) {
AnsiConsole.MarkupLine("[red]Installation of rclone failed. You need to install it manually[/]");

return 1;
}
}

if (!ExecCommand.Exec("which inotifywait").Contains("inotifywait")) {
if (!AnsiConsole.Confirm("inotifywait needs to be installed for this function. Do you want to install it now?")) {
return 1;
}

ExecCommand.Exec("sudo -v ; curl https://rclone.org/install.sh | sudo bash");

if (!ExecCommand.Exec("which inotifywait").Contains("inotifywait")) {
AnsiConsole.MarkupLine("[red]Installation of inotifywait failed. You need to install it manually[/]");

return 1;
}
}

bool inputInvalid = false;

var workspaceHost = string.Empty;
var workspaceUser = string.Empty;
var workspaceAccessToken = string.Empty;
var localFolder = string.Empty;
var remoteFolder = string.Empty;

do {
AnsiConsole.WriteLine("Enter the url of the workspace you want to connect to.");
AnsiConsole.MarkupLine("[orange3]Info: The format should look like this: https://WORKSPACE-ID.ws-REGION.gitpod.io/[/]");

workspaceHost = AnsiConsole.Ask<string>("Host:");

if (workspaceHost == string.Empty) {
AnsiConsole.MarkupLine("[red]Enter a valid gitpod workspace url.[/]");
inputInvalid = true;
} else {
inputInvalid = false;
}
} while (inputInvalid);

do {
AnsiConsole.WriteLine("Enter the name of the user.");
AnsiConsole.MarkupLine("[orange3]Info: This is the name of the workspace[/]");

workspaceUser = AnsiConsole.Ask<string>("User:");

if (workspaceUser == string.Empty) {
AnsiConsole.MarkupLine("[red]Enter a valid user.[/]");
inputInvalid = true;
} else {
inputInvalid = false;
}
} while (inputInvalid);

do {
AnsiConsole.WriteLine("Enter the access token.");

workspaceAccessToken = AnsiConsole.Ask<string>("Access Token:");

if (workspaceAccessToken == string.Empty) {
AnsiConsole.MarkupLine("[red]Enter a valid access token.[/]");
inputInvalid = true;
} else {
inputInvalid = false;
}
} while (inputInvalid);

do {
AnsiConsole.WriteLine("Enter the local folder");
AnsiConsole.MarkupLine("[orange3]Info: This is the folder you want to sync over to the remove machine.[/]");

localFolder = AnsiConsole.Ask<string>("Local folder:");

if (localFolder == string.Empty) {
AnsiConsole.MarkupLine("[red]Enter a valid local folder.[/]");
inputInvalid = true;
} else {
inputInvalid = false;
}
} while (inputInvalid);

do {
AnsiConsole.WriteLine("Enter the remote folder");
AnsiConsole.MarkupLine("[orange3]Info: The folder on the remove machine to which you want to sync the files to.[/]");

remoteFolder = AnsiConsole.Ask<string>("Remote folder:");

if (remoteFolder == string.Empty) {
AnsiConsole.MarkupLine("[red]Enter a valid remote folder.[/]");
inputInvalid = true;
} else {
inputInvalid = false;
}
} while (inputInvalid);

var accessTokenObscured = ExecCommand.Exec("echo \"" + workspaceAccessToken + "\" | rclone obscure -");

var command = "rclone sync";

// Set local folder
command += " " + localFolder;

// Set remote folder
command += " :sftp:" + remoteFolder;

// Set Host
command += " --sftp-host " + workspaceHost;

// Set User
command += " --sftp-user " + workspaceUser;

// Set the password
command += " --sftp-pass " + accessTokenObscured;

// Set shell type
command += " --sftp-shell-type unix";

// Set hash commands
command += " --sftp-md5sum-command md5sum --sftp-sha1sum-command sha1sum";

File.WriteAllText(".sync", command);

return 0;
}
}
}
17 changes: 16 additions & 1 deletion gpt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,24 @@ if [ -f "$GPTDIR/.nodejs" ]; then
nvm alias default $version
fi

# Check if we want to change the nodejs version
# Restore env variables
if [ -f "$GPTDIR/.env_restore" ]; then
source "$GPTDIR/.env_restore"

rm "$GPTDIR/.env_restore"
fi

# Execute the sync commands
if [ -f "$GPTDIR/.sync" ]; then
syncCommand=$(<"$GPTDIR/.sync")

rm "$GPTDIR/.sync"

eval $syncCommand

inotifywait --recursive --monitor --format "%e %w%f" --event modify,move,create,delete ./ \
| while read changed; do
echo $changed
eval $syncCommand
done
fi

0 comments on commit 4eae5b7

Please sign in to comment.