Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Fixed

- ``tt cartridge`` command takes into account run dir path from the `tt` environment. So most
of the `tt cartridge` sub-commands are able to work without specifying `--run-dir` option.

## [1.0.1] - 2023-04-04

### Added
Expand Down
66 changes: 66 additions & 0 deletions cli/cartridge/extra/006_consider_tt_run_dir.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
diff --git a/cli/commands/admin.go b/cli/commands/admin.go
index 71b8f4f..e83efc0 100644
--- a/cli/commands/admin.go
+++ b/cli/commands/admin.go
@@ -1,6 +1,7 @@
package commands

import (
+ "os"
"path/filepath"
"strings"

@@ -8,6 +9,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/tarantool/cartridge-cli/cli/admin"
+ "github.com/tarantool/cartridge-cli/cli/project"
)

var CartridgeCliAdmin *cobra.Command
@@ -74,6 +76,11 @@ func runAdminCommand(cmd *cobra.Command, args []string) error {
return err
}
ctx.Running.RunDir = abspath
+ } else {
+ runDir := os.Getenv(project.EnvRunDir)
+ if runDir != "" {
+ ctx.Running.RunDir = filepath.Join(runDir, ctx.Project.Name)
+ }
}

// log level is usually set in rootCmd.PersistentPreRun
diff --git a/cli/project/project.go b/cli/project/project.go
index 2eed9cb..3d3a995 100644
--- a/cli/project/project.go
+++ b/cli/project/project.go
@@ -12,6 +12,7 @@ import (
)

const EnvInstEnabled = "TT_INST_ENABLED"
+const EnvRunDir = "TT_RUN_DIR"

func FillCtx(ctx *context.Ctx) error {
var err error
@@ -30,7 +31,20 @@ func FillCtx(ctx *context.Ctx) error {

instEnabled := os.Getenv(EnvInstEnabled)
if instEnabled != "" {
- ctx.Running.AppDir = filepath.Join(instEnabled, ctx.Project.Name)
+ if instEnabled == "." {
+ ctx.Running.AppDir, err = os.Getwd()
+ if err != nil {
+ return fmt.Errorf("Failed to get current directory: %s", err)
+ }
+ } else {
+ ctx.Running.AppDir = filepath.Join(instEnabled, ctx.Project.Name)
+ }
+ }
+
+ runDir := os.Getenv(EnvRunDir)
+ if runDir != "" {
+ appName := filepath.Base(ctx.Running.AppDir)
+ ctx.Running.RunDir = filepath.Join(runDir, appName)
}

ctx.Replicasets.File = filepath.Join(ctx.Running.AppDir, "replicasets.yml")
1 change: 1 addition & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ func InitRoot() {
// Required for cartridge.
if cliOpts.App != nil {
os.Setenv("TT_INST_ENABLED", cliOpts.App.InstancesEnabled)
os.Setenv("TT_RUN_DIR", cliOpts.App.RunDir)
}

// Getting modules information.
Expand Down
3 changes: 2 additions & 1 deletion cli/configure/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ func updateCliOpts(cliOpts *config.CliOpts, configDir string) error {

if cliOpts.App.InstancesEnabled == "" {
cliOpts.App.InstancesEnabled = "."
} else if cliOpts.App.InstancesEnabled != "." {
} else if cliOpts.App.InstancesEnabled != "." || (cliOpts.App.InstancesEnabled == "." &&
!util.IsApp(configDir)) {
if cliOpts.App.InstancesEnabled, err =
adjustPathWithConfigLocation(cliOpts.App.InstancesEnabled, configDir, ""); err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func PatchCC() error {
"003_fix_work_paths.patch",
"004_fix_warning.patch",
"005_rename_tt_env.patch",
"006_consider_tt_run_dir.patch",
}

for _, patch := range patches {
Expand Down
172 changes: 153 additions & 19 deletions test/integration/cartridge/test_cartridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import time

import pytest
import yaml

import utils
from utils import run_command_and_get_output, wait_file
Expand Down Expand Up @@ -91,22 +92,155 @@ def test_cartridge_base_functionality(tt_cmd, tmpdir_with_cfg):

assert started is True

setup_cmd = [tt_cmd, "cartridge", "replicasets", "setup",
"--bootstrap-vshard",
"--name", cartridge_name,
"--run-dir", os.path.join(tmpdir, "var", "run", cartridge_name)]
setup_rc, setup_out = run_command_and_get_output(setup_cmd, cwd=tmpdir)
assert setup_rc == 0
assert re.search(r'Bootstrap vshard task completed successfully', setup_out)

admin_cmd = [tt_cmd, "cartridge", "admin", "probe",
"--conn", "admin:foo@localhost:3301",
"--uri", "localhost:3301",
"--run-dir", os.path.join(tmpdir, utils.run_path, cartridge_name)]
admin_rc, admin_out = run_command_and_get_output(admin_cmd, cwd=tmpdir)
assert admin_rc == 0
assert re.search(r'Probe "localhost:3301": OK', admin_out)

stop_cmd = [tt_cmd, "stop", cartridge_name]
stop_rc, stop_out = run_command_and_get_output(stop_cmd, cwd=tmpdir)
assert stop_rc == 0
try:
setup_cmd = [tt_cmd, "cartridge", "replicasets", "setup",
"--bootstrap-vshard",
"--name", cartridge_name,
"--run-dir", os.path.join(tmpdir, "var", "run", cartridge_name)]
setup_rc, setup_out = run_command_and_get_output(setup_cmd, cwd=tmpdir)
assert setup_rc == 0
assert re.search(r'Bootstrap vshard task completed successfully', setup_out)

admin_cmd = [tt_cmd, "cartridge", "admin", "probe",
"--conn", "admin:foo@localhost:3301",
"--uri", "localhost:3301",
"--run-dir", os.path.join(tmpdir, utils.run_path, cartridge_name)]
admin_rc, admin_out = run_command_and_get_output(admin_cmd, cwd=tmpdir)
assert admin_rc == 0
assert re.search(r'Probe "localhost:3301": OK', admin_out)

# Admin call without --run-dir.
admin_cmd = [tt_cmd, "cartridge", "admin", "probe",
"--conn", "admin:foo@localhost:3301",
"--uri", "localhost:3301"]
admin_rc, admin_out = run_command_and_get_output(admin_cmd, cwd=tmpdir)
assert admin_rc == 0
assert re.search(r'Probe "localhost:3301": OK', admin_out)

# Test replicasets list without --run-dir.
rs_cmd = [tt_cmd, "cartridge", "replicasets", "list", "--name", cartridge_name]
rs_rc, rs_out = run_command_and_get_output(rs_cmd, cwd=tmpdir)
assert rs_rc == 0
assert 'Current replica sets:' in rs_out
assert 'Role: failover-coordinator | vshard-router | app.roles.custom' in rs_out

finally:
stop_cmd = [tt_cmd, "stop", cartridge_name]
stop_rc, stop_out = run_command_and_get_output(stop_cmd, cwd=tmpdir)
assert stop_rc == 0


def test_cartridge_base_functionality_in_app_dir(tt_cmd, tmpdir_with_cfg):
tmpdir = tmpdir_with_cfg
create_cmd = [tt_cmd, "create", "cartridge", "--name", cartridge_name]
create_process = subprocess.Popen(
create_cmd,
cwd=tmpdir,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
text=True
)
create_process.stdin.writelines(["foo\n"])
create_process.stdin.close()
create_process.wait()

assert create_process.returncode == 0
create_out = create_process.stdout.read()
assert re.search(r"Application '" + cartridge_name + "' created successfully", create_out)

app_dir = os.path.join(tmpdir, cartridge_name)

# Add cartridge config to simulate existing cartridge app.
config_path = os.path.join(app_dir, ".cartridge.yml")
with open(config_path, "w") as f:
yaml.dump({"stateboard": True}, f)

# Generate tt env in application directory.
cmd = [tt_cmd, "init"]
rc, out = run_command_and_get_output(cmd, cwd=app_dir)
assert rc == 0
assert 'Environment config is written to ' in out

# Generate tt env in application directory.
cmd = [tt_cmd, "build"]
rc, out = run_command_and_get_output(cmd, cwd=app_dir)
assert rc == 0
assert 'Application was successfully built' in out

cmd = [tt_cmd, "start"]
subprocess.Popen(
cmd,
cwd=app_dir,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
text=True
)

instances = ["router", "stateboard", "s1-master", "s1-replica", "s2-master", "s2-replica"]

# Wait for the full start of the cartridge.
try:
for inst in instances:
run_dir = os.path.join(app_dir, utils.run_path, cartridge_name, inst)
log_dir = os.path.join(app_dir, utils.log_path, cartridge_name, inst)

file = wait_file(run_dir, inst + '.pid', [])
assert file != ""
file = wait_file(log_dir, inst + '.log', [])
assert file != ""

started = False
trying = 0
while not started:
if inst == "stateboard":
started = True
break
if trying == 200:
break
with open(os.path.join(log_dir, inst + '.log'), "r") as fp:
lines = fp.readlines()
lines = [line.rstrip() for line in lines]
for line in lines:
if re.search("Set default metrics endpoints", line):
started = True
break
fp.close()
time.sleep(0.05)
trying = trying + 1

assert started is True

setup_cmd = [tt_cmd, "cartridge", "replicasets", "setup",
"--bootstrap-vshard"]
setup_rc, setup_out = run_command_and_get_output(setup_cmd, cwd=app_dir)
assert setup_rc == 0
assert 'Bootstrap vshard task completed successfully' in setup_out

# Test replicasets list without run-dir and app name
rs_cmd = [tt_cmd, "cartridge", "replicasets", "list"]
rs_rc, rs_out = run_command_and_get_output(rs_cmd, cwd=app_dir)
assert rs_rc == 0
assert 'Current replica sets:' in rs_out
assert 'Role: failover-coordinator | vshard-router | app.roles.custom' in rs_out

# Admin call without --run-dir.
admin_cmd = [tt_cmd, "cartridge", "admin", "probe",
"--conn", "admin:foo@localhost:3301",
"--uri", "localhost:3301"]
admin_rc, admin_out = run_command_and_get_output(admin_cmd, cwd=app_dir)
assert admin_rc == 0
assert 'Probe "localhost:3301": OK' in admin_out

# Failover command.
failover_cmd = [tt_cmd, "cartridge", "failover", "status"]
failover_rc, failover_out = run_command_and_get_output(failover_cmd, cwd=app_dir)
assert failover_rc == 0
assert 'Current failover status:' in failover_out

stop_cmd = [tt_cmd, "stop"]
stop_rc, _ = run_command_and_get_output(stop_cmd, cwd=app_dir)
assert stop_rc == 0

finally:
run_command_and_get_output([tt_cmd, "stop"], cwd=app_dir)
40 changes: 38 additions & 2 deletions test/integration/cfg/test_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,45 @@ def test_cfg_dump_no_config(tt_cmd, tmpdir):


def test_cfg_dump_default_no_config(tt_cmd, tmpdir):
buid_cmd = [tt_cmd, "cfg", "dump"]
dump_cmd = [tt_cmd, "cfg", "dump"]
tt_process = subprocess.Popen(
buid_cmd,
dump_cmd,
cwd=tmpdir,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
text=True
)
tt_process.stdin.close()
tt_process.wait()
assert tt_process.returncode == 0

output = tt_process.stdout.read()
print(output)
assert f"bin_dir: {os.path.join(tmpdir, 'bin')}" in output
assert f"run_dir: {os.path.join(tmpdir, 'var', 'run')}" in output
assert f"wal_dir: {os.path.join(tmpdir, 'var', 'lib')}" in output
assert f"vinyl_dir: {os.path.join(tmpdir, 'var', 'lib')}" in output
assert f"memtx_dir: {os.path.join(tmpdir, 'var', 'lib')}" in output
assert f"log_dir: {os.path.join(tmpdir, 'var', 'log')}" in output
assert f"inc_dir: {os.path.join(tmpdir, 'include')}" in output
assert f"directory: {os.path.join(tmpdir, 'modules')}" in output
assert f"distfiles: {os.path.join(tmpdir, 'distfiles')}" in output
assert "log_maxsize: 100" in output
assert "log_maxbackups: 10" in output
assert f"instances_enabled: {tmpdir}" in output
assert f"templates:\n - path: {os.path.join(tmpdir, 'templates')}" in output
assert 'credential_path: ""' in output

# Create init.lua in current dir making it an application.

script_path = os.path.join(tmpdir, "init.lua")
with open(script_path, "w") as f:
f.write('print("hello")')

dump_cmd = [tt_cmd, "cfg", "dump"]
tt_process = subprocess.Popen(
dump_cmd,
cwd=tmpdir,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
Expand Down