mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 20:40:26 +08:00
优化节点创建流程
This commit is contained in:
@@ -71,6 +71,10 @@ func (this *RPCClient) NodeGrantRPC() pb.NodeGrantServiceClient {
|
||||
return pb.NewNodeGrantServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeLoginRPC() pb.NodeLoginServiceClient {
|
||||
return pb.NewNodeLoginServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeClusterRPC() pb.NodeClusterServiceClient {
|
||||
return pb.NewNodeClusterServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CreateNodeAction 创建节点
|
||||
@@ -67,6 +69,22 @@ func (this *CreateNodeAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["dnsRoutes"] = dnsRouteMaps
|
||||
|
||||
// API节点列表
|
||||
apiNodesResp, err := this.RPC().APINodeRPC().FindAllEnabledAPINodes(this.AdminContext(), &pb.FindAllEnabledAPINodesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
apiNodes := apiNodesResp.Nodes
|
||||
apiEndpoints := []string{}
|
||||
for _, apiNode := range apiNodes {
|
||||
if !apiNode.IsOn {
|
||||
continue
|
||||
}
|
||||
apiEndpoints = append(apiEndpoints, apiNode.AccessAddrs...)
|
||||
}
|
||||
this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\""
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -174,5 +192,56 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建节点 %d", nodeId)
|
||||
|
||||
// 响应数据
|
||||
this.Data["nodeId"] = nodeId
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: nodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if nodeResp.Node != nil {
|
||||
var addresses = []string{}
|
||||
for _, addrMap := range ipAddresses {
|
||||
addresses = append(addresses, addrMap.GetString("ip"))
|
||||
}
|
||||
|
||||
var grantMap maps.Map = nil
|
||||
grantId := params.GrantId
|
||||
if grantId > 0 {
|
||||
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if grantResp.NodeGrant != nil && grantResp.NodeGrant.Id > 0 {
|
||||
grantMap = maps.Map{
|
||||
"id": grantResp.NodeGrant.Id,
|
||||
"name": grantResp.NodeGrant.Name,
|
||||
"method": grantResp.NodeGrant.Method,
|
||||
"methodName": grantutils.FindGrantMethodName(grantResp.NodeGrant.Method),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": nodeResp.Node.Id,
|
||||
"name": nodeResp.Node.Name,
|
||||
"uniqueId": nodeResp.Node.UniqueId,
|
||||
"secret": nodeResp.Node.Secret,
|
||||
"addresses": addresses,
|
||||
"login": maps.Map{
|
||||
"id": 0,
|
||||
"name": "SSH",
|
||||
"type": "ssh",
|
||||
"params": maps.Map{
|
||||
"grantId": params.GrantId,
|
||||
"host": params.SshHost,
|
||||
"port": params.SshPort,
|
||||
},
|
||||
},
|
||||
"grant": grantMap,
|
||||
}
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type CreateNodeInstallAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CreateNodeInstallAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
SshHost string
|
||||
SshPort int
|
||||
GrantId int64
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("安装节点 %d", params.NodeId)
|
||||
|
||||
params.Must.
|
||||
Field("sshHost2", params.SshHost).
|
||||
Require("请填写SSH主机地址").
|
||||
Field("sshPort2", params.SshPort).
|
||||
Gt(0, "请填写SSH主机端口").
|
||||
Lt(65535, "SSH主机端口需要小于65535").
|
||||
Field("grantId", params.GrantId).
|
||||
Gt(0, "请选择SSH登录认证")
|
||||
|
||||
// 查询login
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var node = nodeResp.Node
|
||||
if node == nil {
|
||||
this.Fail("找不到要修改的节点")
|
||||
}
|
||||
var loginId int64
|
||||
if node.NodeLogin != nil {
|
||||
loginId = node.NodeLogin.Id
|
||||
}
|
||||
|
||||
// 修改节点信息
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeLogin(this.AdminContext(), &pb.UpdateNodeLoginRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeLogin: &pb.NodeLogin{
|
||||
Id: loginId,
|
||||
Name: "SSH",
|
||||
Type: "ssh",
|
||||
Params: maps.Map{
|
||||
"grantId": params.GrantId,
|
||||
"host": params.SshHost,
|
||||
"port": params.SshPort,
|
||||
}.AsJSON(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 开始安装
|
||||
_, err = this.RPC().NodeRPC().InstallNode(this.AdminContext(), &pb.InstallNodeRequest{NodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.Fail("安装失败:" + err.Error())
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -27,9 +27,11 @@ func init() {
|
||||
Post("/upgradeStatus", new(UpgradeStatusAction)).
|
||||
GetPost("/delete", new(DeleteAction)).
|
||||
GetPost("/createNode", new(CreateNodeAction)).
|
||||
Post("/createNodeInstall", new(CreateNodeInstallAction)).
|
||||
GetPost("/createBatch", new(CreateBatchAction)).
|
||||
GetPost("/updateNodeSSH", new(UpdateNodeSSHAction)).
|
||||
GetPost("/installManual", new(InstallManualAction)).
|
||||
Post("/suggestLoginPorts", new(SuggestLoginPortsAction)).
|
||||
|
||||
// 节点相关
|
||||
Prefix("/clusters/cluster/node").
|
||||
@@ -58,7 +60,6 @@ func init() {
|
||||
// 看板相关
|
||||
Prefix("/clusters/cluster/boards").
|
||||
Get("", new(boards.IndexAction)).
|
||||
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 安装节点
|
||||
// InstallAction 安装节点
|
||||
type InstallAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (this *InstallAction) RunGet(params struct {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
// 开始安装
|
||||
// RunPost 开始安装
|
||||
func (this *InstallAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type SuggestLoginPortsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SuggestLoginPortsAction) RunPost(params struct {
|
||||
Host string
|
||||
}) {
|
||||
portsResp, err := this.RPC().NodeLoginRPC().FindNodeLoginSuggestPorts(this.AdminContext(), &pb.FindNodeLoginSuggestPortsRequest{Host: params.Host})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(portsResp.Ports) == 0 {
|
||||
this.Data["ports"] = []int32{}
|
||||
} else {
|
||||
this.Data["ports"] = portsResp.Ports
|
||||
}
|
||||
|
||||
if len(portsResp.AvailablePorts) == 0 {
|
||||
this.Data["availablePorts"] = []int32{}
|
||||
} else {
|
||||
this.Data["availablePorts"] = portsResp.AvailablePorts
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -16,21 +16,24 @@ Vue.component("grant-selector", {
|
||||
if (that.grantId > 0) {
|
||||
that.grant = resp.data.grant;
|
||||
}
|
||||
that.notifyUpdate()
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
// 创建授权
|
||||
create: function () {
|
||||
let that = this
|
||||
teaweb.popup("/clusters/grants/createPopup", {
|
||||
height: "26em",
|
||||
callback: (resp) => {
|
||||
this.grantId = resp.data.grant.id;
|
||||
if (this.grantId > 0) {
|
||||
this.grant = resp.data.grant;
|
||||
that.grantId = resp.data.grant.id;
|
||||
if (that.grantId > 0) {
|
||||
that.grant = resp.data.grant;
|
||||
}
|
||||
that.notifyUpdate()
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
// 修改授权
|
||||
@@ -39,18 +42,24 @@ Vue.component("grant-selector", {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
let that = this
|
||||
teaweb.popup("/clusters/grants/updatePopup?grantId=" + this.grant.id, {
|
||||
height: "26em",
|
||||
callback: (resp) => {
|
||||
this.grant = resp.data.grant;
|
||||
that.grant = resp.data.grant
|
||||
that.notifyUpdate()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 删除已选择授权
|
||||
remove: function () {
|
||||
this.grant = null;
|
||||
this.grantId = 0;
|
||||
this.grant = null
|
||||
this.grantId = 0
|
||||
this.notifyUpdate()
|
||||
},
|
||||
notifyUpdate: function () {
|
||||
this.$emit("change", this.grant)
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
|
||||
60
web/public/js/components/node/node-login-suggest-ports.js
Normal file
60
web/public/js/components/node/node-login-suggest-ports.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// 节点登录推荐端口
|
||||
Vue.component("node-login-suggest-ports", {
|
||||
data: function () {
|
||||
return {
|
||||
ports: [],
|
||||
availablePorts: [],
|
||||
autoSelected: false,
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reload: function (host) {
|
||||
let that = this
|
||||
this.autoSelected = false
|
||||
this.isLoading = true
|
||||
Tea.action("/clusters/cluster/suggestLoginPorts")
|
||||
.params({
|
||||
host: host
|
||||
})
|
||||
.success(function (resp) {
|
||||
if (resp.data.availablePorts != null) {
|
||||
that.availablePorts = resp.data.availablePorts
|
||||
if (that.availablePorts.length > 0) {
|
||||
that.autoSelectPort(that.availablePorts[0])
|
||||
that.autoSelected = true
|
||||
}
|
||||
}
|
||||
if (resp.data.ports != null) {
|
||||
that.ports = resp.data.ports
|
||||
if (that.ports.length > 0 && !that.autoSelected) {
|
||||
that.autoSelectPort(that.ports[0])
|
||||
that.autoSelected = true
|
||||
}
|
||||
}
|
||||
})
|
||||
.done(function () {
|
||||
that.isLoading = false
|
||||
})
|
||||
.post()
|
||||
},
|
||||
selectPort: function (port) {
|
||||
this.$emit("select", port)
|
||||
},
|
||||
autoSelectPort: function (port) {
|
||||
this.$emit("auto-select", port)
|
||||
}
|
||||
},
|
||||
template: `<span>
|
||||
<span v-if="isLoading">正在检查端口...</span>
|
||||
<span v-if="availablePorts.length > 0">
|
||||
推荐端口:<a href="" v-for="port in availablePorts" @click.prevent="selectPort(port)" class="ui label tiny basic blue" style="border: 1px #2185d0 dashed; font-weight: normal">{{port}}</a>
|
||||
|
||||
</span>
|
||||
<span v-if="ports.length > 0">
|
||||
常用端口:<a href="" v-for="port in ports" @click.prevent="selectPort(port)" class="ui label tiny basic blue" style="border: 1px #2185d0 dashed; font-weight: normal">{{port}}</a>
|
||||
</span>
|
||||
<span v-if="ports.length == 0">常用端口有22等。</span>
|
||||
<span v-if="ports.length > 0" class="grey small">(可以点击要使用的端口)</span>
|
||||
</span>`
|
||||
})
|
||||
@@ -4,4 +4,10 @@
|
||||
.right-box {
|
||||
top: 10em;
|
||||
}
|
||||
.row {
|
||||
line-height: 4;
|
||||
}
|
||||
.step.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
/*# sourceMappingURL=createNode.css.map */
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["createNode.less"],"names":[],"mappings":"AAAA;EACC,SAAA;;AAGD;EACC,SAAA","file":"createNode.css"}
|
||||
{"version":3,"sources":["createNode.less"],"names":[],"mappings":"AAAA;EACC,SAAA;;AAGD;EACC,SAAA;;AAGD;EACC,cAAA;;AAGD,KAAK;EACJ,iBAAA","file":"createNode.css"}
|
||||
@@ -1,9 +1,23 @@
|
||||
{$layout}
|
||||
{$template "/clusters/cluster/menu"}
|
||||
{$template "/left_menu"}
|
||||
{$template "/code_editor"}
|
||||
|
||||
<div class="right-box">
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<div class="ui steps small fluid">
|
||||
<div class="ui step" :class="{active: step == 'info'}">
|
||||
<div class="content">1. 填写节点信息</div>
|
||||
</div>
|
||||
<div class="ui step" :class="{active: step == 'install'}">
|
||||
<div class="content">2. 安装节点</div>
|
||||
</div>
|
||||
<div class="ui step" :class="{active: step == 'finish'}">
|
||||
<div class="content">3. 完成</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 填写信息 -->
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success" v-show="step == 'info'">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
@@ -51,7 +65,7 @@
|
||||
<td>SSH主机地址</td>
|
||||
<td>
|
||||
<input type="text" name="sshHost" maxlength="64"/>
|
||||
<p class="comment">比如192.168.1.100</p>
|
||||
<p class="comment">比如192.168.1.100,用于远程安装节点应用程序。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -69,6 +83,86 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
<submit-btn>下一步</submit-btn>
|
||||
</form>
|
||||
|
||||
<!-- 安装节点 -->
|
||||
<div v-if="step == 'install'">
|
||||
<div class="ui tabular menu">
|
||||
<a href="" class="item" :class="{active: installMethod == 'remote'}" @click.prevent="switchInstallMethod('remote')">远程安装</a>
|
||||
<a href="" class="item" :class="{active: installMethod == 'manual'}" @click.prevent="switchInstallMethod('manual')">手动安装</a>
|
||||
</div>
|
||||
|
||||
<!-- 远程安装 -->
|
||||
<div v-if="installMethod == 'remote'">
|
||||
<form class="ui form">
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">SSH主机地址 *</td>
|
||||
<td>
|
||||
<input type="text" name="sshHost2" maxlength="64" v-model="sshHost" ref="installSSHHostRef" style="width: 16em" @change="changeSSHHost"/>
|
||||
<div v-if="node.addresses != null && node.addresses.length > 1" style="margin-top: 1em">
|
||||
<a href="" class="ui label small basic" v-for="addr in node.addresses" title="点击使用" @click.prevent="selectSSHHost(addr)">{{addr}}</a>
|
||||
</div>
|
||||
<p class="comment">比如192.168.1.100,用于远程安装节点应用程序。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SSH主机端口 *</td>
|
||||
<td>
|
||||
<input type="text" name="sshPort2" maxlength="5" v-model="sshPort" style="width:5em"/>
|
||||
<p class="comment"><node-login-suggest-ports ref="nodeLoginSuggestPortsRef" @select="selectLoginPort" @auto-select="autoSelectLoginPort"></node-login-suggest-ports></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SSH登录认证 *</td>
|
||||
<td>
|
||||
<grant-selector :v-grant="node.grant" @change="changeGrant"></grant-selector>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<div v-if="installStatus != null && (installStatus.isRunning || installStatus.isFinished)"
|
||||
class="ui segment installing-box">
|
||||
<div v-if="installStatus.isRunning" class="blue">安装中...</div>
|
||||
<div v-if="installStatus.isFinished">
|
||||
<span v-if="installStatus.isOk" class="green">已安装成功</span>
|
||||
<span v-if="!installStatus.isOk" class="red">安装过程中发生错误:{{installStatus.error}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="ui primary button" type="button" @click.prevent="install" v-if="!isInstalling">远程安装</button>
|
||||
<button class="ui button disabled" v-if="isInstalling">正在安装</button>
|
||||
<a href="" @click.prevent="finish" v-if="!isInstalling" style="margin-left: 1em; float: right">跳过安装</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 手动安装 -->
|
||||
<div v-if="installMethod == 'manual'">
|
||||
<div class="row">在边缘节点安装目录下,复制<code-label>configs/api.template.yaml</code-label>为<code-label>configs/api.yaml</code-label>,然后修改文件里面的内容为以下内容:</div>
|
||||
<source-code-box id="rpc-code" type="text/yaml">rpc:
|
||||
endpoints: [ {{apiEndpoints}} ]
|
||||
nodeId: "{{node.uniqueId}}"
|
||||
secret: "{{node.secret}}"</source-code-box>
|
||||
<div class="row">然后再使用<code-label>bin/edge-node start</code-label>命令启动节点。</div>
|
||||
<div>
|
||||
<a href="" @click.prevent="finish" style="float: right">跳过安装</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 完成 -->
|
||||
<div v-show="step == 'finish'">
|
||||
<div>
|
||||
<div style="text-align: center; font-size: 1.4em; margin-top: 2.4em" v-if="isInstalled"><span class="green">"{{node.name}}"节点已被创建并安装成功。</span></div>
|
||||
<div style="text-align: center; font-size: 1.4em; margin-top: 2.4em" v-if="!isInstalled"><span class="green">"{{node.name}}"节点已创建成功。</span></div>
|
||||
<div style="text-align: center; margin-top: 3em">
|
||||
<a :href="'/clusters/cluster/node?nodeId=' + nodeId + '&clusterId=' + clusterId" class="ui button primary" type="button">现在进入节点详情<i class="ui icon long arrow alternate right"></i></a>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 1em">
|
||||
<a href="" @click.prevent="createNext">继续创建下一个节点</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,173 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifySuccess("保存成功", "/clusters/cluster/nodes?clusterId=" + this.clusterId);
|
||||
});
|
||||
this.nodeId = 0
|
||||
this.node = {}
|
||||
this.sshHost = ""
|
||||
this.sshPort = ""
|
||||
this.grantId = 0
|
||||
this.step = "info"
|
||||
|
||||
this.success = function (resp) {
|
||||
this.node = resp.data.node
|
||||
this.nodeId = this.node.id
|
||||
this.sshHost = this.node.login.params.host
|
||||
if (this.node.login.params.port > 0) {
|
||||
this.sshPort = this.node.login.params.port
|
||||
}
|
||||
if (this.node.addresses.length > 0) {
|
||||
this.sshHost = this.node.addresses[0]
|
||||
}
|
||||
this.step = "install"
|
||||
this.$delay(function () {
|
||||
this.$refs.installSSHHostRef.focus()
|
||||
this.$refs.nodeLoginSuggestPortsRef.reload(this.sshHost)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装
|
||||
*/
|
||||
this.isInstalled = false
|
||||
this.installMethod = "remote" // remote | manual
|
||||
this.isInstalling = false
|
||||
|
||||
this.switchInstallMethod = function (method) {
|
||||
this.installMethod = method
|
||||
}
|
||||
|
||||
this.selectSSHHost = function (host) {
|
||||
this.sshHost = host
|
||||
this.changeSSHHost()
|
||||
}
|
||||
|
||||
this.changeSSHHost = function () {
|
||||
if (this.$refs.nodeLoginSuggestPortsRef != null) {
|
||||
this.$refs.nodeLoginSuggestPortsRef.reload(this.sshHost)
|
||||
}
|
||||
}
|
||||
|
||||
this.selectLoginPort = function (port) {
|
||||
this.sshPort = port
|
||||
}
|
||||
|
||||
this.autoSelectLoginPort = function (port) {
|
||||
if (this.sshPort == null || this.sshPort <= 0) {
|
||||
this.sshPort = port
|
||||
}
|
||||
}
|
||||
|
||||
this.install = function () {
|
||||
if (this.node.grant != null) {
|
||||
this.grantId = this.node.grant.id
|
||||
}
|
||||
|
||||
this.isInstalling = true
|
||||
this.$post(".createNodeInstall")
|
||||
.params({
|
||||
nodeId: this.node.id,
|
||||
sshHost: this.sshHost,
|
||||
sshPort: this.sshPort,
|
||||
grantId: this.grantId
|
||||
})
|
||||
.timeout(30)
|
||||
.success(function () {
|
||||
this.$delay(function () {
|
||||
this.isInstalling = true
|
||||
this.reloadStatus(this.node.id)
|
||||
})
|
||||
})
|
||||
.done(function () {
|
||||
this.isInstalling = false
|
||||
})
|
||||
}
|
||||
|
||||
this.changeGrant = function (grant) {
|
||||
if (grant != null) {
|
||||
this.grantId = grant.id
|
||||
} else {
|
||||
this.grantId = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新状态
|
||||
this.installStatus = null
|
||||
this.reloadStatus = function (nodeId) {
|
||||
let that = this
|
||||
|
||||
this.$post("/clusters/cluster/node/status")
|
||||
.params({
|
||||
nodeId: nodeId
|
||||
})
|
||||
.success(function (resp) {
|
||||
this.installStatus = resp.data.installStatus
|
||||
this.node.isInstalled = resp.data.isInstalled
|
||||
if (this.node.isInstalled) {
|
||||
this.isInstalling = false
|
||||
this.isInstalled = true
|
||||
this.finish()
|
||||
}
|
||||
|
||||
if (!this.isInstalling) {
|
||||
return
|
||||
}
|
||||
|
||||
let nodeId = this.node.id
|
||||
let errMsg = this.installStatus.error
|
||||
|
||||
if (this.installStatus.errorCode.length > 0 || errMsg.length > 0) {
|
||||
this.isInstalling = false
|
||||
}
|
||||
|
||||
switch (this.installStatus.errorCode) {
|
||||
case "EMPTY_LOGIN":
|
||||
case "EMPTY_SSH_HOST":
|
||||
case "EMPTY_SSH_PORT":
|
||||
case "EMPTY_GRANT":
|
||||
teaweb.warn("需要填写SSH登录信息", function () {
|
||||
teaweb.popup("/clusters/cluster/updateNodeSSH?nodeId=" + nodeId, {
|
||||
height: "30em",
|
||||
callback: function () {
|
||||
that.install()
|
||||
}
|
||||
})
|
||||
})
|
||||
return
|
||||
case "SSH_LOGIN_FAILED":
|
||||
teaweb.warn("SSH登录失败,请检查设置")
|
||||
return
|
||||
case "CREATE_ROOT_DIRECTORY_FAILED":
|
||||
teaweb.warn("创建根目录失败,请检查目录权限或者手工创建:" + errMsg)
|
||||
return
|
||||
case "INSTALL_HELPER_FAILED":
|
||||
teaweb.warn("安装助手失败:" + errMsg)
|
||||
return
|
||||
case "TEST_FAILED":
|
||||
teaweb.warn("环境测试失败:" + errMsg)
|
||||
return
|
||||
case "RPC_TEST_FAILED":
|
||||
teaweb.confirm("html:要安装的节点到API服务之间的RPC通讯测试失败,具体错误:" + errMsg + ",<br/>现在修改API信息?", function () {
|
||||
window.location = "/api"
|
||||
})
|
||||
return
|
||||
default:
|
||||
shouldReload = true
|
||||
//teaweb.warn("安装失败:" + errMsg)
|
||||
}
|
||||
})
|
||||
.done(function () {
|
||||
this.$delay(function () {
|
||||
this.reloadStatus(nodeId)
|
||||
}, 1000)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成
|
||||
*/
|
||||
this.finish = function () {
|
||||
this.step = "finish"
|
||||
}
|
||||
|
||||
this.createNext = function () {
|
||||
teaweb.reload()
|
||||
}
|
||||
})
|
||||
@@ -4,4 +4,12 @@
|
||||
|
||||
.right-box {
|
||||
top: 10em;
|
||||
}
|
||||
|
||||
.row {
|
||||
line-height: 4;
|
||||
}
|
||||
|
||||
.step.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
Reference in New Issue
Block a user