~mclehman/guestctl

850cd391f19f975f74610e658fa6f570916a2bae — 0xFORDCOMMA 4 years ago df04e7d + b2e8150
Merge branch 'master' of github-0xford:0xFORDCOMMA/guestctl
M META6.json => META6.json +2 -1
@@ 9,9 9,10 @@
    "resources" : [
        "templates/dockerfile.tmpl",
        "templates/docker-compose.tmpl",
        "templates/user.tmpl",
        "templates/sshd_config.tmpl"
    ],
    "version" : "0.0.2",
    "version" : "0.1.2",
    "production" : false,
    "perl" : "v6.*",
    "authors" : [

M bin/guestctl => bin/guestctl +32 -2
@@ 6,7 6,7 @@ use App::Guestctl::Templates;
use App::Guestctl::Utils;

# Primary main subroutine for individual guest control.
multi MAIN($guest, GuestAction $action) {
multi MAIN($guest, GuestAction $action, *@args) {
    # Run remotely if properly configured to do so.
    given %*ENV<GUEST_REMOTE_HOST GUEST_REMOTE_EXE> {
        when *.all.defined {


@@ 48,6 48,36 @@ multi MAIN($guest, GuestAction $action) {
            transparent-run <docker-compose restart>, cwd => $guest-dir;
        }

        when (Snapshots, Any) {
            my @snapshots = run(<<docker image list>>, :out).out.slurp.lines.grep(/'guest-' $guest/)>>.split('  ', :skip-empty);
            .say for @snapshots>>[1,3].grep({ .head ~~ /\d+/ }).map: -> ($tag, $time) { $tag ~ "\t" ~ $time };
        }

        when (Rollback, Any) {
            my $rollback-image = "guest-" ~ $guest ~ ":" ~ @args.head;
            my $live-image = "guest-" ~ $guest ~ ":live";
            transparent-run <<docker tag $rollback-image $live-image>>, :proceed;
            transparent-run <<docker-compose up -d --force-recreate>>, cwd => $guest-dir;
        }

        when (Connect, Running) {
            my $container-id = run(<<docker-compose ps -q $guest>>, :out, cwd => $guest-dir).out.slurp.chomp;
            my $user = "$guest-dir/user".IO.slurp.chomp;
            my $home-dir = "/home/$user";
            run <<docker exec -it -u $user -w $home-dir $container-id bash>>;
        }

        when (Commit, Running) {
            my $container-id = run(<<docker-compose ps -q $guest>>, :out, cwd => $guest-dir).out.slurp.chomp;
            my $commit-epoch-time = now.to-posix.head.Int;
            my $committed-image = "guest-" ~ $guest ~ ":" ~ $commit-epoch-time;
            my $live-image = "guest-" ~ $guest ~ ":live";
            note qq{Committing guest "$guest" to image $committed-image.};
            transparent-run <<docker commit $container-id $committed-image>>, :proceed;
            transparent-run <<docker tag $committed-image $live-image>>, :proceed;
            transparent-run <<docker-compose up -d>>, cwd => $guest-dir;
        }

        default {
            # Show status, either because it was requested or because the requested action is invalid.
            # Since type-checking MAIN guarantees that a valid command was received, this does not have to be an unknown command catch-all.


@@ 105,7 135,7 @@ multi MAIN("new", $guest) {
                             prompt     => "Guest username: "
                         },
                         {
                             key        => "password",
                             key        => "temporarypassword",
                             prompt     => "(populates dockerfile, change immediately on getting access)\nGuest password: "
                         },
                         {

M lib/App/Guestctl/Common.pm6 => lib/App/Guestctl/Common.pm6 +8 -4
@@ 9,10 9,14 @@ enum GuestStatus is export
     Stopped => "down");

enum GuestCommand is export
    (Up      => "up",
     Down    => "down",
     Restart => "restart",
     Status  => "status");
    (Up        => "up",
     Down      => "down",
     Restart   => "restart",
     Status    => "status",
	 Commit    => "commit",
     Snapshots => "snapshots",
     Rollback  => "rollback",
     Connect   => "connect");

enum ManageCommand is export
    (Update  => "update",

M lib/App/Guestctl/Templates.pm6 => lib/App/Guestctl/Templates.pm6 +1 -0
@@ 38,6 38,7 @@ sub gen-template-vars(@prompt-entries, $guest) is export {
sub load-template-files($template-dir) is export {
    return ("Dockerfile"         => %?RESOURCES<templates/dockerfile.tmpl>.slurp,
            "docker-compose.yml" => %?RESOURCES<templates/docker-compose.tmpl>.slurp,
            "user"               => %?RESOURCES<templates/user.tmpl>.slurp,
            "ssh/sshd_config"    => %?RESOURCES<templates/sshd_config.tmpl>.slurp);
}


M resources/templates/docker-compose.tmpl => resources/templates/docker-compose.tmpl +0 -7
@@ 7,10 7,3 @@ services:
    restart: unless-stopped
    ports:
      - "{{ ssh_port }}:22"
    volumes:
      - type: volume
        source: guest-{{ guest }}
        target: /home/{{ user }}

volumes:
  guest-{{ guest }}:

A resources/templates/user.tmpl => resources/templates/user.tmpl +1 -0
@@ 0,0 1,1 @@
{{ user }}