Cannot rename a hashed project
Summary
Attempting to rename a project backed by the new "hashed storage" functionality results in the error message:
There is already a repository with that name on disk
I saw this on my EE install, but I'm pretty sure it will be an issue in CE as well.
Steps to reproduce
- Enable hashed storage
- Create a new project
- Navigate to project -> settings -> general -> advanced settings
- Change the project path and press "Submit"
What is the current bug behavior?
Error response There is already a repository with that name on disk
What is the expected correct behavior?
Success response allowing the rename to go ahead
Relevant logs and/or screenshots
development.log
Started PATCH "/root/test-geo-log-cursor-2" for 127.0.0.1 at 2017-09-21 11:29:40 +0100 GeoNode Exists (0.4ms) SELECT 1 AS one FROM "geo_nodes" LIMIT 1 GeoNode Load (0.4ms) SELECT "geo_nodes".* FROM "geo_nodes" WHERE "geo_nodes"."host" = $1 AND "geo_nodes"."port" = $2 AND "geo_nodes"."relative_url_root" = $3 LIMIT 1 [["host", "localhost"], ["port", 4000], ["relative_url_root", ""]] Group Load (0.7ms) SELECT "namespaces".* FROM "namespaces" INNER JOIN "routes" ON "routes"."source_id" = "namespaces"."id" AND "routes"."source_type" = $1 WHERE "namespaces"."type" IN ('Group') AND ((LOWER(routes.path) = LOWER('root/test-geo-log-cursor-2'))) ORDER BY (CASE WHEN routes.path = 'root/test-geo-log-cursor-2' THEN 0 ELSE 1 END) LIMIT 1 [["source_type", "Namespace"]] Project Load (0.8ms) SELECT "projects".* FROM "projects" INNER JOIN "routes" ON "routes"."source_id" = "projects"."id" AND "routes"."source_type" = $1 WHERE ((LOWER(routes.path) = LOWER('root/test-geo-log-cursor-2'))) ORDER BY (CASE WHEN routes.path = 'root/test-geo-log-cursor-2' THEN 0 ELSE 1 END) LIMIT 1 [["source_type", "Project"]] Processing by ProjectsController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "project"=>{"name"=>"test-geo-log-cursor-200", "path"=>"test-geo-log-cursor-200"}, "namespace_id"=>"root", "id"=>"test-geo-log-cursor-2"} User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]] Identity Exists (0.4ms) SELECT 1 AS one FROM "identities" WHERE "identities"."user_id" = $1 AND (provider LIKE 'ldap%' AND extern_uid IS NOT NULL) LIMIT 1 [["user_id", 1]] CACHE (0.0ms) SELECT "projects".* FROM "projects" INNER JOIN "routes" ON "routes"."source_id" = "projects"."id" AND "routes"."source_type" = $1 WHERE ((LOWER(routes.path) = LOWER('root/test-geo-log-cursor-2'))) ORDER BY (CASE WHEN routes.path = 'root/test-geo-log-cursor-2' THEN 0 ELSE 1 END) LIMIT 1 [["source_type", "Project"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 29], ["source_type", "Project"]] License Load (0.3ms) SELECT "licenses".* FROM "licenses" ORDER BY "licenses"."id" DESC LIMIT 1 Namespace Load (0.6ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = $1 LIMIT 1 [["id", 1]] ContainerRepository Load (0.7ms) SELECT "container_repositories".* FROM "container_repositories" WHERE "container_repositories"."project_id" = $1 [["project_id", 29]] (0.2ms) BEGIN Route Load (0.5ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 1], ["source_type", "Namespace"]] User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] RemoteMirror Load (0.6ms) SELECT "remote_mirrors".* FROM "remote_mirrors" WHERE "remote_mirrors"."project_id" = $1 [["project_id", 29]] Project Load (0.7ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT 1 [["id", 29]] Route Exists (0.8ms) SELECT 1 AS one FROM "routes" WHERE (LOWER("routes"."path") = LOWER('root/test-geo-log-cursor-200') AND "routes"."id" != 91) LIMIT 1 Route Exists (0.6ms) SELECT 1 AS one FROM "routes" WHERE (LOWER("routes"."path") = LOWER('root/test-geo-log-cursor-200') AND "routes"."id" != 91) LIMIT 1 Project Exists (0.6ms) SELECT 1 AS one FROM "projects" WHERE ("projects"."path" = 'test-geo-log-cursor-200' AND "projects"."id" != 29 AND "projects"."namespace_id" = 1) LIMIT 1 Project Exists (0.4ms) SELECT 1 AS one FROM "projects" WHERE ("projects"."name" = 'test-geo-log-cursor-200' AND "projects"."id" != 29 AND "projects"."namespace_id" = 1) LIMIT 1 ProjectImportData Load (0.2ms) SELECT "project_import_data".* FROM "project_import_data" WHERE "project_import_data"."project_id" = $1 LIMIT 1 [["project_id", 29]] Group Load (0.4ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" IN ('Group') AND "namespaces"."id" = $1 AND "namespaces"."type" IN ('Group') AND "namespaces"."type" = $2 LIMIT 1 [["id", 1], ["type", "Group"]] ForkedProjectLink Load (0.3ms) SELECT "forked_project_links".* FROM "forked_project_links" WHERE "forked_project_links"."forked_to_project_id" = $1 LIMIT 1 [["forked_to_project_id", 29]] Project Exists (0.3ms) SELECT 1 AS one FROM "projects" WHERE "projects"."namespace_id" = $1 AND "projects"."path" = $2 LIMIT 1 [["namespace_id", 1], ["path", "test-geo-log-cursor-200.wiki"]] (0.2ms) ROLLBACK Rendered shared/_nav_scroll.html.haml (0.3ms) ProjectFeature Load (0.4ms) SELECT "project_features".* FROM "project_features" WHERE "project_features"."project_id" = $1 LIMIT 1 [["project_id", 29]] Rendered ee/app/views/projects/settings/ee/_nav.html.haml (1.0ms) Rendered projects/settings/_head.html.haml (7.6ms) Rendered shared/_repository_size_limit_setting.html.haml (0.4ms) ActsAsTaggableOn::Tagging Load (0.3ms) SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 [["taggable_id", 29], ["taggable_type", "Project"]] ActsAsTaggableOn::Tag Load (0.4ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) [["taggable_id", 29], ["taggable_type", "Project"]] Rendered ee/app/views/projects/ee/_issues_settings.html.haml (2.9ms) Rendered ee/app/views/shared/promotions/_promote_mr_features.html.haml (0.1ms) Approver Load (0.4ms) SELECT "approvers".* FROM "approvers" WHERE "approvers"."target_id" = $1 AND "approvers"."target_type" = $2 [["target_id", 29], ["target_type", "Project"]] ApproverGroup Load (0.3ms) SELECT "approver_groups".* FROM "approver_groups" WHERE "approver_groups"."target_id" = $1 AND "approver_groups"."target_type" = $2 [["target_id", 29], ["target_type", "Project"]] Rendered ee/app/views/projects/ee/_merge_request_approvals_settings.html.haml (3.3ms) Rendered ee/app/views/projects/ee/_merge_request_settings.html.haml (5.2ms) Rendered projects/_merge_request_merge_settings.html.haml (0.9ms) Rendered projects/_merge_request_settings.html.haml (7.0ms) Rendered ee/app/views/projects/ee/_service_desk_settings.html.haml (0.1ms) Rendered projects/_export.html.haml (0.8ms) Rendered projects/_errors.html.haml (0.3ms) (0.4ms) SELECT COUNT(*) FROM "services" WHERE "services"."project_id" = $1 AND "services"."category" = $2 [["project_id", 29], ["category", "deployment"]] Group Load (0.6ms) SELECT "namespaces".* FROM "namespaces" INNER JOIN "members" ON "namespaces"."id" = "members"."source_id" WHERE "members"."source_type" = $1 AND "namespaces"."type" IN ('Group') AND "members"."user_id" = $2 AND "namespaces"."type" IN ('Group') AND "members"."access_level" = 50 AND "members"."type" IN ('GroupMember') AND "members"."requested_at" IS NULL [["source_type", "Namespace"], ["user_id", 1]] Group Load (0.5ms) SELECT "namespaces".* FROM "namespaces" INNER JOIN "members" ON "namespaces"."id" = "members"."source_id" WHERE "members"."source_type" = $1 AND "namespaces"."type" IN ('Group') AND "members"."user_id" = $2 AND "namespaces"."type" IN ('Group') AND "members"."access_level" = 40 AND "members"."type" IN ('GroupMember') AND "members"."requested_at" IS NULL [["source_type", "Namespace"], ["user_id", 1]] Namespace Load (0.6ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."owner_id" = $1 AND "namespaces"."type" IS NULL LIMIT 1 [["owner_id", 1]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 3], ["source_type", "Namespace"]] Route Load (0.3ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 4], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 5], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 54], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 55], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 56], ["source_type", "Namespace"]] Route Load (0.1ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 57], ["source_type", "Namespace"]] Route Load (0.1ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 58], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 59], ["source_type", "Namespace"]] Route Load (0.2ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 60], ["source_type", "Namespace"]] Route Load (0.1ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = $1 AND "routes"."source_type" = $2 LIMIT 1 [["source_id", 61], ["source_type", "Namespace"]] User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] Rendered shared/_confirm_modal.html.haml (0.4ms) Rendered projects/edit.html.haml within layouts/project_settings (101.0ms) Rendered layouts/_head.html.haml (61.8ms) Rendered /home/lupine/.gem/ruby/2.3.4/gems/peek-1.0.1/app/views/peek/_bar.html.erb (0.1ms) Rendered layouts/header/_ee_license_banner.html.haml (0.1ms) Rendered shared/_logo.svg (0.1ms) Rendered shared/_logo_type.svg (0.1ms) Rendered shared/icons/_caret_down.svg (0.0ms) Rendered layouts/nav/projects_dropdown/_show.html.haml (1.6ms) Rendered shared/icons/_caret_down.svg (0.0ms) Rendered layouts/nav/_dashboard.html.haml (6.1ms) Rendered shared/icons/_plus_square.svg (0.1ms) Rendered shared/icons/_caret_down.svg (0.0ms) (2.6ms) SELECT COUNT(*) FROM "projects" INNER JOIN "namespaces" ON "projects"."namespace_id" = "namespaces"."id" WHERE "namespaces"."owner_id" = $1 AND "namespaces"."type" IS NULL [["owner_id", 1]] Rendered layouts/header/_new_dropdown.haml (10.5ms) Rendered layouts/_search.html.haml (2.5ms) Rendered shared/icons/_issues.svg (0.0ms) Rendered shared/icons/_mr_bold.svg (0.1ms) Rendered shared/icons/_todo_done.svg (0.1ms) Rendered shared/icons/_caret_down.svg (0.0ms) Rendered shared/_outdated_browser.html.haml (0.1ms) Rendered layouts/header/_default.html.haml (36.2ms) Rendered shared/icons/_project.svg (0.1ms) Rendered shared/icons/_issues.svg (0.0ms) Rendered shared/icons/_mr_bold.svg (0.0ms) Rendered shared/icons/_pipeline.svg (0.1ms) Rendered shared/icons/_wiki.svg (0.0ms) Rendered shared/icons/_snippets.svg (0.0ms) Rendered shared/icons/_settings.svg (0.1ms) Rendered ee/app/views/projects/settings/ee/_nav.html.haml (0.9ms) Rendered shared/_sidebar_toggle_button.html.haml (0.3ms) Rendered layouts/nav/sidebar/_project.html.haml (41.3ms) Rendered layouts/_broadcast.html.haml (1.4ms) Rendered layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml (0.1ms) Rendered layouts/nav/_breadcrumbs.html.haml (0.8ms) Rendered layouts/_flash.html.haml (0.1ms) Rendered layouts/_page.html.haml (46.1ms) Rendered layouts/application.html.haml (147.4ms) Rendered layouts/project.html.haml (150.7ms) Completed 200 OK in 297ms (Views: 244.8ms | ActiveRecord: 17.6ms | Elasticsearch: 0.0ms)
Possible fixes
I think either the project or the wiki rename is actually checking the invariant hashed storage path on disk, noticing that it exists, and so failing the rename for that reason. There's no need to perform this check when hashed storage is enabled.