|
5 | 5 | "context" |
6 | 6 | "encoding/json" |
7 | 7 | "fmt" |
| 8 | + "github.com/docker/docker/api/types/container" |
| 9 | + "github.com/docker/docker/pkg/stdcopy" |
8 | 10 | "io" |
9 | 11 | "os" |
10 | 12 | "path" |
@@ -1301,6 +1303,74 @@ func (d *Deployer) getNodeOTP(ctx context.Context, clusterID string, nodeId stri |
1301 | 1303 | return "", nil |
1302 | 1304 | } |
1303 | 1305 |
|
| 1306 | +func (d *Deployer) execInContainer(ctx context.Context, containerID string, cmd []string) error { |
| 1307 | + execOpts := container.ExecOptions{ |
| 1308 | + Cmd: cmd, |
| 1309 | + AttachStdout: true, |
| 1310 | + AttachStderr: true, |
| 1311 | + Tty: false, |
| 1312 | + Privileged: false, |
| 1313 | + } |
| 1314 | + |
| 1315 | + execResp, err := d.dockerCli.ContainerExecCreate(ctx, containerID, execOpts) |
| 1316 | + if err != nil { |
| 1317 | + return fmt.Errorf("ContainerExecCreate failed: %w", err) |
| 1318 | + } |
| 1319 | + |
| 1320 | + attachResp, err := d.dockerCli.ContainerExecAttach(ctx, execResp.ID, container.ExecAttachOptions{}) |
| 1321 | + if err != nil { |
| 1322 | + return fmt.Errorf("ContainerExecAttach failed: %w", err) |
| 1323 | + } |
| 1324 | + defer attachResp.Close() |
| 1325 | + |
| 1326 | + _, err = stdcopy.StdCopy(os.Stdout, os.Stderr, attachResp.Reader) |
| 1327 | + if err != nil { |
| 1328 | + return fmt.Errorf("copying output failed: %w", err) |
| 1329 | + } |
| 1330 | + |
| 1331 | + return nil |
| 1332 | +} |
| 1333 | + |
| 1334 | +/* |
| 1335 | +KillCouchbase stops the couchbase-server process on the specified nodes. |
| 1336 | +The runSv supervisor will automatically restart couchbase-server within 10 seconds. |
| 1337 | +This method is used to simulate a stop and restart of the couchbase server. |
| 1338 | +*/ |
| 1339 | +func (d *Deployer) KillCouchbase(ctx context.Context, clusterID string, nodeIDs []string) error { |
| 1340 | + var nodeContainerIDs []string |
| 1341 | + |
| 1342 | + for _, nodeId := range nodeIDs { |
| 1343 | + node, err := d.getNode(ctx, clusterID, nodeId) |
| 1344 | + if err != nil { |
| 1345 | + return errors.Wrap(err, "failed to get node") |
| 1346 | + } |
| 1347 | + |
| 1348 | + nodeContainerIDs = append(nodeContainerIDs, node.ContainerID) |
| 1349 | + } |
| 1350 | + if len(nodeIDs) == 0 { |
| 1351 | + clusterInfo, err := d.getCluster(ctx, clusterID) |
| 1352 | + if err != nil { |
| 1353 | + return errors.Wrap(err, "failed to get cluster info") |
| 1354 | + } |
| 1355 | + |
| 1356 | + for _, node := range clusterInfo.Nodes { |
| 1357 | + nodeContainerIDs = append(nodeContainerIDs, node.ContainerID) |
| 1358 | + } |
| 1359 | + } |
| 1360 | + |
| 1361 | + for _, nodeContainerID := range nodeContainerIDs { |
| 1362 | + d.logger.Info("killing couchbase process on node", |
| 1363 | + zap.String("containerID", nodeContainerID)) |
| 1364 | + |
| 1365 | + err := d.execInContainer(ctx, nodeContainerID, []string{"pkill", "-f", "couchbase-server"}) |
| 1366 | + if err != nil { |
| 1367 | + return errors.Wrapf(err, "failed to kill couchbase process on node %s", nodeContainerID) |
| 1368 | + } |
| 1369 | + } |
| 1370 | + |
| 1371 | + return nil |
| 1372 | +} |
| 1373 | + |
1304 | 1374 | func (d *Deployer) RedeployCluster(ctx context.Context, clusterID string) error { |
1305 | 1375 | return errors.New("docker deploy does not support redeploy cluster") |
1306 | 1376 | } |
|
0 commit comments