File: //snap/google-cloud-cli/current/lib/surface/compute/instances/tail_serial_port_output.py
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for tailing the serial port output of an instance."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import time
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.instances import flags
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
class TailSerialPortOutputException(exceptions.Error):
"""An error occurred while tailing the serial port."""
class TailSerialPortOutput(base.Command):
# pylint:disable=line-too-long
"""Periodically fetch new output from a virtual machine instance's serial port and display it as it becomes available.
{command} is used to tail the output from a Compute
Engine virtual machine instance's serial port. The serial port output
from the instance will be printed to standard output. This
information can be useful for diagnostic purposes.
"""
detailed_help = {
'EXAMPLES': """
To fetch new output from instance's serial port and display it, run:
$ {command} example-instance --zone=us-central1-b
"""}
POLL_SLEEP_SECS = 10
@staticmethod
def Args(parser):
flags.INSTANCE_ARG.AddArgument(parser)
parser.add_argument(
'--port',
type=arg_parsers.BoundedInt(1, 4),
help="""\
Instances can support up to four serial port outputs, numbered 1 through
4. By default, this command will return the output of the first serial
port. Setting this flag will return the output of the requested serial
port.
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
instance_ref = flags.INSTANCE_ARG.ResolveAsResource(
args, holder.resources,
scope_lister=flags.GetInstanceZoneScopeLister(client))
start = None
while True:
request = (client.apitools_client.instances,
'GetSerialPortOutput',
client.messages.ComputeInstancesGetSerialPortOutputRequest(
instance=instance_ref.Name(),
project=instance_ref.project,
port=args.port,
start=start,
zone=instance_ref.zone))
errors = []
objects = client.MakeRequests(
requests=[request],
errors_to_collect=errors)
if errors:
raise TailSerialPortOutputException(
'Could not fetch serial port output: ' +
','.join([error[1] for error in errors]))
result = objects[0]
log.out.write(result.contents)
log.out.flush()
start = result.next
# If we didn't get any results, we sleep for a short time before the next
# call.
if not result.contents:
time.sleep(self.POLL_SLEEP_SECS)