RunCommand——云助手从2.0迈入1.0时代-阿里云开发者社区

开发者社区> 开发与运维> 正文

RunCommand——云助手从2.0迈入1.0时代

简介: # 摘要 是的,你没有看错![云助手](https://help.aliyun.com/document_detail/64601.html?spm=ata.13261165.0.0.2e27228etjeGVx)RunCommand API发布,执行云助手命令从需要先创建命令([CreateCommand](https://help.aliyun.com/document_detail/648

摘要

是的,你没有看错!云助手RunCommand API发布,执行云助手命令从需要先创建命令(CreateCommand)再执行命令(InvokeCommand)的“二点灵”时代,进入了只需一次RunCommand的“一点灵”时代。

背景

用户在使用云助手的时候,经常会遇到以下场景。

场景一

用户:我要通过云助手去部署环境,命令无法复用,必须每次都要创建一个新的命令么?
我:是的。需要先创建一条云助手命令,再执行这条云助手命令。
用户:这么麻烦。。。

场景二

用户:我通过OpenAPI调用云助手,执行结果为乱码,为什么???
我:请确认输入的命令是否经过Base64编码,如果没有经过Base64编码的命令内容,云助手无法解析哦。
用户:不支持直接明文传递命令内容吗?
我:暂时不支持。
用户:。。。

场景三

用户:我的命令数量超过了quota,无法创建新的命令,影响了我的线上服务,怎么办???
我:亲,这边建议把不用的命令清理一下哦。
用户:???

这些场景给用户使用云助手带来了极大的不便和困扰,RunCommand的引入将有效缓解以上问题。

功能介绍

行云流水的执行流程

统计发现,超过80%的云助手命令在创建后只执行了一次,所以先创建命令、再去执行命令的方式,不仅使云助手的执行流程异常繁琐,也极大的提高了用户管理云助手命令的成本。

通过调用RunCommand,用户传入必要信息,如命令内容、目标实例ID等,即可创建并执行一条命令。当命令执行完毕、手动停止或执行失败后,命令会被自动清除,不占用用户创建命令的quota。RunCommand淡化“命令”,强调“执行”,每次RunCommand即是一次执行,可以通过DescribeInvocationsDescribeInvocationResults返回执行的结果。用户不需要关心“命令”的概念,命令执行完成后即被删除,通过DescribeCommands查询也不会返回该命令。我们希望用户能够更加简单的执行云助手命令,下图显示了云助手执行命令流程的变化:两步并为一步,而且不必担心创建命令超过限额。
RunCommand3.jpg

“一招鲜”的通用接口

RunCommand的定位,是提供一个全新的接口,覆盖掉原有逻辑中不合理的部分,所以RunCommand完全覆盖了CreateCommand的全部功能,包括命令支持自定义参数等。也就是说,今后可以用RunCommand完全代替CreateCommand去创建和执行命令。如果在执行RunCommand时,指定KeepCommand参数为true,则会在此次执行之后仍然保留命令。后续仍可以通过命令ID去执行该命令,行为上完全与CreateCommand创建的命令相同。

DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
    IAcsClient client = new DefaultAcsClient(profile);

RunCommandRequest request = new RunCommandRequest();
request.setCommandContent("echo hello");
request.setType("RunShellScript");
request.setName("test_runcommand");
List<String> instanceIdList = new ArrayList<String>();
instanceIdList.add("i-XXXX");
request.setInstanceIds(instanceIdList);
//在执行完成后保留命令
request.setKeepCommand(true);


try {
    RunCommandResponse response = client.getAcsResponse(request);
    System.out.println(new Gson().toJson(response));
} catch (ServerException e) {
    e.printStackTrace();
} catch (ClientException e) {
    System.out.println("ErrCode:" + e.getErrCode());
    System.out.println("ErrMsg:" + e.getErrMsg());
    System.out.println("RequestId:" + e.getRequestId());
}

返回结果

{
    "requestId":"B66550CC-XXXX-XXXX-XXXX-4A7195695CD2",
    "commandId":"c-XXXXXXXXXXX",
    "invokeId":"t-XXXXXXXXX"
}

通过该commandId,可以再次执行该命令,该命令会占用创建命令的quota。

所见即所得的命令内容

原有接口无论在创建还是查询时,命令内容都以Base64编码的形式呈现。云助手控制台屏蔽了这个问题,用户看到的依然是明文形式的命令。但对于阿里云CLI用户来讲,进行Base64转码是件非常麻烦的事情,可能需要自己去写代码或借助于第三方工具。创建命令的例子如下,CommandContent字段是一段长长的Base64编码,非常不直观。

aliyun ecs CreateCommand --RegionId cn-hangzhou --CommandContent ZWNobyBoZWxsbyB3b3JsZAplY2hvIGhlbGxvIFJ1bkNvbW1hbmQ= --Type RunShellScript --Name testCLI

RunCommand提供所见即所得的API,默认用户传入明文形式的命令内容,换行符用“n”表示。通过RunCommand,阿里云CLI用户可以更方便的创建命令(需要使用CLI 3.0.27以上版本)。当然,用户仍能传入Base64形式的命令内容,只需要指定ContentEncoding字段为“Base64”即可。

aliyun ecs RunCommand --RegionId cn-hangzhou --CommandContent 'echo hello world\necho hello RunCommand' --Type RunShellScript --Name testCLI --InstanceId.1 i-XXXXXX
...

执行结果
hello world
hello RunCommand

对于查询接口DescribeCommands和DescribeInvocations,为了保持兼容,返回的命令内容默认仍为Base64编码形式,但可以通过指定ContentEncoding为“PlainText”来返回明文。

//查询上面的执行记录
DescribeInvocationsRequest request = new DescribeInvocationsRequest();
request.setContentEncoding("PlainText");
...

返回结果的命令内容字段
"echo hello world;\necho hello RunCommand"

控制台使用

RunCommand对控制台的改动很小,入口仍为“创建命令”按钮,在填入命令信息后,点击“立即执行”就可以进入执行信息配置页面。
RunCommand1.jpg

选择目标执行实例,即可开始执行,同样支持单次执行和周期执行。如果选择“保留命令”,则命令会在执行完成之后被保留,并能够再次执行;否则执行完成后自动清理掉命令,节约命令管理空间。
RunCommand2.jpg

相关API

以上功能对云助手API产生了如下变化。

RunCommand

增加了RunCommand API。

  • RunCommand请求参数
名称 类型 是否必选 示例值 描述
CommandContent String echo hello 命令内容,默认采用明文方式传输。 脚本内容的大小不能超过 16 KB。
EnableParameter Boolean false 创建的命令是否携带自定义参数。 默认值:false,表示不在命令中携带自定义参数。
Type String RunShellScript 命令的类型。取值范围: BatScript:创建一个在 Windows 实例中运行的 Bat 脚本。 PowerShellScript:创建一个在 Windows 实例中运行的 PowerShell 脚本。 * ShellScript:创建一个在 Linux 实例中运行的 Shell 脚本。
Description String Test1 命令描述,支持全字符集。 长度不得超过512个字符。
Timeout Long 3600 命令在 ECS 实例中执行时最大的超时时间,单位为秒。 默认值:3600。
WorkingDir String /home 命令在 ECS 实例中运行的目录。默认值: 对于 Linux 实例,默认在管理员 root 用户的 home 目录下,具体为 /root 目录。 对于 Windows 实例,默认在云助手客户端进程所在目录,例如,C:ProgramDataaliyunassist&dollar;(version)。
InstanceId.N RepeatList i-bp185dy2o3o6nxxxxxxx 需要执行命令的实例列表,最多能指定 50 台实例 ID。 N 的取值范围为1~50。
Timed Boolean true 命令是否为周期执行。 默认值:False。
Frequency String 0 /20 * 周期任务的执行周期,两次周期任务的时间间隔不能低于10秒。 当参数 Timed 的值为 True 时,参数 Frequency 为必需参数。
Parameters Json {"name":"Jack", "accessKey":"LTAIdyvaRY"} 启用自定义参数功能时,执行命令时传入的自定义参数的键值对。
KeepCommand Boolean true 执行完毕该命令后,是否保留该命令。 默认值为false,即在每次执行后自动删除命令; 如选择保留命令,则该命令会像普通命令一样,可以通过InvokeCommand再次执行,通过DescribeCommands查询,并通过DeleteCommands删除,并会占用用户创建命令的限额。
ContentEncoding String base64 CommandContent的编码方式,默认为PlainText,表示明文传输。 取值范围(不区分大小写): PlainText:明文传输; Base64:传入Base64编码的CommandContent其余值均按照明文处理。
  • RunCommand返回参数
名称 类型 示例值 描述
CommandId String c-7d2a745b412b4601b2d47f6a768dXXXX 命令 ID。 当KeepCommand为false时,该CommandId不能被再次执行, 命令也不能通过DescribeCommands接口查询。
InvokeId String t-7d2a745b412b4601b2d47f6a768dXXXX 命令执行ID
RequestId String 473469C7-AA6F-4DC5-B3DB-A3DC0DE3XXXX 请求 ID

DescribeCommands

通过RunCommand创建的命令,如果指定了KeepCommand为false,则不能通过DescribeCommands返回,如果希望查看执行情况,可以通过DescribeInvocations和DescribeInvocationResults查询。如果指定了KeepCommand为true,则与通过CreateCommand创建的命令相同。
由于RunCommand的命令可以采取多种编码方式,所以DescribeCommands的返回值也应该支持多种编码方式。为保证兼容性,默认的返回值仍为Base64编码,请求参数中加入ContentEncoding字段允许用户选择其他编码方式。

名称 类型 是否必选 示例值 描述
ContentEncoding String Base64 返回的CommandContent的编码方式,默认为Base64。取值范围(不区分大小写): PlainText:返回明文形式的CommandContent Base64:返回Base64编码的CommandContent其余值均按照Base64处理

DescribeInvocations

DescribeInvocations也会返回CommandContent信息,与DescribeCommands类似,请求参数中加入ContentEncoding字段允许用户选择其他编码方式。

名称 类型 是否必选 示例值 描述
ContentEncoding String Base64 返回的CommandContent的编码方式,默认为Base64。取值范围(不区分大小写): PlainText:返回明文形式的CommandContent Base64:返回Base64编码的CommandContent其余值均按照Base64处理

应用举例

使用RunCommand,可以以极简的方式完成命令的执行。比如我们有一台或一批实例,想要在创建实例之后安装MySQL。由于只需要安装一次,之后没有必要再保留该命令,所以很适合采用RunCommand。

DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
    IAcsClient client = new DefaultAcsClient(profile);

RunCommandRequest request = new RunCommandRequest();
request.setCommandContent("yum install mysql");
request.setType("RunShellScript");
request.setName("test_runcommand");
List<String> instanceIdList = new ArrayList<String>();
instanceIdList.add("i-XXXX");
request.setInstanceIds(instanceIdList);


try {
    RunCommandResponse response = client.getAcsResponse(request);
    System.out.println(new Gson().toJson(response));
} catch (ServerException e) {
    e.printStackTrace();
} catch (ClientException e) {
    System.out.println("ErrCode:" + e.getErrCode());
    System.out.println("ErrMsg:" + e.getErrMsg());
    System.out.println("RequestId:" + e.getRequestId());
}

总结

RunCommand的引入进一步完善了用户调用云助手的场景。对于命令内容相似,需要复用的场景,我们已经提供了命令支持自定义参数功能。而RunCommand关注于更轻量的命令执行,让用户能够更便捷、高效的执行云助手命令。
RunCommand4.jpg

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章