-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Adding RSYNC auth #6410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Adding RSYNC auth #6410
Conversation
WalkthroughAdds two go.mod dependencies and implements an RsyncClient with ListModules and ListFilesInModule, centralized fast-dial connection helper, captured rsync driver output, and modified isRsync error handling to suppress plugin errors. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor JS as JS Caller
participant RC as RsyncClient
participant Dial as Fast Dialer
participant RS as rsynclib
rect rgb(240,248,255)
note over JS,RC: List modules
JS->>RC: ListModules(ctx, host, port, user, pass)
RC->>Dial: connectWithFastDialer(host:port)
Dial-->>RC: net.Conn / error
RC->>RS: ListModules(conn, creds?)
RS-->>RC: modules[], logs
RC-->>JS: RsyncListResponse{Modules, Output}
end
rect rgb(245,255,240)
note over JS,RC: List files in module
JS->>RC: ListFilesInModule(ctx, host, port, user, pass, module)
RC->>Dial: connectWithFastDialer(host:port)
Dial-->>RC: net.Conn / error
RC->>RS: SocketClient(conn, module, creds?)
RS-->>RC: files[], logs
RC-->>JS: RsyncListResponse{Files, Output}
end
opt Plugin check path
JS->>RC: isRsync(...)
RC->>Dial: connectWithFastDialer(...)
Dial-->>RC: conn / error
RC->>RS: plugin.Run(...)
note right of RC: On plugin error, function now returns nil error (suppressed)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (8)
pkg/js/libs/rsync/rsync.go (8)
20-28
: Docstring references gokrazy driver but the code imports a different forkComment says “Internally client uses https://github.com/gokrazy/rsync driver,” but imports point to
github.com/Mzack9999/go-rsync/rsync
. Please align the docs to avoid confusion (e.g., clarify it's a fork of gokrazy, if applicable).- // Internally client uses https://github.com/gokrazy/rsync driver. + // Internally the client uses a forked rsync driver (github.com/Mzack9999/go-rsync), + // originally based on gokrazy/rsync.
42-54
: Inconsistent naming in docs (“ListSharesResponse”, “ListShares”) vs actual APIThe type is
RsyncListResponse
and the methods areListModules
/ListFilesInModule
, but comments and examples mention “ListSharesResponse” andListShares
. Please fix wording to reflect the exported API.- // ListSharesResponse is the response from the ListShares function. - // this is returned by ListShares function. + // RsyncListResponse is returned by ListModules and ListFilesInModule.
57-63
: Propagate context to the fast dialer instead of using context.Background()Using
context.Background()
ignores caller cancellations/timeouts. Thread the ctx down for better control, especially inside scans.-func connectWithFastDialer(executionId string, host string, port int) (net.Conn, error) { +func connectWithFastDialer(ctx context.Context, executionId string, host string, port int) (net.Conn, error) { dialer := protocolstate.GetDialersWithId(executionId) if dialer == nil { return nil, fmt.Errorf("dialers not initialized for %s", executionId) } - return dialer.Fastdialer.Dial(context.Background(), "tcp", net.JoinHostPort(host, strconv.Itoa(port))) + return dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(host, strconv.Itoa(port))) }And in the only call site:
-conn, err := connectWithFastDialer(executionId, host, port) +conn, err := connectWithFastDialer(context.Background(), executionId, host, port)If feasible, also thread the original
ctx
fromIsRsync
intoisRsync
to respect upstream cancellations/timeouts.
93-94
: Swallowing plugin errors alters semantics and hinders troubleshootingReturning
nil
onrsyncPlugin.Run
error makes it indistinguishable from “not rsync.” If intentional, add a debug log or metric so users can differentiate transport/plugin failures from clean negatives. Otherwise, consider returning a wrapped error.- if err != nil { - return resp, nil - } + if err != nil { + // Treat as negative but record reason for diagnostics. + // TODO: emit debug log/metric here if available. + return resp, nil + }Would you like me to wire a debug logger here behind a global/debug flag?
148-152
: Don’t send empty credentials; build options conditionallyPassing
WithClientAuth("", "")
may change server behavior (e.g., provoke auth or lockouts). Build options slice and only add auth when provided.- sr, err := rsynclib.ListModules(address, - rsynclib.WithClientAuth(username, password), - rsynclib.WithLogger(logger), - rsynclib.WithFastDialer(fastDialer.Fastdialer), - ) + opts := []rsynclib.Option{rsynclib.WithFastDialer(fastDialer.Fastdialer)} + opts = append(opts, rsynclib.WithLogger(logger)) + if username != "" || password != "" { + opts = append(opts, rsynclib.WithClientAuth(username, password)) + } + sr, err := rsynclib.ListModules(address, opts...)
169-187
: DRY: repeated logger constructionThe bytes.Buffer + slog.TextHandler boilerplate is duplicated in both list functions. Consider a small helper that returns
(logger *slog.Logger, getOutput func() string)
to centralize redaction/capping as well.I can provide a small
newBufferedLogger()
helper if you want me to push a patch.
188-193
: Same as above: conditional auth, plus ensure client cleanupBuild options conditionally and ensure the client is closed if the driver exposes a
Close
/Disconnect
method to avoid leaks.- sr, err := rsynclib.SocketClient(nil, address, module, ".", - rsynclib.WithClientAuth(username, password), - rsynclib.WithLogger(logger), - rsynclib.WithFastDialer(fastDialer.Fastdialer), - ) + opts := []rsynclib.Option{rsynclib.WithFastDialer(fastDialer.Fastdialer), rsynclib.WithLogger(logger)} + if username != "" || password != "" { + opts = append(opts, rsynclib.WithClientAuth(username, password)) + } + sr, err := rsynclib.SocketClient(nil, address, module, ".", opts...) + // If the client exposes Close(), ensure we don't leak the connection: + // defer sr.Close()Please verify whether the returned client type has a
Close()
method and add a defer accordingly.
197-201
: Error message may over-attribute failures to auth
sr.List()
can fail for reasons beyond authentication (permissions, module path, network hiccups). Consider a more neutral message.- return RsyncListResponse{}, fmt.Errorf("authentication failed: %v", err) + return RsyncListResponse{}, fmt.Errorf("list failed (auth/permissions/network): %v", err)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (4)
cmd/nuclei/rsync.yaml
is excluded by!**/*.yaml
go.sum
is excluded by!**/*.sum
pkg/js/generated/go/librsync/rsync.go
is excluded by!**/generated/**
pkg/js/generated/ts/rsync.ts
is excluded by!**/generated/**
📒 Files selected for processing (2)
go.mod
(2 hunks)pkg/js/libs/rsync/rsync.go
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/js/libs/rsync/rsync.go (2)
pkg/protocols/common/protocolstate/state.go (1)
GetDialersWithId
(39-45)pkg/js/generated/ts/rsync.ts (3)
RsyncClient
(25-70)ListModules
(53-55)ListFilesInModule
(67-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Tests (macOS-latest)
- GitHub Check: Tests (ubuntu-latest)
- GitHub Check: Tests (windows-latest)
🔇 Additional comments (1)
go.mod (1)
247-247
: No change needed for kubuffer requireRunning
go mod why -m github.com/kaiakz/ubuffer
shows it is pulled in viagithub.com/Mzack9999/go-rsync
(which your module imports) and thus isn’t pruned bygo mod tidy
. This explicit indirect requirement is required to pin the version for reproducible builds, so it should remain.
RsyncListResponse struct { | ||
Modules []string | ||
Files []string | ||
Output string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JS API mismatch: Go returns RsyncListResponse, TS definitions expect string[]
The generated TS in pkg/js/generated/ts/rsync.ts documents:
ListModules(...): string[] | null
ListFilesInModule(...): string[] | null
But Go returns RsyncListResponse
with { Modules|Files, Output }
. This will confuse users and may break typings.
Two options:
- Update TS signatures and docs to return an object with
{ modules?: string[]; files?: string[]; output?: string }
. - Or change Go to return
[]string
and expose logs via a separate debug method/flag.
I can open a follow-up PR to update the TS definitions—let me know.
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) { | ||
executionId := ctx.Value("executionId").(string) | ||
return listModules(executionId, host, port, username, password) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid panic on missing executionId in context
Direct type assertion will panic if the key is absent or of the wrong type. Return a clean error instead.
-func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
- executionId := ctx.Value("executionId").(string)
- return listModules(executionId, host, port, username, password)
-}
+func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
+ executionId, ok := ctx.Value("executionId").(string)
+ if !ok || executionId == "" {
+ return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
+ }
+ return listModules(executionId, host, port, username, password)
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) { | |
executionId := ctx.Value("executionId").(string) | |
return listModules(executionId, host, port, username, password) | |
} | |
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) { | |
executionId, ok := ctx.Value("executionId").(string) | |
if !ok || executionId == "" { | |
return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context") | |
} | |
return listModules(executionId, host, port, username, password) | |
} |
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 111 to 114, the function uses a
direct type assertion on ctx.Value("executionId").(string) which will panic if
the key is missing or not a string; change it to retrieve the value with the
comma-ok idiom (v, ok := ctx.Value("executionId").(string)) and return a clear
error (e.g. fmt.Errorf or errors.New) when ok is false instead of allowing a
panic; then pass the validated executionId to listModules.
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) { | ||
executionId := ctx.Value("executionId").(string) | ||
return listFilesInModule(executionId, host, port, username, password, module) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Same: guard against missing executionId to prevent panic
Repeat the safe-assertion pattern for ListFilesInModule
.
-func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
- executionId := ctx.Value("executionId").(string)
- return listFilesInModule(executionId, host, port, username, password, module)
-}
+func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
+ executionId, ok := ctx.Value("executionId").(string)
+ if !ok || executionId == "" {
+ return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
+ }
+ return listFilesInModule(executionId, host, port, username, password, module)
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) { | |
executionId := ctx.Value("executionId").(string) | |
return listFilesInModule(executionId, host, port, username, password, module) | |
} | |
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) { | |
executionId, ok := ctx.Value("executionId").(string) | |
if !ok || executionId == "" { | |
return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context") | |
} | |
return listFilesInModule(executionId, host, port, username, password, module) | |
} |
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 124 to 127, the code unconditionally
type-asserts ctx.Value("executionId").(string) which can panic if the value is
missing; update ListFilesInModule to safely retrieve the executionId using the
comma-ok form (val, ok := ctx.Value("executionId").(string)) and return a
descriptive error if ok is false (matching the safe-assertion pattern used in
the other method), then pass the validated executionId into listFilesInModule.
// Create a bytes buffer for logging | ||
var logBuffer bytes.Buffer | ||
|
||
// Create a custom slog handler that writes to the buffer | ||
logHandler := slog.NewTextHandler(&logBuffer, &slog.HandlerOptions{ | ||
Level: slog.LevelDebug, | ||
}) | ||
|
||
// Create a logger that writes to our buffer | ||
logger := slog.New(logHandler) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sensitive data risk: driver logs are surfaced verbatim via Output
You capture driver logs at debug level and return them to templates (RsyncListResponse.Output
). Depending on the driver, logs may include credentials or server banners that we don’t want to leak downstream or to user logs.
Mitigations:
- Only attach a logger when an explicit “debug”/“verbose” flag is enabled.
- Redact credentials from the buffer before returning.
- Cap output length to avoid memory blowups.
Minimal, localized change to redact obvious secrets:
- result := RsyncListResponse{
- Modules: make([]string, len(sr)),
- Output: logBuffer.String(),
- }
+ result := RsyncListResponse{
+ Modules: make([]string, len(sr)),
+ Output: sanitizeRsyncLogs(logBuffer.String(), username, password),
+ }
Add this helper (and strings
import) elsewhere in the file:
// sanitizeRsyncLogs removes obvious secrets from log output.
// Best-effort: relies on the caller passing the same creds used for auth.
func sanitizeRsyncLogs(out, user, pass string) string {
// Skip work quickly
if out == "" {
return out
}
// Redact password first to avoid accidental leaking
if pass != "" {
out = strings.ReplaceAll(out, pass, "******")
}
if user != "" {
out = strings.ReplaceAll(out, user, "***")
}
// Optionally cap to N bytes
const max = 8 << 10 // 8KiB
if len(out) > max {
out = out[:max] + "...[truncated]"
}
return out
}
If preferred, I can refactor to enable logging only under an explicit debug setting.
Also applies to: 157-161
result := RsyncListResponse{ | ||
Files: make([]string, len(list)), | ||
Output: logBuffer.String(), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apply the same redaction/capping to Output in files listing
Mirror the sanitizeRsyncLogs
usage here to prevent leaking secrets and cap size.
- result := RsyncListResponse{
- Files: make([]string, len(list)),
- Output: logBuffer.String(),
- }
+ result := RsyncListResponse{
+ Files: make([]string, len(list)),
+ Output: sanitizeRsyncLogs(logBuffer.String(), username, password),
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
result := RsyncListResponse{ | |
Files: make([]string, len(list)), | |
Output: logBuffer.String(), | |
} | |
result := RsyncListResponse{ | |
Files: make([]string, len(list)), | |
Output: sanitizeRsyncLogs(logBuffer.String(), username, password), | |
} |
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 203 to 206, the
RsyncListResponse.Output is assigned the raw logBuffer.String() which can leak
secrets and exceed size limits; apply the same sanitizeRsyncLogs redaction and
capping used elsewhere to the Output field (call
sanitizeRsyncLogs(logBuffer.String()) and assign that result, ensuring it honors
the existing max length/cap logic) so Output is redacted and size-limited before
being returned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
cmd/integration-test/javascript.go (4)
105-133
: Remove ineffective pool.Retry wrapper; it never retries.The closure always returns nil, so
pool.Retry
won’t retry. Either return the actual error from the closure or droppool.Retry
and call directly (you already have an outer retry loop).Apply this minimal change:
- _ = pool.Retry(func() error { - //let rsync server start - time.Sleep(3 * time.Second) - results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug) - return nil - }) - if err != nil { - return err - } + // let rsync server start + time.Sleep(3 * time.Second) + results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug) + if err != nil { + return err + }
111-111
: Prefer 127.0.0.1 over localhost for stability.Avoids IPv6/hosts-file surprises when the daemon only listens on IPv4.
- finalURL := "localhost:" + tempPort + finalURL := "127.0.0.1:" + tempPort
205-205
: Make config writing more portable and remove ambiguity in credentials.
- Use printf instead of echo -e for reliability.
- The OS user password (mysecret) differs from rsync secret (MySecret123). Consider aligning or dropping the OS password step since rsync auth uses the secrets file.
- Cmd: []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:mysecret' | chpasswd && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && echo -e '[data]\\n path = /data\\n comment = Local Rsync Share\\n read only = false\\n auth users = rsyncuser\\n secrets file = /etc/rsyncd.secrets' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"}, + Cmd: []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && printf '[data]\\n path = /data\\n comment = Local Rsync Share\\n read only = false\\n auth users = rsyncuser\\n secrets file = /etc/rsyncd.secrets\\n' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"},
103-134
: Optional: collapse result-count check into the retry loop.You can return the assertion from inside the loop to avoid tracking an errors slice.
- if err := expectResultsCount(results, 1); err == nil { - return nil - } else { - errs = append(errs, err) - } + if err := expectResultsCount(results, 1); err == nil { + return nil + } else { + errs = append(errs, err) + }If you adopt the earlier suggestion to remove
pool.Retry
, consider returning on success and continuing on error, keeping logic concise.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
go.sum
is excluded by!**/*.sum
integration_tests/protocols/javascript/rsync-test.yaml
is excluded by!**/*.yaml
📒 Files selected for processing (2)
cmd/integration-test/javascript.go
(3 hunks)go.mod
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- go.mod
🧰 Additional context used
🧬 Code graph analysis (1)
cmd/integration-test/javascript.go (1)
pkg/testutils/integration.go (2)
TestCase
(247-250)RunNucleiTemplateAndGetResults
(30-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Lint
🔇 Additional comments (2)
cmd/integration-test/javascript.go (2)
18-18
: Rsync JS testcase entry looks good.Disabled on Windows/macOS consistent with other dockerized tests. No issues.
24-24
: Resource handle addition is appropriate.
rsyncResource
mirrors existing Redis/SSH patterns.
{Path: "protocols/javascript/ssh-server-fingerprint.yaml", TestCase: &javascriptSSHServerFingerprint{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }}, | ||
{Path: "protocols/javascript/net-multi-step.yaml", TestCase: &networkMultiStep{}}, | ||
{Path: "protocols/javascript/net-https.yaml", TestCase: &javascriptNetHttps{}}, | ||
{Path: "protocols/javascript/rsync-test.yaml", TestCase: &javascriptRsyncTest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Sanity-check that the template matches container credentials and module.
Ensure protocols/javascript/rsync-test.yaml
uses:
- user: rsyncuser
- pass: MySecret123
- module: data
- target: host:port provided here
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -nC2 -e 'rsyncuser' -e 'MySecret123' -e '\bdata\b' protocols/javascript/rsync-test.yaml || {
echo "Note: verify the template uses the expected credentials/module."
}
Length of output: 322
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate any rsync-test.yaml files in the repo
paths=$(fd rsync-test.yaml)
if [ -z "$paths" ]; then
echo "No rsync-test.yaml file found in the repository."
exit 0
fi
# For each found file, verify the expected credentials/module
for file in $paths; do
echo "Checking $file:"
rg -nC2 -e 'user:\s*rsyncuser' -e 'pass:\s*MySecret123' -e 'module:\s*data' "$file" \
|| echo "⚠️ Note: verify that $file uses user: rsyncuser, pass: MySecret123, module: data."
done
Length of output: 182
Critical: Verify existence of the referenced YAML template
It appears the integration test is pointing at protocols/javascript/rsync-test.yaml
, but no such file is present in the repository. This will cause test discovery to fail.
• File: cmd/integration-test/javascript.go
Line: 18
{Path: "protocols/javascript/rsync-test.yaml", TestCase: &javascriptRsyncTest{}, DisableOn: …},
Action required:
- Confirm whether the YAML lives under a different path and update the
Path
accordingly, or - Add the missing
protocols/javascript/rsync-test.yaml
template (ensuring it usesuser: rsyncuser
,pass: MySecret123
,module: data
, and the correcttarget
).
🤖 Prompt for AI Agents
In cmd/integration-test/javascript.go around line 18, the test references
protocols/javascript/rsync-test.yaml which is missing from the repo; update the
Path to the actual location if the YAML exists elsewhere or add the missing file
at protocols/javascript/rsync-test.yaml containing a valid rsync template that
includes user: rsyncuser, pass: MySecret123, module: data and the correct target
(ensure the target matches the integration test expectations), then run test
discovery to confirm the test picks up the template.
// setup a temporary rsync server | ||
rsyncResource, err = pool.RunWithOptions(&dockertest.RunOptions{ | ||
Repository: "alpine", | ||
Tag: "latest", | ||
Cmd: []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:mysecret' | chpasswd && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && echo -e '[data]\\n path = /data\\n comment = Local Rsync Share\\n read only = false\\n auth users = rsyncuser\\n secrets file = /etc/rsyncd.secrets' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"}, | ||
Platform: "linux/amd64", | ||
}) | ||
if err != nil { | ||
log.Printf("Could not start Rsync resource: %s", err) | ||
return | ||
} | ||
// by default expire after 30 sec | ||
if err := rsyncResource.Expire(30); err != nil { | ||
log.Printf("Could not expire Rsync resource: %s", err) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rsync port 873 isn’t exposed; GetPort("873/tcp") will be empty.
Alpine image doesn’t EXPOSE 873, so no host port is published unless you set it explicitly. Expose and bind 873/tcp.
Apply this diff in the run options:
rsyncResource, err = pool.RunWithOptions(&dockertest.RunOptions{
Repository: "alpine",
Tag: "latest",
Cmd: []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:mysecret' | chpasswd && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && echo -e '[data]\\n path = /data\\n comment = Local Rsync Share\\n read only = false\\n auth users = rsyncuser\\n secrets file = /etc/rsyncd.secrets' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"},
+ ExposedPorts: []string{"873/tcp"},
+ PortBindings: map[docker.Port][]docker.PortBinding{
+ "873/tcp": {{HostIP: "0.0.0.0", HostPort: ""}},
+ },
Platform: "linux/amd64",
})
Also add the import:
// at the top imports
"github.com/ory/dockertest/v3/docker"
🤖 Prompt for AI Agents
In cmd/integration-test/javascript.go around lines 201-216, the rsync container
never exposes or binds port 873 so GetPort("873/tcp") will be empty; update the
RunWithOptions to declare ExposedPorts and HostConfig PortBindings for "873/tcp"
(map container port 873 to a random host port) in the RunOptions by supplying a
docker HostConfig with PortBindings and ExposedPorts, and add the import
"github.com/ory/dockertest/v3/docker" at the top of the file.
Proposed changes
Close #6409
Checklist
Summary by CodeRabbit
New Features
Tests
Chores