X-Git-Url: https://git.proxmox.com/?p=pve-client.git;a=blobdiff_plain;f=PVE%2FAPIClient%2FCommands%2Flxc.pm;h=4e76f70fce4bfc696f1ec7b6f19e46b42497bae2;hp=650b6b5273e9cdf8cfa9f052afa5659a2aebf090;hb=7acede2069649648c7b87de6db792ca3f17ac594;hpb=8a58c00176a3a90c19046d075a23e74c6fc640b6 diff --git a/PVE/APIClient/Commands/lxc.pm b/PVE/APIClient/Commands/lxc.pm index 650b6b5..4e76f70 100644 --- a/PVE/APIClient/Commands/lxc.pm +++ b/PVE/APIClient/Commands/lxc.pm @@ -149,6 +149,16 @@ my $full_write = sub { return $len; }; +# Takes an escape character with an optional '^' prefix and returns an escape +# character code. +my $escapekey_to_char = sub { + my ($def) = @_; + if ($def =~ /^\^?([a-zA-Z])$/) { + return 1 + ord(lc($1)) - ord('a'); + } + die "bad escape key definition: $def\n"; +}; + __PACKAGE__->register_method ({ name => 'enter', path => 'enter', @@ -158,10 +168,7 @@ __PACKAGE__->register_method ({ additionalProperties => 0, properties => { remote => get_standard_option('pveclient-remote-name'), - vmid => { - description => "The container ID", - type => 'string', - }, + vmid => get_standard_option('pve-vmid') }, }, returns => { type => 'null'}, @@ -171,6 +178,9 @@ __PACKAGE__->register_method ({ my $config = PVE::APIClient::Config->load(); my $conn = PVE::APIClient::Config->remote_conn($config, $param->{remote}); + # FIXME: This should come from $config + my $escape_char = $escapekey_to_char->('a'); + # Get the real node from the resources endpoint my $resource_list = $conn->get("api2/json/cluster/resources", { type => 'vm'}); my ($resource) = grep { $_->{type} eq "lxc" && $_->{vmid} eq $param->{vmid}} @$resource_list; @@ -202,7 +212,9 @@ __PACKAGE__->register_method ({ my $wb_socket_read_available_bytes = sub { my $nr = $web_socket->sysread($wsbuf, $max_payload_size, length($wsbuf)); - die "web socket read error - $!\n" if $nr < 0; + if (!defined($nr) && !($! == EINTR || $! == EAGAIN)) { + die "web socket read error - $!\n"; + } return $nr; }; @@ -258,14 +270,15 @@ __PACKAGE__->register_method ({ # And set it to non-blocking so we can every char with IO::Select. STDIN->blocking(0); - $web_socket->blocking(1); + STDOUT->blocking(0); + $web_socket->blocking(0); $read_select->add($web_socket); my $input_fh = \*STDIN; $read_select->add($input_fh); my $output_fh = \*STDOUT; - my $ctrl_a_pressed_before = 0; + my $in_escape_sequence; my $winch_received = 0; $SIG{WINCH} = sub { $winch_received = 1; }; @@ -289,7 +302,7 @@ __PACKAGE__->register_method ({ my $len = length($$buffer_ref); my $nr = syswrite($fh, $$buffer_ref); if (!defined($nr)) { - next if $! == EINTR || $! == EAGAIN; + return if $! == EINTR || $! == EAGAIN; die "drain buffer - write error - $!\n"; } return $nr if !$nr; @@ -318,7 +331,7 @@ __PACKAGE__->register_method ({ my $nr = $wb_socket_read_available_bytes->(); if (!defined($nr)) { - die "web socket read error $!\n"; + # wait } elsif ($nr == 0) { return; # EOF } else { @@ -341,11 +354,27 @@ __PACKAGE__->register_method ({ my $char = ord($buff); - # check for CTRL-a-q - return if $ctrl_a_pressed_before == 1 && $char == hex("0x71"); - - $ctrl_a_pressed_before = ($char == hex("0x01") && $ctrl_a_pressed_before == 0) ? 1 : 0; + # Handle escape sequences: + if ($in_escape_sequence) { + $in_escape_sequence = 0; + if ($char == 0x71) { + # (escape, 'q') + return; + } elsif ($char == $escape_char) { + # (escape, escape) + # Pass this one through as a single escapekey + } else { + # Unknown escape sequence + # We could generate a bell or something... + # but for now just skip it + next; + } + } elsif ($char == $escape_char) { + $in_escape_sequence = 1; + next; + } + # Pass the key through: $websock_buffer .= $create_websockt_frame->("0:" . $nr . ":" . $buff); $write_select->add($web_socket); } @@ -387,29 +416,8 @@ __PACKAGE__->register_method ({ return undef; }}); -__PACKAGE__->register_method ({ - name => 'list', - path => 'list', - method => 'GET', - description => "List containers.", - parameters => { - additionalProperties => 0, - properties => { - remote => get_standard_option('pveclient-remote-name'), - }, - }, - returns => { type => 'null'}, - code => sub { - my ($param) = @_; - - die "implement me"; - - }}); - - our $cmddef = { enter => [ __PACKAGE__, 'enter', ['remote', 'vmid']], - list => [ __PACKAGE__, 'list', ['remote']], }; 1;