Skip to content

feat(drivers/alias): add autoMakeDir for missing dest#2817

Open
qiuxiuya wants to merge 1 commit into
OpenListTeam:mainfrom
qiuxiuya:autoMakeDir
Open

feat(drivers/alias): add autoMakeDir for missing dest#2817
qiuxiuya wants to merge 1 commit into
OpenListTeam:mainfrom
qiuxiuya:autoMakeDir

Conversation

@qiuxiuya

@qiuxiuya qiuxiuya commented Jul 22, 2026

Copy link
Copy Markdown

Summary / 摘要

alias 驱动的 all / all_strict 写入策略增加目标目录缺失时自动创建,使新加入的存储也能参与写入。

此前,写入操作的「有效路径」仅指目标对象已存在且类型匹配的后端路径。当某个后端(例如新加入的存储)缺少对应的子目录时,会被判定为无效路径而跳过,导致数据不会写入该后端。本次改动在解析写入目标时,对返回 ObjectNotFound 的目录后端自动调用 fs.MakeDir 创建目录后纳入写入目标。

实现要点:

  • getAllObjs() 新增 autoMakeDir bool 参数;当目标为目录、后端返回 ObjectNotFound 且开关开启时,自动 fs.MakeDir 创建后继续参与写入。

  • 新增 isAllWritePolicy() 辅助函数,判断策略是否为 all / all_strict

  • 写入目标(Put/Copy/Mkdir/Rename/Remove 的目标目录)在 all / all_strict 策略下启用自动建目录;源对象与读操作(Link 等)保持 false,不受影响。

  • This PR has breaking changes.
    / 此 PR 包含破坏性变更。

  • This PR changes public API, config, storage format, or migration behavior.
    / 此 PR 修改了公开 API、配置、存储格式或迁移行为。

  • This PR requires corresponding changes in related repositories.
    / 此 PR 需要关联仓库同步修改。

Related repository PRs / 关联仓库 PR:

  • OpenList-Frontend:
  • OpenList-Docs:

Testing / 测试

Checklist / 检查清单

  • I have read CONTRIBUTING.
    / 我已阅读 CONTRIBUTING
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
    / 我确认此贡献符合仓库许可证、贡献规范和行为准则。
  • I have formatted the changed code with gofmt, go fmt, or prettier where applicable.
    / 我已按适用情况使用 gofmtgo fmtprettier 格式化变更代码。
  • I have requested review from relevant maintainers or code owners where applicable.
    / 我已在适用情况下请求相关维护者或代码所有者审查。

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.
    / 此 PR 包含 AI 辅助内容。

Tools used / 使用工具:

  • ChatGPT
  • Codex
  • GitHub Copilot
  • Claude
  • Gemini
  • Other (please specify) / 其他(请注明):

Usage scope / 使用范围:

  • Code generation / 代码生成
  • Refactoring / 重构
  • Documentation / 文档
  • Tests / 测试
  • Translation / 翻译
  • Review assistance / 审查辅助
  • I have reviewed and validated all AI-assisted content included in this PR.
    / 我已审核并验证此 PR 中的所有 AI 辅助内容。
  • I have ensured that all AI-assisted commits include Co-Authored-By attribution.
    / 我已确保所有 AI 辅助提交都包含 Co-Authored-By 归属信息。
  • I can reproduce all AI-assisted content included in this PR without any AI tools.
    / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。

…n folder if it does not exist

Co-authored-by: Claude <claude@users.noreply.github.com>
@jyxjjj

jyxjjj commented Jul 22, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3ed6c944f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread drivers/alias/util.go
return nil, errs.PermissionDenied
}
return d.getAllObjs(ctx, obj, getWriteAndPutFilterFunc(d.WriteConflictPolicy))
return d.getAllObjs(ctx, obj, getWriteAndPutFilterFunc(d.WriteConflictPolicy), isAllWritePolicy(d.WriteConflictPolicy))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't auto-create missing source directories

When WriteConflictPolicy is all/all_strict, getWriteObjs is also used by Rename and Remove for the object being operated on, not just by MakeDir for a destination parent. If /foo is a directory that exists on backend A but is missing on backend B, renaming it now creates B's /foo and then renames that empty directory to /bar, so the alias gains a new empty destination on a backend that never had the source content. Limit autoMakeDir to destination-parent resolution paths such as upload/copy/move/mkdir, not source-object resolution.

Useful? React with 👍 / 👎.

Comment thread drivers/alias/util.go
}
}
// 目标为目录但该后端不存在时,按需自动创建,使新加入的存储也能参与写入
if err != nil && autoMakeDir && bObj.IsDir() && errs.IsObjectNotFound(err) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve earlier missing roots before mkdir

The auto-create branch only has a backend path for *tempObjs, but Alias.Get collapses any missing backend that appears before the first existing copy into nil, so this still misses those roots. For example, with alias paths [new, old] and /album present only on old, /album resolves to the old object plus nil; an all upload/mkdir under /album never sees new/album to create it, and all_strict still fails. The missing backend path needs to be preserved instead of represented only as nil when auto-creation is enabled.

Useful? React with 👍 / 👎.

Comment thread drivers/alias/util.go
return nil, nil, errs.PermissionDenied
}
dstObjs, err := d.getAllObjs(ctx, dstDir, getWriteAndPutFilterFunc(d.PutConflictPolicy))
dstObjs, err := d.getAllObjs(ctx, dstDir, getWriteAndPutFilterFunc(d.PutConflictPolicy), isAllWritePolicy(d.PutConflictPolicy))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate move sources before creating destination dirs

For PutConflictPolicy all/all_strict, resolving dstDir now creates missing destination parent directories before getMoveObjs checks whether there are enough source copies to move. If a file or folder exists on only one backend but the destination parent is auto-created on two backends, the later len(tmpSrcObjs) < len(dstObjs) check returns ErrNotEnoughSrcObjs, leaving the newly-created destination directory behind even though the move failed. Resolve the source count before performing mkdir side effects, or skip auto-creation for move cases that cannot be satisfied.

Useful? React with 👍 / 👎.

Comment thread drivers/alias/util.go
}
// 目标为目录但该后端不存在时,按需自动创建,使新加入的存储也能参与写入
if err != nil && autoMakeDir && bObj.IsDir() && errs.IsObjectNotFound(err) {
if mkErr := fs.MakeDir(ctx, o.GetPath()); mkErr == nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Roll back auto-created dirs when strict setup fails

With all_strict, this loop creates each missing backend directory as it is encountered and immediately clears the error, but a later backend can still fail MakeDir; in that case getAllObjs returns before the upload/copy/mkdir runs while any earlier auto-created directories remain. For a destination that is missing on two backends where only the first can be created, a failed strict operation now leaks an empty directory onto the first backend. Preflight the targets or undo directories created during this resolution step when a later strict target cannot be prepared.

Useful? React with 👍 / 👎.

@xrgzs xrgzs changed the title feat(alias): Add autoMakeDir to automatically create the destinatio… feat(alias): add autoMakeDir for missing dest Jul 22, 2026
@xrgzs xrgzs changed the title feat(alias): add autoMakeDir for missing dest feat(drivers/alias): add autoMakeDir for missing dest Jul 22, 2026
@xrgzs xrgzs added enhancement Module: Driver Driver-Related Issue/PR labels Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Module: Driver Driver-Related Issue/PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants