mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-29 13:14:45 +02:00
Merge pull request #261 from pelican-dev/charles/docker-tags
Add docker container labels
This commit is contained in:
commit
54ae4b3dc1
@ -309,55 +309,6 @@ class CreateServer extends CreateRecord
|
|||||||
->inline()
|
->inline()
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
Forms\Components\Select::make('select_image')
|
|
||||||
->label('Docker Image Name')
|
|
||||||
->prefixIcon('tabler-brand-docker')
|
|
||||||
->live()
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
|
|
||||||
->options(function ($state, Forms\Get $get, Forms\Set $set) {
|
|
||||||
$egg = Egg::query()->find($get('egg_id'));
|
|
||||||
$images = $egg->docker_images ?? [];
|
|
||||||
|
|
||||||
$currentImage = $get('image');
|
|
||||||
if (!$currentImage && $images) {
|
|
||||||
$defaultImage = collect($images)->first();
|
|
||||||
$set('image', $defaultImage);
|
|
||||||
$set('select_image', $defaultImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_flip($images) + ['ghcr.io/custom-image' => 'Custom Image'];
|
|
||||||
})
|
|
||||||
->selectablePlaceholder(false)
|
|
||||||
->columnSpan([
|
|
||||||
'default' => 2,
|
|
||||||
'sm' => 2,
|
|
||||||
'md' => 2,
|
|
||||||
'lg' => 3,
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('image')
|
|
||||||
->label('Docker Image')
|
|
||||||
->prefixIcon('tabler-brand-docker')
|
|
||||||
->live()
|
|
||||||
->debounce(500)
|
|
||||||
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
|
|
||||||
$egg = Egg::query()->find($get('egg_id'));
|
|
||||||
$images = $egg->docker_images ?? [];
|
|
||||||
|
|
||||||
if (in_array($state, $images)) {
|
|
||||||
$set('select_image', $state);
|
|
||||||
} else {
|
|
||||||
$set('select_image', 'ghcr.io/custom-image');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
->placeholder('Enter a custom Image')
|
|
||||||
->columnSpan([
|
|
||||||
'default' => 2,
|
|
||||||
'sm' => 2,
|
|
||||||
'md' => 2,
|
|
||||||
'lg' => 3,
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Textarea::make('startup')
|
Forms\Components\Textarea::make('startup')
|
||||||
->hintIcon('tabler-code')
|
->hintIcon('tabler-code')
|
||||||
->label('Startup Command')
|
->label('Startup Command')
|
||||||
@ -452,7 +403,7 @@ class CreateServer extends CreateRecord
|
|||||||
->columnSpan(2),
|
->columnSpan(2),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Section::make('Resource Management')
|
Forms\Components\Section::make('Environment Management')
|
||||||
->collapsed()
|
->collapsed()
|
||||||
->icon('tabler-server-cog')
|
->icon('tabler-server-cog')
|
||||||
->iconColor('primary')
|
->iconColor('primary')
|
||||||
@ -464,175 +415,190 @@ class CreateServer extends CreateRecord
|
|||||||
])
|
])
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Grid::make()
|
Forms\Components\Fieldset::make('Resource Limits')
|
||||||
->columns(4)
|
->columnSpan([
|
||||||
->columnSpanFull()
|
'default' => 2,
|
||||||
|
'sm' => 4,
|
||||||
|
'md' => 4,
|
||||||
|
'lg' => 6,
|
||||||
|
])
|
||||||
|
->columns([
|
||||||
|
'default' => 1,
|
||||||
|
'sm' => 2,
|
||||||
|
'md' => 3,
|
||||||
|
'lg' => 3,
|
||||||
|
])
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\ToggleButtons::make('unlimited_mem')
|
Forms\Components\Grid::make()
|
||||||
->label('Memory')->inlineLabel()->inline()
|
->columns(4)
|
||||||
->default(true)
|
->columnSpanFull()
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
|
->schema([
|
||||||
->live()
|
Forms\Components\ToggleButtons::make('unlimited_mem')
|
||||||
->options([
|
->label('Memory')->inlineLabel()->inline()
|
||||||
true => 'Unlimited',
|
->default(true)
|
||||||
false => 'Limited',
|
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
|
||||||
])
|
->live()
|
||||||
->colors([
|
->options([
|
||||||
true => 'primary',
|
true => 'Unlimited',
|
||||||
false => 'warning',
|
false => 'Limited',
|
||||||
])
|
])
|
||||||
->columnSpan(2),
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('memory')
|
Forms\Components\TextInput::make('memory')
|
||||||
->dehydratedWhenHidden()
|
->dehydratedWhenHidden()
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
|
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
|
||||||
->label('Memory Limit')->inlineLabel()
|
->label('Memory Limit')->inlineLabel()
|
||||||
->suffix('MiB')
|
->suffix('MiB')
|
||||||
->default(0)
|
->default(0)
|
||||||
->required()
|
->required()
|
||||||
->columnSpan(2)
|
->columnSpan(2)
|
||||||
->numeric()
|
->numeric()
|
||||||
->minValue(0),
|
->minValue(0),
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('unlimited_disk')
|
|
||||||
->label('Disk Space')->inlineLabel()->inline()
|
|
||||||
->default(true)
|
|
||||||
->live()
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
|
|
||||||
->options([
|
|
||||||
true => 'Unlimited',
|
|
||||||
false => 'Limited',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
true => 'primary',
|
|
||||||
false => 'warning',
|
|
||||||
])
|
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('disk')
|
|
||||||
->dehydratedWhenHidden()
|
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
|
|
||||||
->label('Disk Space Limit')->inlineLabel()
|
|
||||||
->suffix('MiB')
|
|
||||||
->default(0)
|
|
||||||
->required()
|
|
||||||
->columnSpan(2)
|
|
||||||
->numeric()
|
|
||||||
->minValue(0),
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
|
||||||
->label('CPU')->inlineLabel()->inline()
|
|
||||||
->default(true)
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
|
||||||
->live()
|
|
||||||
->options([
|
|
||||||
true => 'Unlimited',
|
|
||||||
false => 'Limited',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
true => 'primary',
|
|
||||||
false => 'warning',
|
|
||||||
])
|
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('cpu')
|
|
||||||
->dehydratedWhenHidden()
|
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
|
||||||
->label('CPU Limit')->inlineLabel()
|
|
||||||
->suffix('%')
|
|
||||||
->default(0)
|
|
||||||
->required()
|
|
||||||
->columnSpan(2)
|
|
||||||
->numeric()
|
|
||||||
->minValue(0)
|
|
||||||
->helperText('100% equals one logical thread'),
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('swap_support')
|
|
||||||
->live()
|
|
||||||
->label('Enable Swap Memory')
|
|
||||||
->inlineLabel()
|
|
||||||
->inline()
|
|
||||||
->columnSpan(2)
|
|
||||||
->default('disabled')
|
|
||||||
->afterStateUpdated(function ($state, Forms\Set $set) {
|
|
||||||
$value = match ($state) {
|
|
||||||
'unlimited' => -1,
|
|
||||||
'disabled' => 0,
|
|
||||||
'limited' => 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
$set('swap', $value);
|
|
||||||
})
|
|
||||||
->options([
|
|
||||||
'unlimited' => 'Unlimited',
|
|
||||||
'limited' => 'Limited',
|
|
||||||
'disabled' => 'Disabled',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
'unlimited' => 'primary',
|
|
||||||
'limited' => 'warning',
|
|
||||||
'disabled' => 'danger',
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('swap')
|
Forms\Components\Grid::make()
|
||||||
->dehydratedWhenHidden()
|
->columns(4)
|
||||||
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
|
->columnSpanFull()
|
||||||
'disabled', 'unlimited' => true,
|
->schema([
|
||||||
'limited' => false,
|
Forms\Components\ToggleButtons::make('unlimited_disk')
|
||||||
})
|
->label('Disk Space')->inlineLabel()->inline()
|
||||||
->label('Swap Memory')
|
->default(true)
|
||||||
->default(0)
|
->live()
|
||||||
->suffix('MiB')
|
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
|
||||||
->minValue(-1)
|
->options([
|
||||||
->columnSpan(2)
|
true => 'Unlimited',
|
||||||
->inlineLabel()
|
false => 'Limited',
|
||||||
->required()
|
])
|
||||||
->integer(),
|
->colors([
|
||||||
]),
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
Forms\Components\Hidden::make('io')
|
Forms\Components\TextInput::make('disk')
|
||||||
->helperText('The IO performance relative to other running containers')
|
->dehydratedWhenHidden()
|
||||||
->label('Block IO Proportion')
|
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
|
||||||
->default(500),
|
->label('Disk Space Limit')->inlineLabel()
|
||||||
|
->suffix('MiB')
|
||||||
Forms\Components\Grid::make()
|
->default(0)
|
||||||
->columns(4)
|
->required()
|
||||||
->columnSpanFull()
|
->columnSpan(2)
|
||||||
->schema([
|
->numeric()
|
||||||
Forms\Components\ToggleButtons::make('oom_killer')
|
->minValue(0),
|
||||||
->label('OOM Killer')
|
|
||||||
->inlineLabel()->inline()
|
|
||||||
->default(false)
|
|
||||||
->columnSpan(2)
|
|
||||||
->options([
|
|
||||||
false => 'Disabled',
|
|
||||||
true => 'Enabled',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
false => 'success',
|
|
||||||
true => 'danger',
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('oom_disabled_hidden')
|
Forms\Components\Grid::make()
|
||||||
->hidden(),
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
||||||
|
->label('CPU')->inlineLabel()->inline()
|
||||||
|
->default(true)
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
||||||
|
->live()
|
||||||
|
->options([
|
||||||
|
true => 'Unlimited',
|
||||||
|
false => 'Limited',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('cpu')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('CPU Limit')->inlineLabel()
|
||||||
|
->suffix('%')
|
||||||
|
->default(0)
|
||||||
|
->required()
|
||||||
|
->columnSpan(2)
|
||||||
|
->numeric()
|
||||||
|
->minValue(0)
|
||||||
|
->helperText('100% equals one CPU core.'),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('swap_support')
|
||||||
|
->live()
|
||||||
|
->label('Enable Swap Memory')
|
||||||
|
->inlineLabel()
|
||||||
|
->inline()
|
||||||
|
->columnSpan(2)
|
||||||
|
->default('disabled')
|
||||||
|
->afterStateUpdated(function ($state, Forms\Set $set) {
|
||||||
|
$value = match ($state) {
|
||||||
|
'unlimited' => -1,
|
||||||
|
'disabled' => 0,
|
||||||
|
'limited' => 128,
|
||||||
|
};
|
||||||
|
|
||||||
|
$set('swap', $value);
|
||||||
|
})
|
||||||
|
->options([
|
||||||
|
'unlimited' => 'Unlimited',
|
||||||
|
'limited' => 'Limited',
|
||||||
|
'disabled' => 'Disabled',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
'unlimited' => 'primary',
|
||||||
|
'limited' => 'warning',
|
||||||
|
'disabled' => 'danger',
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('swap')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
|
||||||
|
'disabled', 'unlimited' => true,
|
||||||
|
'limited' => false,
|
||||||
|
})
|
||||||
|
->label('Swap Memory')
|
||||||
|
->default(0)
|
||||||
|
->suffix('MiB')
|
||||||
|
->minValue(-1)
|
||||||
|
->columnSpan(2)
|
||||||
|
->inlineLabel()
|
||||||
|
->required()
|
||||||
|
->integer(),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\Hidden::make('io')
|
||||||
|
->helperText('The IO performance relative to other running containers')
|
||||||
|
->label('Block IO Proportion')
|
||||||
|
->default(500),
|
||||||
|
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('oom_killer')
|
||||||
|
->label('OOM Killer')
|
||||||
|
->inlineLabel()->inline()
|
||||||
|
->default(false)
|
||||||
|
->columnSpan(2)
|
||||||
|
->options([
|
||||||
|
false => 'Disabled',
|
||||||
|
true => 'Enabled',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
false => 'success',
|
||||||
|
true => 'danger',
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('oom_disabled_hidden')
|
||||||
|
->hidden(),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Fieldset::make('Application Feature Limits')
|
Forms\Components\Fieldset::make('Feature Limits')
|
||||||
->inlineLabel()
|
->inlineLabel()
|
||||||
->columnSpan([
|
->columnSpan([
|
||||||
'default' => 2,
|
'default' => 2,
|
||||||
@ -663,6 +629,60 @@ class CreateServer extends CreateRecord
|
|||||||
->numeric()
|
->numeric()
|
||||||
->default(0),
|
->default(0),
|
||||||
]),
|
]),
|
||||||
|
Forms\Components\Fieldset::make('Docker Settings')
|
||||||
|
->columnSpan([
|
||||||
|
'default' => 2,
|
||||||
|
'sm' => 4,
|
||||||
|
'md' => 4,
|
||||||
|
'lg' => 6,
|
||||||
|
])
|
||||||
|
->columns([
|
||||||
|
'default' => 1,
|
||||||
|
'sm' => 2,
|
||||||
|
'md' => 3,
|
||||||
|
'lg' => 3,
|
||||||
|
])
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Select::make('select_image')
|
||||||
|
->label('Image Name')
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
|
||||||
|
->options(function ($state, Forms\Get $get, Forms\Set $set) {
|
||||||
|
$egg = Egg::query()->find($get('egg_id'));
|
||||||
|
$images = $egg->docker_images ?? [];
|
||||||
|
|
||||||
|
$currentImage = $get('image');
|
||||||
|
if (!$currentImage && $images) {
|
||||||
|
$defaultImage = collect($images)->first();
|
||||||
|
$set('image', $defaultImage);
|
||||||
|
$set('select_image', $defaultImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_flip($images) + ['ghcr.io/custom-image' => 'Custom Image'];
|
||||||
|
})
|
||||||
|
->selectablePlaceholder(false)
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('image')
|
||||||
|
->label('Image')
|
||||||
|
->debounce(500)
|
||||||
|
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
|
||||||
|
$egg = Egg::query()->find($get('egg_id'));
|
||||||
|
$images = $egg->docker_images ?? [];
|
||||||
|
|
||||||
|
if (in_array($state, $images)) {
|
||||||
|
$set('select_image', $state);
|
||||||
|
} else {
|
||||||
|
$set('select_image', 'ghcr.io/custom-image');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->placeholder('Enter a custom Image')
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
Forms\Components\TagsInput::make('docker_labels')
|
||||||
|
->label('Labels')
|
||||||
|
->placeholder('Enter custom Docker container labels')
|
||||||
|
->columnSpan(1),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -157,49 +157,6 @@ class EditServer extends EditRecord
|
|||||||
])
|
])
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
Forms\Components\Select::make('select_image')
|
|
||||||
->label('Docker Image Name')
|
|
||||||
->prefixIcon('tabler-brand-docker')
|
|
||||||
->live()
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
|
|
||||||
->formatStateUsing(fn (Forms\Get $get) => $get('image'))
|
|
||||||
->options(function ($state, Forms\Get $get) {
|
|
||||||
$egg = Egg::query()->find($get('egg_id'));
|
|
||||||
$images = $egg->docker_images ?? [];
|
|
||||||
|
|
||||||
return ['ghcr.io/custom-image' => 'Custom Image'] + array_flip($images);
|
|
||||||
})
|
|
||||||
->selectablePlaceholder(false)
|
|
||||||
->columnSpan([
|
|
||||||
'default' => 2,
|
|
||||||
'sm' => 2,
|
|
||||||
'md' => 2,
|
|
||||||
'lg' => 3,
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('image')
|
|
||||||
->label('Docker Image')
|
|
||||||
->prefixIcon('tabler-brand-docker')
|
|
||||||
->live()
|
|
||||||
->debounce(500)
|
|
||||||
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
|
|
||||||
$egg = Egg::query()->find($get('egg_id'));
|
|
||||||
$images = $egg->docker_images ?? [];
|
|
||||||
|
|
||||||
if (in_array($state, $images)) {
|
|
||||||
$set('select_image', $state);
|
|
||||||
} else {
|
|
||||||
$set('select_image', 'ghcr.io/custom-image');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
->placeholder('Enter a custom Image')
|
|
||||||
->columnSpan([
|
|
||||||
'default' => 2,
|
|
||||||
'sm' => 2,
|
|
||||||
'md' => 2,
|
|
||||||
'lg' => 3,
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Textarea::make('startup')
|
Forms\Components\Textarea::make('startup')
|
||||||
->hintIcon('tabler-code')
|
->hintIcon('tabler-code')
|
||||||
->label('Startup Command')
|
->label('Startup Command')
|
||||||
@ -287,7 +244,7 @@ class EditServer extends EditRecord
|
|||||||
->columnSpan(2),
|
->columnSpan(2),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Section::make('Resource Management')
|
Forms\Components\Section::make('Environment Management')
|
||||||
->collapsed()
|
->collapsed()
|
||||||
->icon('tabler-server-cog')
|
->icon('tabler-server-cog')
|
||||||
->iconColor('primary')
|
->iconColor('primary')
|
||||||
@ -299,170 +256,185 @@ class EditServer extends EditRecord
|
|||||||
])
|
])
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Grid::make()
|
Forms\Components\Fieldset::make('Resource Limits')
|
||||||
->columns(4)
|
->columnSpan([
|
||||||
->columnSpanFull()
|
'default' => 2,
|
||||||
|
'sm' => 4,
|
||||||
|
'md' => 4,
|
||||||
|
'lg' => 6,
|
||||||
|
])
|
||||||
|
->columns([
|
||||||
|
'default' => 1,
|
||||||
|
'sm' => 2,
|
||||||
|
'md' => 3,
|
||||||
|
'lg' => 3,
|
||||||
|
])
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\ToggleButtons::make('unlimited_mem')
|
Forms\Components\Grid::make()
|
||||||
->label('Memory')->inlineLabel()->inline()
|
->columns(4)
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
|
->columnSpanFull()
|
||||||
->formatStateUsing(fn (Forms\Get $get) => $get('memory') == 0)
|
->schema([
|
||||||
->live()
|
Forms\Components\ToggleButtons::make('unlimited_mem')
|
||||||
->options([
|
->label('Memory')->inlineLabel()->inline()
|
||||||
true => 'Unlimited',
|
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
|
||||||
false => 'Limited',
|
->formatStateUsing(fn (Forms\Get $get) => $get('memory') == 0)
|
||||||
])
|
->live()
|
||||||
->colors([
|
->options([
|
||||||
true => 'primary',
|
true => 'Unlimited',
|
||||||
false => 'warning',
|
false => 'Limited',
|
||||||
])
|
])
|
||||||
->columnSpan(2),
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('memory')
|
Forms\Components\TextInput::make('memory')
|
||||||
->dehydratedWhenHidden()
|
->dehydratedWhenHidden()
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
|
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
|
||||||
->label('Memory Limit')->inlineLabel()
|
->label('Memory Limit')->inlineLabel()
|
||||||
->suffix('MiB')
|
->suffix('MiB')
|
||||||
->required()
|
->required()
|
||||||
->columnSpan(2)
|
->columnSpan(2)
|
||||||
->numeric()
|
->numeric()
|
||||||
->minValue(0),
|
->minValue(0),
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('unlimited_disk')
|
|
||||||
->label('Disk Space')->inlineLabel()->inline()
|
|
||||||
->live()
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
|
|
||||||
->formatStateUsing(fn (Forms\Get $get) => $get('disk') == 0)
|
|
||||||
->options([
|
|
||||||
true => 'Unlimited',
|
|
||||||
false => 'Limited',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
true => 'primary',
|
|
||||||
false => 'warning',
|
|
||||||
])
|
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('disk')
|
|
||||||
->dehydratedWhenHidden()
|
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
|
|
||||||
->label('Disk Space Limit')->inlineLabel()
|
|
||||||
->suffix('MiB')
|
|
||||||
->required()
|
|
||||||
->columnSpan(2)
|
|
||||||
->numeric()
|
|
||||||
->minValue(0),
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
|
||||||
->label('CPU')->inlineLabel()->inline()
|
|
||||||
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
|
||||||
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
|
|
||||||
->live()
|
|
||||||
->options([
|
|
||||||
true => 'Unlimited',
|
|
||||||
false => 'Limited',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
true => 'primary',
|
|
||||||
false => 'warning',
|
|
||||||
])
|
|
||||||
->columnSpan(2),
|
|
||||||
|
|
||||||
Forms\Components\TextInput::make('cpu')
|
|
||||||
->dehydratedWhenHidden()
|
|
||||||
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
|
||||||
->label('CPU Limit')->inlineLabel()
|
|
||||||
->suffix('%')
|
|
||||||
->required()
|
|
||||||
->columnSpan(2)
|
|
||||||
->numeric()
|
|
||||||
->minValue(0),
|
|
||||||
]),
|
|
||||||
|
|
||||||
Forms\Components\Grid::make()
|
|
||||||
->columns(4)
|
|
||||||
->columnSpanFull()
|
|
||||||
->schema([
|
|
||||||
Forms\Components\ToggleButtons::make('swap_support')
|
|
||||||
->live()
|
|
||||||
->label('Enable Swap Memory')->inlineLabel()->inline()
|
|
||||||
->columnSpan(2)
|
|
||||||
->afterStateUpdated(function ($state, Forms\Set $set) {
|
|
||||||
$value = match ($state) {
|
|
||||||
'unlimited' => -1,
|
|
||||||
'disabled' => 0,
|
|
||||||
'limited' => 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
$set('swap', $value);
|
|
||||||
})
|
|
||||||
->formatStateUsing(function (Forms\Get $get) {
|
|
||||||
return match (true) {
|
|
||||||
$get('swap') > 0 => 'limited',
|
|
||||||
$get('swap') == 0 => 'disabled',
|
|
||||||
$get('swap') < 0 => 'unlimited',
|
|
||||||
};
|
|
||||||
})
|
|
||||||
->options([
|
|
||||||
'unlimited' => 'Unlimited',
|
|
||||||
'limited' => 'Limited',
|
|
||||||
'disabled' => 'Disabled',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
'unlimited' => 'primary',
|
|
||||||
'limited' => 'warning',
|
|
||||||
'disabled' => 'danger',
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('swap')
|
Forms\Components\Grid::make()
|
||||||
->dehydratedWhenHidden()
|
->columns(4)
|
||||||
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
|
->columnSpanFull()
|
||||||
'disabled', 'unlimited', true => true,
|
->schema([
|
||||||
'limited', false => false,
|
Forms\Components\ToggleButtons::make('unlimited_disk')
|
||||||
})
|
->label('Disk Space')->inlineLabel()->inline()
|
||||||
->label('Swap Memory')->inlineLabel()
|
->live()
|
||||||
->suffix('MiB')
|
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
|
||||||
->minValue(-1)
|
->formatStateUsing(fn (Forms\Get $get) => $get('disk') == 0)
|
||||||
->columnSpan(2)
|
->options([
|
||||||
->required()
|
true => 'Unlimited',
|
||||||
->integer(),
|
false => 'Limited',
|
||||||
]),
|
])
|
||||||
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
Forms\Components\Hidden::make('io')
|
Forms\Components\TextInput::make('disk')
|
||||||
->helperText('The IO performance relative to other running containers')
|
->dehydratedWhenHidden()
|
||||||
->label('Block IO Proportion'),
|
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
|
||||||
|
->label('Disk Space Limit')->inlineLabel()
|
||||||
Forms\Components\Grid::make()
|
->suffix('MiB')
|
||||||
->columns(4)
|
->required()
|
||||||
->columnSpanFull()
|
->columnSpan(2)
|
||||||
->schema([
|
->numeric()
|
||||||
Forms\Components\ToggleButtons::make('oom_killer')
|
->minValue(0),
|
||||||
->label('OOM Killer')->inlineLabel()->inline()
|
|
||||||
->columnSpan(2)
|
|
||||||
->options([
|
|
||||||
false => 'Disabled',
|
|
||||||
true => 'Enabled',
|
|
||||||
])
|
|
||||||
->colors([
|
|
||||||
false => 'success',
|
|
||||||
true => 'danger',
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('oom_disabled_hidden')
|
Forms\Components\Grid::make()
|
||||||
->hidden(),
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
||||||
|
->label('CPU')->inlineLabel()->inline()
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
||||||
|
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
|
||||||
|
->live()
|
||||||
|
->options([
|
||||||
|
true => 'Unlimited',
|
||||||
|
false => 'Limited',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('cpu')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('CPU Limit')->inlineLabel()
|
||||||
|
->suffix('%')
|
||||||
|
->required()
|
||||||
|
->columnSpan(2)
|
||||||
|
->numeric()
|
||||||
|
->minValue(0),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('swap_support')
|
||||||
|
->live()
|
||||||
|
->label('Enable Swap Memory')->inlineLabel()->inline()
|
||||||
|
->columnSpan(2)
|
||||||
|
->afterStateUpdated(function ($state, Forms\Set $set) {
|
||||||
|
$value = match ($state) {
|
||||||
|
'unlimited' => -1,
|
||||||
|
'disabled' => 0,
|
||||||
|
'limited' => 128,
|
||||||
|
};
|
||||||
|
|
||||||
|
$set('swap', $value);
|
||||||
|
})
|
||||||
|
->formatStateUsing(function (Forms\Get $get) {
|
||||||
|
return match (true) {
|
||||||
|
$get('swap') > 0 => 'limited',
|
||||||
|
$get('swap') == 0 => 'disabled',
|
||||||
|
$get('swap') < 0 => 'unlimited',
|
||||||
|
};
|
||||||
|
})
|
||||||
|
->options([
|
||||||
|
'unlimited' => 'Unlimited',
|
||||||
|
'limited' => 'Limited',
|
||||||
|
'disabled' => 'Disabled',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
'unlimited' => 'primary',
|
||||||
|
'limited' => 'warning',
|
||||||
|
'disabled' => 'danger',
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('swap')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
|
||||||
|
'disabled', 'unlimited', true => true,
|
||||||
|
'limited', false => false,
|
||||||
|
})
|
||||||
|
->label('Swap Memory')->inlineLabel()
|
||||||
|
->suffix('MiB')
|
||||||
|
->minValue(-1)
|
||||||
|
->columnSpan(2)
|
||||||
|
->required()
|
||||||
|
->integer(),
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\Hidden::make('io')
|
||||||
|
->helperText('The IO performance relative to other running containers')
|
||||||
|
->label('Block IO Proportion'),
|
||||||
|
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(4)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('oom_killer')
|
||||||
|
->label('OOM Killer')->inlineLabel()->inline()
|
||||||
|
->columnSpan(2)
|
||||||
|
->options([
|
||||||
|
false => 'Disabled',
|
||||||
|
true => 'Enabled',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
false => 'success',
|
||||||
|
true => 'danger',
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('oom_disabled_hidden')
|
||||||
|
->hidden(),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Fieldset::make('Application Feature Limits')
|
Forms\Components\Fieldset::make('Feature Limits')
|
||||||
->inlineLabel()
|
->inlineLabel()
|
||||||
->columnSpan([
|
->columnSpan([
|
||||||
'default' => 2,
|
'default' => 2,
|
||||||
@ -490,6 +462,60 @@ class EditServer extends EditRecord
|
|||||||
->required()
|
->required()
|
||||||
->numeric(),
|
->numeric(),
|
||||||
]),
|
]),
|
||||||
|
Forms\Components\Fieldset::make('Docker Settings')
|
||||||
|
->columnSpan([
|
||||||
|
'default' => 2,
|
||||||
|
'sm' => 4,
|
||||||
|
'md' => 4,
|
||||||
|
'lg' => 6,
|
||||||
|
])
|
||||||
|
->columns([
|
||||||
|
'default' => 1,
|
||||||
|
'sm' => 2,
|
||||||
|
'md' => 3,
|
||||||
|
'lg' => 3,
|
||||||
|
])
|
||||||
|
->schema([
|
||||||
|
Forms\Components\Select::make('select_image')
|
||||||
|
->label('Image Name')
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
|
||||||
|
->options(function ($state, Forms\Get $get, Forms\Set $set) {
|
||||||
|
$egg = Egg::query()->find($get('egg_id'));
|
||||||
|
$images = $egg->docker_images ?? [];
|
||||||
|
|
||||||
|
$currentImage = $get('image');
|
||||||
|
if (!$currentImage && $images) {
|
||||||
|
$defaultImage = collect($images)->first();
|
||||||
|
$set('image', $defaultImage);
|
||||||
|
$set('select_image', $defaultImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_flip($images) + ['ghcr.io/custom-image' => 'Custom Image'];
|
||||||
|
})
|
||||||
|
->selectablePlaceholder(false)
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('image')
|
||||||
|
->label('Image')
|
||||||
|
->debounce(500)
|
||||||
|
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
|
||||||
|
$egg = Egg::query()->find($get('egg_id'));
|
||||||
|
$images = $egg->docker_images ?? [];
|
||||||
|
|
||||||
|
if (in_array($state, $images)) {
|
||||||
|
$set('select_image', $state);
|
||||||
|
} else {
|
||||||
|
$set('select_image', 'ghcr.io/custom-image');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->placeholder('Enter a custom Image')
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
Forms\Components\TagsInput::make('docker_labels')
|
||||||
|
->label('Labels')
|
||||||
|
->placeholder('Enter custom Docker container labels')
|
||||||
|
->columnSpan(1),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ class Server extends Model
|
|||||||
self::UPDATED_AT => 'datetime',
|
self::UPDATED_AT => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'installed_at' => 'datetime',
|
'installed_at' => 'datetime',
|
||||||
|
'docker_labels' => 'array',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class EggConfigurationService
|
|||||||
{
|
{
|
||||||
// Get the legacy configuration structure for the server so that we
|
// Get the legacy configuration structure for the server so that we
|
||||||
// can property map the egg placeholders to values.
|
// can property map the egg placeholders to values.
|
||||||
$structure = $this->configurationStructureService->handle($server, [], true);
|
$structure = $this->configurationStructureService->handle($server);
|
||||||
|
|
||||||
$response = [];
|
$response = [];
|
||||||
// Normalize the output of the configuration for the new Daemon to more
|
// Normalize the output of the configuration for the new Daemon to more
|
||||||
|
@ -20,7 +20,7 @@ class ServerConfigurationStructureService
|
|||||||
* DO NOT MODIFY THIS FUNCTION. This powers legacy code handling for the new daemon
|
* DO NOT MODIFY THIS FUNCTION. This powers legacy code handling for the new daemon
|
||||||
* daemon, if you modify the structure eggs will break unexpectedly.
|
* daemon, if you modify the structure eggs will break unexpectedly.
|
||||||
*/
|
*/
|
||||||
public function handle(Server $server, array $override = [], bool $legacy = false): array
|
public function handle(Server $server, array $override = []): array
|
||||||
{
|
{
|
||||||
$clone = $server;
|
$clone = $server;
|
||||||
// If any overrides have been set on this call make sure to update them on the
|
// If any overrides have been set on this call make sure to update them on the
|
||||||
@ -32,15 +32,13 @@ class ServerConfigurationStructureService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $legacy
|
return $this->returnFormat($clone);
|
||||||
? $this->returnLegacyFormat($clone)
|
|
||||||
: $this->returnCurrentFormat($clone);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the new data format used for the daemon.
|
* Returns the data format used for the daemon.
|
||||||
*/
|
*/
|
||||||
protected function returnCurrentFormat(Server $server): array
|
protected function returnFormat(Server $server): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
@ -59,13 +57,12 @@ class ServerConfigurationStructureService
|
|||||||
'cpu_limit' => $server->cpu,
|
'cpu_limit' => $server->cpu,
|
||||||
'threads' => $server->threads,
|
'threads' => $server->threads,
|
||||||
'disk_space' => $server->disk,
|
'disk_space' => $server->disk,
|
||||||
// This field is deprecated — use "oom_killer".
|
|
||||||
'oom_disabled' => !$server->oom_killer,
|
|
||||||
'oom_killer' => $server->oom_killer,
|
'oom_killer' => $server->oom_killer,
|
||||||
],
|
],
|
||||||
'container' => [
|
'container' => [
|
||||||
'image' => $server->image,
|
'image' => $server->image,
|
||||||
'requires_rebuild' => false,
|
'requires_rebuild' => false,
|
||||||
|
'labels' => $server->docker_labels,
|
||||||
],
|
],
|
||||||
'allocations' => [
|
'allocations' => [
|
||||||
'force_outgoing_ip' => $server->egg->force_outgoing_ip,
|
'force_outgoing_ip' => $server->egg->force_outgoing_ip,
|
||||||
@ -88,41 +85,4 @@ class ServerConfigurationStructureService
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the legacy server data format to continue support for old egg configurations
|
|
||||||
* that have not yet been updated.
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
protected function returnLegacyFormat(Server $server): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'uuid' => $server->uuid,
|
|
||||||
'build' => [
|
|
||||||
'default' => [
|
|
||||||
'ip' => $server->allocation->ip,
|
|
||||||
'port' => $server->allocation->port,
|
|
||||||
],
|
|
||||||
'ports' => $server->allocations->groupBy('ip')->map(function ($item) {
|
|
||||||
return $item->pluck('port');
|
|
||||||
})->toArray(),
|
|
||||||
'env' => $this->environment->handle($server),
|
|
||||||
'oom_disabled' => !$server->oom_killer,
|
|
||||||
'memory' => (int) $server->memory,
|
|
||||||
'swap' => (int) $server->swap,
|
|
||||||
'io' => (int) $server->io,
|
|
||||||
'cpu' => (int) $server->cpu,
|
|
||||||
'threads' => $server->threads,
|
|
||||||
'disk' => (int) $server->disk,
|
|
||||||
'image' => $server->image,
|
|
||||||
],
|
|
||||||
'service' => [
|
|
||||||
'egg' => $server->egg->uuid,
|
|
||||||
'skip_scripts' => $server->skip_scripts,
|
|
||||||
],
|
|
||||||
'rebuild' => false,
|
|
||||||
'suspended' => $server->isSuspended() ? 1 : 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->text('docker_labels')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('docker_labels');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user