src: start sending get request with query params
We are incorrectly using formData in a get request. To move away from this we send both query params and formData until the server is fully upgraded. After which we can stop sending formData.pull/1358/head
parent
0186286e06
commit
0f99a0b1c7
|
@ -30,8 +30,6 @@ jobs:
|
|||
|
||||
- name: Check for changes
|
||||
run: |
|
||||
# Ignore yarn.lock changes since we're using npm
|
||||
git update-index --assume-unchanged yarn.lock || true
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
echo "::error::Build generated new changes. Please commit the generated files."
|
||||
git status
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -11,6 +11,7 @@
|
|||
"@docker/actions-toolkit": "0.37.1",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"axios-retry": "^4.5.0",
|
||||
"form-data": "^4.0.1",
|
||||
"handlebars": "^4.7.7",
|
||||
"portfinder": "^1.0.32"
|
||||
},
|
||||
|
@ -511,6 +512,20 @@
|
|||
"xml2js": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/ms-rest-js/node_modules/form-data": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz",
|
||||
"integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12",
|
||||
"safe-buffer": "^5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/ms-rest-js/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
|
@ -2579,9 +2594,9 @@
|
|||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"version": "1.7.9",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
|
||||
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
|
@ -2600,20 +2615,6 @@
|
|||
"axios": "0.x || 1.x"
|
||||
}
|
||||
},
|
||||
"node_modules/axios/node_modules/form-data": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
|
||||
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/b4a": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
|
||||
|
@ -3996,17 +3997,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz",
|
||||
"integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
|
||||
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12",
|
||||
"safe-buffer": "^5.2.1"
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12"
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"@docker/actions-toolkit": "0.37.1",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"axios-retry": "^4.5.0",
|
||||
"form-data": "^4.0.1",
|
||||
"handlebars": "^4.7.7",
|
||||
"portfinder": "^1.0.32"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import * as reporter from '../reporter';
|
||||
import { getStickyDisk } from '../setup_builder';
|
||||
import FormData from 'form-data';
|
||||
|
||||
jest.mock('../reporter');
|
||||
|
||||
describe('getStickyDisk', () => {
|
||||
const mockGet = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
process.env.GITHUB_REPO_NAME = 'test-repo';
|
||||
process.env.BLACKSMITH_REGION = 'test-region';
|
||||
process.env.BLACKSMITH_INSTALLATION_MODEL_ID = 'test-model';
|
||||
process.env.VM_ID = 'test-vm';
|
||||
|
||||
(reporter.createBlacksmithAgentClient as jest.Mock).mockResolvedValue({});
|
||||
(reporter.get as jest.Mock).mockImplementation(mockGet);
|
||||
mockGet.mockResolvedValue({
|
||||
data: {
|
||||
expose_id: 'test-expose-id',
|
||||
disk_identifier: 'test-device'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('sets both FormData and query parameters correctly', async () => {
|
||||
const appendSpy = jest.spyOn(FormData.prototype, 'append');
|
||||
|
||||
await getStickyDisk();
|
||||
|
||||
expect(mockGet).toHaveBeenCalledTimes(1);
|
||||
const [, url, formData] = mockGet.mock.calls[0];
|
||||
|
||||
// Verify query parameters
|
||||
expect(url).toContain('stickyDiskKey=test-repo');
|
||||
expect(url).toContain('region=test-region');
|
||||
expect(url).toContain('installationModelID=test-model');
|
||||
expect(url).toContain('vmID=test-vm');
|
||||
|
||||
// Verify FormData is correct type
|
||||
expect(formData instanceof FormData).toBeTruthy();
|
||||
|
||||
// Verify the headers are set correctly
|
||||
const headers = formData.getHeaders();
|
||||
expect(headers['content-type']).toContain('multipart/form-data');
|
||||
|
||||
// Verify the correct fields were appended
|
||||
expect(appendSpy).toHaveBeenCalledWith('stickyDiskKey', 'test-repo');
|
||||
expect(appendSpy).toHaveBeenCalledWith('region', 'test-region');
|
||||
expect(appendSpy).toHaveBeenCalledWith('installationModelID', 'test-model');
|
||||
expect(appendSpy).toHaveBeenCalledWith('vmID', 'test-vm');
|
||||
});
|
||||
});
|
|
@ -2,6 +2,7 @@ import * as core from '@actions/core';
|
|||
import axios, {AxiosError, AxiosInstance, AxiosResponse, AxiosStatic } from 'axios';
|
||||
import axiosRetry from 'axios-retry';
|
||||
import {ExportRecordResponse} from '@docker/actions-toolkit/lib/types/buildx/history';
|
||||
import FormData from 'form-data';
|
||||
|
||||
// Configure base axios instance for Blacksmith API.
|
||||
const createBlacksmithAPIClient = () => {
|
||||
|
@ -33,7 +34,11 @@ const createBlacksmithAPIClient = () => {
|
|||
export async function createBlacksmithAgentClient(): Promise<AxiosInstance> {
|
||||
const stickyDiskMgrUrl = 'http://192.168.127.1:5556';
|
||||
const client = axios.create({
|
||||
baseURL: stickyDiskMgrUrl
|
||||
baseURL: stickyDiskMgrUrl,
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.BLACKSMITH_STICKYDISK_TOKEN}`,
|
||||
'X-Github-Repo-Name': process.env.GITHUB_REPO_NAME || '',
|
||||
}
|
||||
});
|
||||
|
||||
axiosRetry(client, {
|
||||
|
@ -78,11 +83,7 @@ export async function reportBuildCompleted(exportRes?: ExportRecordResponse, bla
|
|||
formData.append('exposeID', exposeId || '');
|
||||
formData.append('stickyDiskKey', process.env.GITHUB_REPO_NAME || '');
|
||||
|
||||
await agentClient.post('/stickydisks', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
await post(agentClient, '/stickydisks', formData);
|
||||
|
||||
// Report success to Blacksmith API
|
||||
const requestOptions = {
|
||||
|
@ -131,11 +132,7 @@ export async function reportBuildFailed(dockerBuildId: string | null, dockerBuil
|
|||
formData.append('exposeID', exposeId || '');
|
||||
formData.append('stickyDiskKey', process.env.GITHUB_REPO_NAME || '');
|
||||
|
||||
await blacksmithAgentClient.post('/stickydisks', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
await post(blacksmithAgentClient, '/stickydisks', formData);
|
||||
|
||||
// Report failure to Blacksmith API
|
||||
const requestOptions = {
|
||||
|
@ -180,9 +177,18 @@ export async function get(client: AxiosInstance, url: string, formData: FormData
|
|||
return await client.get(url, {
|
||||
...(formData && {data: formData}),
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.BLACKSMITH_STICKYDISK_TOKEN}`,
|
||||
'X-Github-Repo-Name': process.env.GITHUB_REPO_NAME || '',
|
||||
'Content-Type': 'multipart/form-data'
|
||||
...client.defaults.headers.common,
|
||||
...(formData && {'Content-Type': 'multipart/form-data'})
|
||||
},
|
||||
signal: options?.signal
|
||||
});
|
||||
}
|
||||
|
||||
export async function post(client: AxiosInstance, url: string, formData: FormData | null, options?: {signal?: AbortSignal}): Promise<AxiosResponse> {
|
||||
return await client.post(url, formData, {
|
||||
headers: {
|
||||
...client.defaults.headers.common,
|
||||
...(formData && { 'Content-Type': 'multipart/form-data' }),
|
||||
},
|
||||
signal: options?.signal
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@ import {exec} from 'child_process';
|
|||
import {promisify} from 'util';
|
||||
import * as TOML from '@iarna/toml';
|
||||
import * as reporter from './reporter';
|
||||
import FormData from 'form-data';
|
||||
|
||||
const mountPoint = '/var/lib/buildkit';
|
||||
const execAsync = promisify(exec);
|
||||
|
@ -143,25 +144,38 @@ async function getDiskSize(device: string): Promise<number> {
|
|||
}
|
||||
}
|
||||
|
||||
async function getStickyDisk(options?: {signal?: AbortSignal}): Promise<{expose_id: string; device: string}> {
|
||||
export async function getStickyDisk(options?: {signal?: AbortSignal}): Promise<{expose_id: string; device: string}> {
|
||||
const client = await reporter.createBlacksmithAgentClient();
|
||||
const formData = new FormData();
|
||||
// TODO(adityamaru): Support a stickydisk-per-build flag that will namespace the stickydisks by Dockerfile.
|
||||
// For now, we'll use the repo name as the stickydisk key.
|
||||
const repoName = process.env.GITHUB_REPO_NAME || '';
|
||||
if (repoName === '') {
|
||||
|
||||
// Prepare data for both FormData and query params
|
||||
const stickyDiskKey = process.env.GITHUB_REPO_NAME || '';
|
||||
if (stickyDiskKey === '') {
|
||||
throw new Error('GITHUB_REPO_NAME is not set');
|
||||
}
|
||||
formData.append('stickyDiskKey', repoName);
|
||||
formData.append('region', process.env.BLACKSMITH_REGION || 'eu-central');
|
||||
formData.append('installationModelID', process.env.BLACKSMITH_INSTALLATION_MODEL_ID || '');
|
||||
formData.append('vmID', process.env.VM_ID || '');
|
||||
core.debug(`Getting sticky disk for ${repoName}`);
|
||||
core.debug('FormData contents:');
|
||||
for (const pair of formData.entries()) {
|
||||
core.debug(`${pair[0]}: ${pair[1]}`);
|
||||
}
|
||||
const response = await reporter.get(client, '/stickydisks', formData, options);
|
||||
const region = process.env.BLACKSMITH_REGION || 'eu-central';
|
||||
const installationModelID = process.env.BLACKSMITH_INSTALLATION_MODEL_ID || '';
|
||||
const vmID = process.env.VM_ID || '';
|
||||
|
||||
// Create FormData (for backwards compatibility).
|
||||
// TODO(adityamaru): Remove this once all of our VM agents are reading query params.
|
||||
const formData = new FormData();
|
||||
formData.append('stickyDiskKey', stickyDiskKey);
|
||||
formData.append('region', region);
|
||||
formData.append('installationModelID', installationModelID);
|
||||
formData.append('vmID', vmID);
|
||||
|
||||
// Create query params string.
|
||||
const queryParams = new URLSearchParams({
|
||||
stickyDiskKey,
|
||||
region,
|
||||
installationModelID,
|
||||
vmID
|
||||
}).toString();
|
||||
|
||||
core.debug(`Getting sticky disk for ${stickyDiskKey}`);
|
||||
|
||||
// Send request with both FormData and query params
|
||||
const response = await reporter.get(client, `/stickydisks?${queryParams}`, formData, options);
|
||||
const exposeId = response.data?.expose_id || '';
|
||||
const device = response.data?.disk_identifier || '';
|
||||
return {expose_id: exposeId, device: device};
|
||||
|
|
Loading…
Reference in New Issue