{"host": "registry2005.codfw.wmnet", "state": "core_diff", "description": "Differences to core resources", "diff": {"full": {"total": 2924, "only_in_self": [], "only_in_other": ["File[/etc/nginx/registry-nginx-proxy-common.conf]"], "resource_diffs": [{"resource": "Nginx::Site[registry]"}, {"resource": "Class[Docker_registry::Web]", "parameters": "--- Class[Docker_registry::Web].orig\n+++ Class[Docker_registry::Web]\n\n+    s3_migrations => {'ml': {'port': 5004, 'auth_mode': 'basic', 'push_file': '/etc/nginx/ml-push.htpasswd', 'prefixes': ['ml']}}\n"}, {"resource": "Class[Profile::Docker_registry]", "parameters": "--- Class[Profile::Docker_registry].orig\n+++ Class[Profile::Docker_registry]\n\n+    s3_migrations => {'ml': {'port': 5004, 'auth_mode': 'basic', 'push_file': '/etc/nginx/ml-push.htpasswd', 'prefixes': ['ml']}}\n"}, {"resource": "File[/etc/nginx/registry-nginx-proxy-common.conf]", "parameters": "--- File[/etc/nginx/registry-nginx-proxy-common.conf].orig\n+++ File[/etc/nginx/registry-nginx-proxy-common.conf]\n\n+    owner   => root\n+    group   => root\n+    require => Package[nginx]\n+    source  => puppet:///modules/docker_registry/registry-nginx-proxy-common.conf\n+    mode    => 0744\n+    ensure  => present\n"}, {"resource": "File[/etc/nginx/sites-available/registry]", "content": "--- /etc/nginx/sites-available/registry.orig\n+++ /etc/nginx/sites-available/registry\n@@ -773,57 +773,42 @@\n       send_timeout                180;\n     }\n \n-    location ~ ^/v2/ml/.* {\n-      # Send all but GET/HEAD requests to @ml location block below\n+    # /v2/{ml}/* are served by the S3-backed\n+    # registry-ml instance. GET/HEAD reads try S3 first and fall\n+    # back to swift on a miss/error (@swift_fallback); writes go only to S3 via\n+    # @ml_write.\n+    location ~ ^/v2/(ml/.*) {\n+\n+      # Send all but GET/HEAD requests to @ml_write below, so that\n+      # only idempotent reads are eligible for the swift fallback.\n       # See <https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/>\n       # which explains and recommends this\n-      error_page 418 = @ml;\n+      error_page 418 = @ml_write;\n       recursive_error_pages on;\n       if ($request_method !~ ^(GET|HEAD)$) {\n         return 418;\n       }\n \n-      # This covers GET/HEAD requests to /v2/ml/\n+\n+      # Try the S3-backed registry first; fall back to swift on a miss/error.\n+      proxy_intercept_errors on;\n+      error_page 404 502 503 504 = @swift_fallback;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n-\n-    }\n-\n-    # This block applies to POST/PUT/DELETE/etc. methods to /v2/ml/\n-    location @ml {\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+\n+    }\n+\n+    # Writes (POST/PUT/DELETE/etc.) for every prefix routed to\n+    # registry-ml land here, and go only to S3 (never swift) to\n+    # avoid splitting an in-progress upload across two stores.\n+    location @ml_write {\n       # Only ml users can push images\n       auth_basic \"docker-registry ml\";\n       auth_basic_user_file /etc/nginx/ml-push.htpasswd;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n     }\n \n     # Capture the original request path here so we can pass it to\n@@ -892,6 +877,19 @@\n \n     }\n \n+    # Generic fallback for prefixes migrating to an S3-backed registry: the\n+    # per-prefix blocks above route here when their S3 backend returns a\n+    # 404/5xx. The original $uri is preserved across the internal redirect, so\n+    # swift is queried for the exact same path. Reads only (write locations\n+    # never route here), so no auth is needed: auth_request already ran on the\n+    # way in.\n+    location @swift_fallback {\n+      internal;\n+      proxy_pass http://registry-swift;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+    }\n+\n+\n     # Below are a number of internal locations used by auth_request to route\n     # to either basic auth or JSON Web Token auth based on the value of\n     # $auth_type (see the geo and map directives at the top). Note it would be"}], "perc_changed": "0.21%"}, "core": {"total": 2924, "only_in_self": [], "only_in_other": ["File[/etc/nginx/registry-nginx-proxy-common.conf]"], "resource_diffs": [{"resource": "File[/etc/nginx/sites-available/registry]", "content": "--- /etc/nginx/sites-available/registry.orig\n+++ /etc/nginx/sites-available/registry\n@@ -773,57 +773,42 @@\n       send_timeout                180;\n     }\n \n-    location ~ ^/v2/ml/.* {\n-      # Send all but GET/HEAD requests to @ml location block below\n+    # /v2/{ml}/* are served by the S3-backed\n+    # registry-ml instance. GET/HEAD reads try S3 first and fall\n+    # back to swift on a miss/error (@swift_fallback); writes go only to S3 via\n+    # @ml_write.\n+    location ~ ^/v2/(ml/.*) {\n+\n+      # Send all but GET/HEAD requests to @ml_write below, so that\n+      # only idempotent reads are eligible for the swift fallback.\n       # See <https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/>\n       # which explains and recommends this\n-      error_page 418 = @ml;\n+      error_page 418 = @ml_write;\n       recursive_error_pages on;\n       if ($request_method !~ ^(GET|HEAD)$) {\n         return 418;\n       }\n \n-      # This covers GET/HEAD requests to /v2/ml/\n+\n+      # Try the S3-backed registry first; fall back to swift on a miss/error.\n+      proxy_intercept_errors on;\n+      error_page 404 502 503 504 = @swift_fallback;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n-\n-    }\n-\n-    # This block applies to POST/PUT/DELETE/etc. methods to /v2/ml/\n-    location @ml {\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+\n+    }\n+\n+    # Writes (POST/PUT/DELETE/etc.) for every prefix routed to\n+    # registry-ml land here, and go only to S3 (never swift) to\n+    # avoid splitting an in-progress upload across two stores.\n+    location @ml_write {\n       # Only ml users can push images\n       auth_basic \"docker-registry ml\";\n       auth_basic_user_file /etc/nginx/ml-push.htpasswd;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n     }\n \n     # Capture the original request path here so we can pass it to\n@@ -892,6 +877,19 @@\n \n     }\n \n+    # Generic fallback for prefixes migrating to an S3-backed registry: the\n+    # per-prefix blocks above route here when their S3 backend returns a\n+    # 404/5xx. The original $uri is preserved across the internal redirect, so\n+    # swift is queried for the exact same path. Reads only (write locations\n+    # never route here), so no auth is needed: auth_request already ran on the\n+    # way in.\n+    location @swift_fallback {\n+      internal;\n+      proxy_pass http://registry-swift;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+    }\n+\n+\n     # Below are a number of internal locations used by auth_request to route\n     # to either basic auth or JSON Web Token auth based on the value of\n     # $auth_type (see the geo and map directives at the top). Note it would be"}], "perc_changed": "0.07%"}, "main": {"total": 2924, "only_in_self": [], "only_in_other": ["File[/etc/nginx/registry-nginx-proxy-common.conf]"], "resource_diffs": [{"resource": "Nginx::Site[registry]"}, {"resource": "Class[Docker_registry::Web]", "parameters": "--- Class[Docker_registry::Web].orig\n+++ Class[Docker_registry::Web]\n\n+    s3_migrations => {'ml': {'port': 5004, 'auth_mode': 'basic', 'push_file': '/etc/nginx/ml-push.htpasswd', 'prefixes': ['ml']}}\n"}, {"resource": "File[/etc/nginx/sites-available/registry]", "content": "--- /etc/nginx/sites-available/registry.orig\n+++ /etc/nginx/sites-available/registry\n@@ -773,57 +773,42 @@\n       send_timeout                180;\n     }\n \n-    location ~ ^/v2/ml/.* {\n-      # Send all but GET/HEAD requests to @ml location block below\n+    # /v2/{ml}/* are served by the S3-backed\n+    # registry-ml instance. GET/HEAD reads try S3 first and fall\n+    # back to swift on a miss/error (@swift_fallback); writes go only to S3 via\n+    # @ml_write.\n+    location ~ ^/v2/(ml/.*) {\n+\n+      # Send all but GET/HEAD requests to @ml_write below, so that\n+      # only idempotent reads are eligible for the swift fallback.\n       # See <https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/>\n       # which explains and recommends this\n-      error_page 418 = @ml;\n+      error_page 418 = @ml_write;\n       recursive_error_pages on;\n       if ($request_method !~ ^(GET|HEAD)$) {\n         return 418;\n       }\n \n-      # This covers GET/HEAD requests to /v2/ml/\n+\n+      # Try the S3-backed registry first; fall back to swift on a miss/error.\n+      proxy_intercept_errors on;\n+      error_page 404 502 503 504 = @swift_fallback;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n-\n-    }\n-\n-    # This block applies to POST/PUT/DELETE/etc. methods to /v2/ml/\n-    location @ml {\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+\n+    }\n+\n+    # Writes (POST/PUT/DELETE/etc.) for every prefix routed to\n+    # registry-ml land here, and go only to S3 (never swift) to\n+    # avoid splitting an in-progress upload across two stores.\n+    location @ml_write {\n       # Only ml users can push images\n       auth_basic \"docker-registry ml\";\n       auth_basic_user_file /etc/nginx/ml-push.htpasswd;\n \n       proxy_pass http://registry-ml;\n-      proxy_redirect off;\n-      proxy_buffering off;\n-      proxy_http_version 1.1;\n-      proxy_set_header Upgrade $http_upgrade;\n-      proxy_set_header Connection $connection_upgrade;\n-      proxy_set_header Proxy-Connection \"Keep-Alive\";\n-      proxy_set_header X-Real-IP $remote_addr;\n-      proxy_set_header X-Forwarded-Proto $scheme;\n-      proxy_set_header Host $host;\n-\n-      proxy_connect_timeout       180;\n-      proxy_send_timeout          180;\n-      proxy_read_timeout          180;\n-      send_timeout                180;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n     }\n \n     # Capture the original request path here so we can pass it to\n@@ -892,6 +877,19 @@\n \n     }\n \n+    # Generic fallback for prefixes migrating to an S3-backed registry: the\n+    # per-prefix blocks above route here when their S3 backend returns a\n+    # 404/5xx. The original $uri is preserved across the internal redirect, so\n+    # swift is queried for the exact same path. Reads only (write locations\n+    # never route here), so no auth is needed: auth_request already ran on the\n+    # way in.\n+    location @swift_fallback {\n+      internal;\n+      proxy_pass http://registry-swift;\n+      include /etc/nginx/registry-nginx-proxy-common.conf;\n+    }\n+\n+\n     # Below are a number of internal locations used by auth_request to route\n     # to either basic auth or JSON Web Token auth based on the value of\n     # $auth_type (see the geo and map directives at the top). Note it would be"}, {"resource": "Class[Profile::Docker_registry]", "parameters": "--- Class[Profile::Docker_registry].orig\n+++ Class[Profile::Docker_registry]\n\n+    s3_migrations => {'ml': {'port': 5004, 'auth_mode': 'basic', 'push_file': '/etc/nginx/ml-push.htpasswd', 'prefixes': ['ml']}}\n"}], "perc_changed": "0.17%"}}}