Skip to content

Copy location task reads source location with s3 sdk with STS - #2805

Open
SylvainSenechal wants to merge 1 commit into
development/9.5from
improvement/BB-812
Open

Copy location task reads source location with s3 sdk with STS#2805
SylvainSenechal wants to merge 1 commit into
development/9.5from
improvement/BB-812

Conversation

@SylvainSenechal

@SylvainSenechal SylvainSenechal commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

This pr handles the necessary modification to copyLocation task, so that the clean room can use it to pull object data from the production site.
The main change is basically modifying the way we set up the s3 clients in copyLocationTask, depending on the location of the object. This requires storing and exposing the location configuration which we didn't do before.

Issue: BB-812

@bert-e

bert-e commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Hello sylvainsenechal,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request.
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue BB-812 contains:

  • None

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 9.5.0

Please check the Fix Version/s of BB-812, or the target
branch of this pull request.

Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.46154% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.55%. Comparing base (52b9510) to head (c9e4bb6).

Files with missing lines Patch % Lines
extensions/replication/tasks/CopyLocationTask.js 90.69% 4 Missing ⚠️
lib/Config.js 66.66% 1 Missing ⚠️
lib/management/operatorBackend.js 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

Files with missing lines Coverage Δ
...sions/replication/queueProcessor/QueueProcessor.js 75.61% <100.00%> (+0.33%) ⬆️
lib/Config.js 75.91% <66.66%> (-0.21%) ⬇️
lib/management/operatorBackend.js 48.78% <0.00%> (-1.22%) ⬇️
extensions/replication/tasks/CopyLocationTask.js 69.59% <90.69%> (+2.57%) ⬆️

... and 2 files with indirect coverage changes

Components Coverage Δ
Bucket Notification 80.27% <ø> (ø)
Core Library 81.30% <50.00%> (-0.64%) ⬇️
Ingestion 70.09% <ø> (ø)
Lifecycle 80.46% <ø> (ø)
Oplog Populator 85.83% <ø> (ø)
Replication 62.44% <91.66%> (+0.43%) ⬆️
Bucket Scanner 85.76% <ø> (ø)
@@                 Coverage Diff                 @@
##           development/9.5    #2805      +/-   ##
===================================================
- Coverage            75.76%   75.55%   -0.22%     
===================================================
  Files                  200      200              
  Lines                13922    13968      +46     
===================================================
+ Hits                 10548    10553       +5     
- Misses                3364     3405      +41     
  Partials                10       10              
Flag Coverage Δ
api:retry 9.08% <1.92%> (-0.03%) ⬇️
api:routes 8.85% <1.92%> (-0.03%) ⬇️
bucket-scanner 85.76% <ø> (ø)
ft_test:queuepopulator 9.12% <1.92%> (-1.87%) ⬇️
ingestion 12.23% <1.92%> (-0.04%) ⬇️
lifecycle 19.24% <1.92%> (-0.06%) ⬇️
notification 1.01% <0.00%> (-0.01%) ⬇️
oplogPopulator 0.13% <0.00%> (-0.01%) ⬇️
replication 18.91% <36.53%> (+0.06%) ⬆️
unit 55.00% <78.84%> (+0.11%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
Comment thread extensions/replication/tasks/CopyLocationTask.js
Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
}));
const locations = require('../../conf/locationConfig.json') || {};

config.setLocationConstraints(locations);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

patchConfiguration.js::updateLocations also updates setBootstrapList and setIsTransientLocation but does not call setLocationConstraints. Locations updated through the dynamic configuration path (Orbit/cloud deployments) won't be stored, so config.getLocationConstraint() will return undefined and the isCRR branch in _sendGetObject will never be taken.

Add config.setLocationConstraints(locations) in patchConfiguration.js::updateLocations alongside the existing setBootstrapList call.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is relevant, we don't really care bout backbeat running in orbit mode 🤔


const { errors, jsutil, models } = require('arsenal');
const { ObjectMD } = models;
const { S3Client: AwsS3Client, GetObjectCommand: AwsGetObjectCommand } =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can discuss these renaming
It's just that we are using getObject from both the official aws SDK, and from our cloudserverClient

this.logger = new Logger(
`Backbeat:Replication:QueueProcessor:${this.site}`);

this.assumedRoleCredentialsManager = new CredentialsManager(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure if this is the best place : queueProcessor does create a new copyLocation Task for each kafka entry so we can't put these in CopyLocationTask class otherwise its useless, but we may also have multiple instances of queue processor depending on the config which means we would have multiple credentials managers/clients for the same authentification

* @param {AbortController} abortController - abort controller for the GET request
* @return {Promise} resolves to the GetObject response
*/
async _sendGetObject(actionEntry, objMD, range, log, abortController) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For those who wanna understand the pr's main idea :

Before : We only used our backbeatClient (cloudserver client) to get object, that backbeat client asked cloudserver to deal with reading the data based on the location.

But Cloudserver is not capable of reading data from external CRR locations.

Now : When the object's location is "CRR", we use a classic S3 client with sts to directly get the data without going through cloudserver

@SylvainSenechal
SylvainSenechal marked this pull request as ready for review August 19, 2026 14:02
@SylvainSenechal
SylvainSenechal requested review from a team, benzekrimaha and delthas August 19, 2026 14:02
Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
Comment thread extensions/replication/tasks/CopyLocationTask.js Outdated
@bert-e

bert-e commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue BB-812 contains:

  • 9.6.0

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 9.5.0

  • 9.6.0

Please check the Fix Version/s of BB-812, or the target
branch of this pull request.

@SylvainSenechal SylvainSenechal changed the title Copy location task reads source location from s3 with STS Copy location task reads source location with s3 sdk with STS Aug 19, 2026
* @param {AbortController} abortController - abort controller for the GET request
* @return {Promise} resolves to the GetObject response
*/
async _sendGetObject(actionEntry, objMD, range, log, abortController) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this function does 2 things, which are orthogonal concerns:

  • it retrieves/builds a client, depending on location : either the (exisitng/global) backbeatClient, or the new STS client if required.
  • it send the actual command

it would seem more appropriate to split responsability, and introduce a "getClient" function - then fallthrough to the existing code.......but I see you don't pass the same parameter, to the command: see https://github.com/scality/backbeat/pull/2805/changes#r3819951224

Key: objMD.getKey(),
VersionId: part.dataStoreVersionId,
Range: range && `bytes=${range.start}-${range.end}`,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the parameters should be mostly the same as the regular ones:

  • bucket, key and version shoud come from the message's actionEntry.getAttribute('target'), same as the other case
  • need to pass the requestUids as well

the only difference is the locationConstraint indeed.....and the object type AwsGetObjectCommand vs BackbeatRoutesGetObjectCommand

  • I wonder if/why locationConstraint is used here, should not be needed most of the time - but maybe in case of transient location or similarly advanced/corner case. So indeed should not be changed I guess (for the regular transition path), let's not take risk ; and must not be added to the STS path indeed.
  • the "target" of CopyLocationTask is not a random S3 server, this is really a cloudserver. So we can and should use CloudServerClient and our own 'extensions' (RequestUids)

Comment on lines +189 to +196
const locations = objMD.getLocation();
const part = locations && locations[0];
if (!part || !part.role) {
const err = errors.AccessDenied.customizeDescription(
'missing role on location part for isCRR source location');
err.retryable = true;
throw err;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't have the full design in mind anymore, but I think params should be in the kafka message instea?

when we create the message, we will anyway parse the ObjMD : so this location validation/... would better be done there only (in particular adding the role to actionEntry.getAttribute('target')), so in CopyLocationTask we only need to do it.

this also matches the current 'design' of CopyLocationTask : it copies data from actionEntry.getAttribute('target') to the object's location, and does try to check what is currently in ObjMD's location - which may (or may not) help to avoid some race conditions, not sure...

(STS could even be 'triggered' not just by locationConfig?.isCRR but by actionEntry.getAttribute('target').role ? Either way, will need to access the location for creds/hosts...)

What do you think? Can you evaluate impact and confirm?

* @throws {ArsenalError} AccessDenied (retryable) if credentials
* could not be obtained for the role
*/
_getAssumedRoleS3Client(locationConfig, roleArn, log) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't we have this (or similar) function in CRR ?
can't we dedup and use the same function?

@bert-e

bert-e commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue BB-812 contains:

  • 9.6.0

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 9.5.1

  • 9.6.0

Please check the Fix Version/s of BB-812, or the target
branch of this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants