Skip to content

Commit 5e40d25

Browse files
authored
Merge pull request #114 from devsapp/fix-permission
fix: s tools for windows permission
2 parents 1b13711 + 91479e3 commit 5e40d25

File tree

11 files changed

+1514
-0
lines changed

11 files changed

+1514
-0
lines changed

__tests__/e2e/ci-windows.ps1

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,31 @@ $ErrorActionPreference = "Stop"
66
# $env:OS="WIN"
77
# $env:PROCESSOR_ARCHITECTURE="NT"
88

9+
Write-Host "[PERMISSIONS_TEST] Testing nodejs permissions validation ..."
10+
cd nodejs
11+
Write-Host "[PERMISSIONS_TEST] Running permissions validation test..." -ForegroundColor Green
12+
& ./check-permissions-before-deploy.ps1
13+
14+
# Test Windows-specific deployment
15+
$env:fc_component_function_name = "nodejs18-$($env:OS)-$($env:PROCESSOR_ARCHITECTURE)-$($env:RANDSTR)"
16+
s deploy -y -t ./s_permission.yaml
17+
s invoke -e '{"hello":"fc nodejs with auto"}' -t ./s_permission.yaml
18+
s info -y -t ./s_permission.yaml
19+
20+
# Check permissions after deployment and handle result
21+
Write-Host "[PERMISSIONS_TEST] Checking permissions after deployment..." -ForegroundColor Green
22+
& ./check-permissions-after-deploy.ps1
23+
if ($LASTEXITCODE -ne 0) {
24+
Write-Host "ERROR: PERMISSIONS TEST FAILED - setNodeModulesBinPermissions is not working correctly" -ForegroundColor Red
25+
exit 1
26+
} else {
27+
Write-Host "SUCCESS: PERMISSIONS TEST PASSED - setNodeModulesBinPermissions is working correctly" -ForegroundColor Green
28+
}
29+
30+
s remove -y -t ./s_permission.yaml
31+
cd ..
32+
cd ..
33+
934
Write-Host "test go runtime"
1035
cd go
1136
$env:fc_component_function_name = "go1-$($env:OS)-$($env:PROCESSOR_ARCHITECTURE)-$($env:RANDSTR)"
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Windows PowerShell script for checking permissions after deployment
2+
3+
Write-Host "=== Checking Permissions After Deployment ==="
4+
5+
# Change to the nodejs directory
6+
Set-Location -Path "$PSScriptRoot"
7+
8+
cd test-permission-code
9+
10+
# Function to check permissions and return result
11+
function Check-Permissions {
12+
param([string]$Label)
13+
14+
Write-Host "[$Label] Checking permissions..." -ForegroundColor Yellow
15+
16+
# Create temporary JS file for checking permissions
17+
$jsCode = @"
18+
const fs = require('fs');
19+
const path = require('path');
20+
21+
console.log('=== ' + process.argv[1] + ' Permissions State ===');
22+
23+
const binPath = path.join('.', 'node_modules', '.bin');
24+
if (fs.existsSync(binPath)) {
25+
console.log('✓ node_modules/.bin found');
26+
const files = fs.readdirSync(binPath);
27+
28+
let executableCount = 0;
29+
let totalCount = 0;
30+
31+
// Check permissions of first 5 files
32+
files.slice(0, 5).forEach(file => {
33+
const filePath = path.join(binPath, file);
34+
try {
35+
const stat = fs.statSync(filePath);
36+
if (!stat.isDirectory()) {
37+
totalCount++;
38+
// Cross-platform executable check
39+
let hasExecutePermission = false;
40+
41+
if (process.platform === 'win32') {
42+
// On Windows, check file extension for common executable types
43+
const ext = path.extname(file).toLowerCase();
44+
hasExecutePermission = (
45+
ext === '.exe' ||
46+
ext === '.cmd' ||
47+
ext === '.bat' ||
48+
ext === '.ps1' ||
49+
ext === '.com' ||
50+
ext === '.msi'
51+
);
52+
} else {
53+
// Unix way
54+
hasExecutePermission = (stat.mode & 0o111) !== 0;
55+
}
56+
57+
if (hasExecutePermission) {
58+
executableCount++;
59+
}
60+
console.log(file + ': ' + (hasExecutePermission ? 'EXECUTABLE' : 'NON-EXECUTABLE') + ' (mode: ' + stat.mode.toString(8) + ', platform: ' + process.platform + ')');
61+
} else {
62+
console.log(file + ': DIRECTORY');
63+
}
64+
} catch (e) {
65+
console.log(file + ': ERROR - ' + e.message);
66+
}
67+
});
68+
69+
// Return result for validation
70+
console.log('=== RESULT_FOR_VALIDATION ===');
71+
console.log('TOTAL_FILES:' + totalCount);
72+
console.log('EXECUTABLE_FILES:' + executableCount);
73+
console.log('=== END_RESULT ===');
74+
} else {
75+
console.log('node_modules/.bin not found');
76+
console.log('=== RESULT_FOR_VALIDATION ===');
77+
console.log('TOTAL_FILES:0');
78+
console.log('EXECUTABLE_FILES:0');
79+
console.log('=== END_RESULT ===');
80+
}
81+
82+
console.log('=== ' + process.argv[1] + ' State Recorded ===');
83+
"@
84+
85+
# Save to temp file and execute
86+
$tempFile = [System.IO.Path]::GetTempFileName() + ".js"
87+
$jsCode | Out-File -FilePath $tempFile -Encoding UTF8
88+
try {
89+
$result = node $tempFile $Label
90+
return $result
91+
} finally {
92+
if (Test-Path $tempFile) {
93+
Remove-Item $tempFile -Force
94+
}
95+
}
96+
}
97+
98+
# Record final permissions after deployment and validate
99+
$resultLines = Check-Permissions "AFTER_DEPLOYMENT"
100+
101+
# Parse validation results
102+
$totalFiles = 0
103+
$executableFiles = 0
104+
105+
foreach ($line in $resultLines) {
106+
if ($line -match "TOTAL_FILES:(\d+)") {
107+
$totalFiles = [int]$matches[1]
108+
}
109+
if ($line -match "EXECUTABLE_FILES:(\d+)") {
110+
$executableFiles = [int]$matches[1]
111+
}
112+
}
113+
114+
Write-Host "=== Validation Results ===" -ForegroundColor Cyan
115+
Write-Host "Total files checked: $totalFiles" -ForegroundColor Cyan
116+
Write-Host "Executable files: $executableFiles" -ForegroundColor Cyan
117+
118+
# Automated validation - Simplified approach: just need some executable files to verify the fix worked
119+
# This is a more realistic test - we don't need ALL files to be executable, just need to verify
120+
# that the permission restoration mechanism is working (at least one file should be restored)
121+
if ($totalFiles -gt 0 -and $executableFiles -gt 0) {
122+
Write-Host "SUCCESS: EST PASSED: $executableFiles/$totalFiles files have executable permissions (at least one file restored)" -ForegroundColor Green
123+
Write-Host "=== setNodeModulesBinPermissions function is working correctly ===" -ForegroundColor Green
124+
exit 0 # Success exit code
125+
} elseif ($totalFiles -gt 0) {
126+
Write-Host "ERROR: TEST FAILED: No files have executable permissions" -ForegroundColor Red
127+
Write-Host "=== setNodeModulesBinPermissions function is NOT working correctly ===" -ForegroundColor Red
128+
exit 1 # Failure exit code
129+
} else {
130+
Write-Host "WARNING: No files found to validate" -ForegroundColor Yellow
131+
exit 0 # Consider this as success since there's nothing to fix
132+
}
133+
134+
Write-Host "=== Post-deployment permissions check completed ===" -ForegroundColor Cyan
135+
136+
cd ..
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Windows PowerShell script for testing setNodeModulesBinPermissions functionality
2+
3+
Write-Host "=== Testing setNodeModulesBinPermissions Functionality ==="
4+
5+
# Change to the nodejs directory
6+
Set-Location -Path "$PSScriptRoot"
7+
8+
# Run the function locally first
9+
Write-Host "Running permissions validation test..." -ForegroundColor Green
10+
cd test-permission-code
11+
12+
# Check if node_modules exists, install if not
13+
if (-not (Test-Path "node_modules")) {
14+
Write-Host "Installing dependencies..."
15+
npm install
16+
}
17+
18+
# Function to check and record permissions
19+
function Check-Permissions {
20+
param([string]$Label)
21+
22+
Write-Host "[$Label] Checking permissions..." -ForegroundColor Yellow
23+
24+
# Create temporary JS file for checking permissions
25+
$jsCode = @"
26+
const fs = require('fs');
27+
const path = require('path');
28+
29+
console.log('=== ' + process.argv[1] + ' Permissions State ===');
30+
31+
const binPath = path.join('.', 'node_modules', '.bin');
32+
if (fs.existsSync(binPath)) {
33+
console.log('✓ node_modules/.bin found');
34+
const files = fs.readdirSync(binPath);
35+
36+
let executableCount = 0;
37+
let totalCount = 0;
38+
39+
// Record permissions of first 5 files
40+
files.slice(0, 5).forEach(file => {
41+
const filePath = path.join(binPath, file);
42+
try {
43+
const stat = fs.statSync(filePath);
44+
if (!stat.isDirectory()) {
45+
totalCount++;
46+
// Cross-platform executable check
47+
let hasExecutePermission = false;
48+
49+
if (process.platform === 'win32') {
50+
// On Windows, check file extension for common executable types
51+
const ext = path.extname(file).toLowerCase();
52+
hasExecutePermission = (
53+
ext === '.exe' ||
54+
ext === '.cmd' ||
55+
ext === '.bat' ||
56+
ext === '.ps1' ||
57+
ext === '.com' ||
58+
ext === '.msi'
59+
);
60+
} else {
61+
// Unix way
62+
hasExecutePermission = (stat.mode & 0o111) !== 0;
63+
}
64+
65+
if (hasExecutePermission) {
66+
executableCount++;
67+
}
68+
console.log(file + ': ' + (hasExecutePermission ? 'EXECUTABLE' : 'NON-EXECUTABLE') + ' (mode: ' + stat.mode.toString(8) + ', platform: ' + process.platform + ')');
69+
} else {
70+
console.log(file + ': DIRECTORY');
71+
}
72+
} catch (e) {
73+
console.log(file + ': ERROR - ' + e.message);
74+
}
75+
});
76+
77+
// Return result for validation
78+
console.log('=== RESULT_FOR_VALIDATION ===');
79+
console.log('TOTAL_FILES:' + totalCount);
80+
console.log('EXECUTABLE_FILES:' + executableCount);
81+
console.log('=== END_RESULT ===');
82+
} else {
83+
console.log('node_modules/.bin not found');
84+
console.log('=== RESULT_FOR_VALIDATION ===');
85+
console.log('TOTAL_FILES:0');
86+
console.log('EXECUTABLE_FILES:0');
87+
console.log('=== END_RESULT ===');
88+
}
89+
90+
console.log('=== ' + process.argv[1] + ' State Recorded ===');
91+
"@
92+
93+
# Save to temp file and execute
94+
$tempFile = [System.IO.Path]::GetTempFileName() + ".js"
95+
$jsCode | Out-File -FilePath $tempFile -Encoding UTF8
96+
try {
97+
$result = node $tempFile $Label
98+
return $result
99+
} finally {
100+
if (Test-Path $tempFile) {
101+
Remove-Item $tempFile -Force
102+
}
103+
}
104+
}
105+
106+
# Record initial permissions
107+
$resultLines = Check-Permissions "BEFORE"
108+
109+
# Parse initial validation results
110+
$initialTotalFiles = 0
111+
$initialExecutableFiles = 0
112+
113+
foreach ($line in $resultLines) {
114+
if ($line -match "TOTAL_FILES:(\d+)") {
115+
$initialTotalFiles = [int]$matches[1]
116+
}
117+
if ($line -match "EXECUTABLE_FILES:(\d+)") {
118+
$initialExecutableFiles = [int]$matches[1]
119+
}
120+
}
121+
122+
Write-Host "[BEFORE] Found $initialExecutableFiles/$initialTotalFiles executable files" -ForegroundColor Cyan
123+
124+
# Modify permissions to make them non-executable (simulate issue)
125+
Write-Host "[MODIFY] Making files non-executable to test fix..." -ForegroundColor Yellow
126+
127+
$modifyJsCode = @"
128+
const fs = require('fs');
129+
const path = require('path');
130+
131+
const binPath = path.join('.', 'node_modules', '.bin');
132+
if (fs.existsSync(binPath)) {
133+
const files = fs.readdirSync(binPath);
134+
135+
// Remove executable permissions from first 3 files
136+
files.slice(0, 3).forEach(file => {
137+
const filePath = path.join(binPath, file);
138+
try {
139+
const stat = fs.statSync(filePath);
140+
if (!stat.isDirectory()) {
141+
// Remove executable bits
142+
const newMode = stat.mode & ~0o111;
143+
fs.chmodSync(filePath, newMode);
144+
console.log('✓ Made non-executable: ' + file + ' (new mode: ' + newMode.toString(8) + ')');
145+
}
146+
} catch (e) {
147+
console.log('✗ Error modifying ' + file + ': ' + e.message);
148+
}
149+
});
150+
}
151+
"@
152+
153+
# Save to temp file and execute
154+
$tempModifyFile = [System.IO.Path]::GetTempFileName() + ".js"
155+
$modifyJsCode | Out-File -FilePath $tempModifyFile -Encoding UTF8
156+
try {
157+
node $tempModifyFile
158+
} finally {
159+
if (Test-Path $tempModifyFile) {
160+
Remove-Item $tempModifyFile -Force
161+
}
162+
}
163+
164+
# Record permissions after modification
165+
$resultLines = Check-Permissions "AFTER_MODIFY"
166+
167+
# Parse modified validation results
168+
$modifiedTotalFiles = 0
169+
$modifiedExecutableFiles = 0
170+
171+
foreach ($line in $resultLines) {
172+
if ($line -match "TOTAL_FILES:(\d+)") {
173+
$modifiedTotalFiles = [int]$matches[1]
174+
}
175+
if ($line -match "EXECUTABLE_FILES:(\d+)") {
176+
$modifiedExecutableFiles = [int]$matches[1]
177+
}
178+
}
179+
180+
Write-Host "[AFTER_MODIFY] Found $modifiedExecutableFiles/$modifiedTotalFiles executable files" -ForegroundColor Cyan
181+
182+
# Verify that we successfully reduced executable files
183+
if ($initialExecutableFiles -gt $modifiedExecutableFiles) {
184+
Write-Host "SUCCESS: Successfully reduced executable files from $initialExecutableFiles to $modifiedExecutableFiles" -ForegroundColor Green
185+
} else {
186+
Write-Host "Warning: Executable file count not reduced (before: $initialExecutableFiles, after: $modifiedExecutableFiles)" -ForegroundColor Yellow
187+
}
188+
189+
Write-Host "=== Pre-deployment setup completed ===" -ForegroundColor Cyan
190+
Write-Host "Now proceeding with: s deploy -y -t s_permission.yaml" -ForegroundColor Cyan
191+
Write-Host "After deployment, check if permissions were restored!" -ForegroundColor Cyan
192+
193+
cd ..

__tests__/e2e/nodejs/run

100755100644
File mode changed.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
edition: 3.0.0
2+
name: test-nodejs-app
3+
access: quanxi
4+
5+
vars:
6+
region: ${env('REGION', 'cn-hongkong')}
7+
8+
resources:
9+
fcDemo:
10+
component: ${env('fc_component_version', path('../../../'))}
11+
props:
12+
region: ${vars.region}
13+
functionName: fc3-event-${env('fc_component_function_name', 'nodejs18')}-permission
14+
runtime: nodejs18
15+
code: ./test-permission-code
16+
handler: index.handler
17+
memorySize: 128
18+
timeout: 30
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports.handler = async function(event, context, callback) {
2+
return 'hello world';
3+
};

0 commit comments

Comments
 (0)