Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e6154b0de | ||
|
|
d29f71a92f | ||
|
|
aea14cda7e | ||
|
|
4893ccda6e |
@@ -199,6 +199,17 @@ export function ConfigurationModal({
|
||||
return !isNaN(num) && num > 0;
|
||||
};
|
||||
|
||||
const validateHostname = (hostname: string): boolean => {
|
||||
if (!hostname || hostname.length > 253) return false;
|
||||
const label = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
|
||||
const labels = hostname.split('.');
|
||||
return labels.length >= 1 && labels.every(l => l.length >= 1 && l.length <= 63 && label.test(l));
|
||||
};
|
||||
|
||||
const validateAptCacherAddress = (value: string): boolean => {
|
||||
return validateIPv4(value) || validateHostname(value);
|
||||
};
|
||||
|
||||
const validateForm = (): boolean => {
|
||||
const newErrors: Record<string, string> = {};
|
||||
|
||||
@@ -216,8 +227,8 @@ export function ConfigurationModal({
|
||||
if (advancedVars.var_ns && !validateIPv4(advancedVars.var_ns as string)) {
|
||||
newErrors.var_ns = 'Invalid IPv4 address';
|
||||
}
|
||||
if (advancedVars.var_apt_cacher_ip && !validateIPv4(advancedVars.var_apt_cacher_ip as string)) {
|
||||
newErrors.var_apt_cacher_ip = 'Invalid IPv4 address';
|
||||
if (advancedVars.var_apt_cacher_ip && !validateAptCacherAddress(advancedVars.var_apt_cacher_ip as string)) {
|
||||
newErrors.var_apt_cacher_ip = 'Invalid IPv4 address or hostname';
|
||||
}
|
||||
// Validate IPv4 CIDR if network mode is static
|
||||
const netValue = advancedVars.var_net;
|
||||
@@ -904,13 +915,13 @@ export function ConfigurationModal({
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-foreground mb-2">
|
||||
APT Cacher IP
|
||||
APT Cacher host or IP
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
value={typeof advancedVars.var_apt_cacher_ip === 'boolean' ? '' : String(advancedVars.var_apt_cacher_ip ?? '')}
|
||||
onChange={(e) => updateAdvancedVar('var_apt_cacher_ip', e.target.value)}
|
||||
placeholder="192.168.1.10"
|
||||
placeholder="192.168.1.10 or apt-cacher.internal"
|
||||
className={errors.var_apt_cacher_ip ? 'border-destructive' : ''}
|
||||
/>
|
||||
{errors.var_apt_cacher_ip && (
|
||||
|
||||
@@ -2068,32 +2068,72 @@ export const installedScriptsRouter = createTRPCRouter({
|
||||
};
|
||||
}
|
||||
|
||||
// Get the script's interface_port from metadata (prioritize metadata over existing database values)
|
||||
let detectedPort = 80; // Default fallback
|
||||
|
||||
// Resolve app slug from /usr/bin/update (community-scripts) when available; else from hostname/suffix.
|
||||
let slugFromUpdate: string | null = null;
|
||||
try {
|
||||
const updateCommand = `pct exec ${scriptData.container_id} -- cat /usr/bin/update 2>/dev/null`;
|
||||
let updateOutput = '';
|
||||
await new Promise<void>((resolve) => {
|
||||
void sshExecutionService.executeCommand(
|
||||
server as Server,
|
||||
updateCommand,
|
||||
(data: string) => { updateOutput += data; },
|
||||
() => {},
|
||||
() => resolve()
|
||||
);
|
||||
});
|
||||
const ctSlugMatch = /ct\/([a-zA-Z0-9_.-]+)\.sh/.exec(updateOutput);
|
||||
if (ctSlugMatch?.[1]) {
|
||||
slugFromUpdate = ctSlugMatch[1].trim().toLowerCase();
|
||||
console.log('🔍 Slug from /usr/bin/update:', slugFromUpdate);
|
||||
}
|
||||
} catch {
|
||||
// Container may not be from community-scripts; use hostname fallback
|
||||
}
|
||||
|
||||
// Get the script's interface_port from metadata. Primary: slug from /usr/bin/update; fallback: hostname/suffix.
|
||||
let detectedPort = 80; // Default fallback
|
||||
|
||||
try {
|
||||
// Import localScriptsService to get script metadata
|
||||
const { localScriptsService } = await import('~/server/services/localScripts');
|
||||
|
||||
// Get all scripts and find the one matching our script name
|
||||
const allScripts = await localScriptsService.getAllScripts();
|
||||
|
||||
// Extract script slug from script_name (remove .sh extension)
|
||||
const scriptSlug = scriptData.script_name.replace(/\.sh$/, '');
|
||||
console.log('🔍 Looking for script with slug:', scriptSlug);
|
||||
|
||||
const scriptMetadata = allScripts.find(script => script.slug === scriptSlug);
|
||||
|
||||
|
||||
const nameFromHostname = scriptData.script_name.replace(/\.sh$/, '').toLowerCase();
|
||||
|
||||
// Primary: slug from /usr/bin/update (community-scripts)
|
||||
let scriptMetadata =
|
||||
slugFromUpdate != null
|
||||
? allScripts.find((s) => s.slug === slugFromUpdate)
|
||||
: undefined;
|
||||
if (scriptMetadata) {
|
||||
console.log('🔍 Using slug from /usr/bin/update for metadata:', scriptMetadata.slug);
|
||||
}
|
||||
|
||||
// Fallback: exact hostname then hostname ends with slug (longest wins)
|
||||
if (!scriptMetadata) {
|
||||
scriptMetadata = allScripts.find((script) => script.slug === nameFromHostname);
|
||||
if (!scriptMetadata) {
|
||||
const suffixMatches = allScripts.filter((script) => nameFromHostname.endsWith(script.slug));
|
||||
scriptMetadata =
|
||||
suffixMatches.length > 0
|
||||
? suffixMatches.reduce((a, b) => (a.slug.length >= b.slug.length ? a : b))
|
||||
: undefined;
|
||||
if (scriptMetadata) {
|
||||
console.log('🔍 Matched metadata by slug suffix in hostname:', scriptMetadata.slug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptMetadata?.interface_port) {
|
||||
detectedPort = scriptMetadata.interface_port;
|
||||
console.log('📋 Found interface_port in metadata:', detectedPort);
|
||||
} else {
|
||||
console.log('📋 No interface_port found in metadata, using default port 80');
|
||||
detectedPort = 80; // Default to port 80 if no metadata port found
|
||||
detectedPort = 80;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('⚠️ Error getting script metadata, using default port 80:', error);
|
||||
detectedPort = 80; // Default to port 80 if metadata lookup fails
|
||||
detectedPort = 80;
|
||||
}
|
||||
|
||||
console.log('🎯 Final detected port:', detectedPort);
|
||||
|
||||
Reference in New Issue
Block a user