Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions legacy/src/Command/Resources/ResourcesGetCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Platformsh\Cli\Service\PropertyFormatter;
use Platformsh\Cli\Service\Table;
use Platformsh\Client\Exception\EnvironmentStateException;
use Platformsh\Client\Model\Deployment\WebApp;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -30,13 +31,14 @@ class ResourcesGetCommand extends ResourcesCommandBase
'cpu' => 'CPU',
'memory' => 'Memory (MB)',
'disk' => 'Disk (MB)',
'object_storage' => 'Object storage (MB)',
'instance_count' => 'Instances',
'base_memory' => 'Base memory',
'memory_ratio' => 'Memory ratio',
];

/** @var string[] */
protected array $defaultColumns = ['service', 'profile_size', 'cpu_type', 'cpu', 'memory', 'disk', 'instance_count'];
protected array $defaultColumns = ['service', 'profile_size', 'cpu_type', 'cpu', 'memory', 'disk', 'object_storage', 'instance_count'];

public function __construct(private readonly Api $api, private readonly Config $config, private readonly PropertyFormatter $propertyFormatter, private readonly ResourcesUtil $resourcesUtil, private readonly Selector $selector, private readonly Table $table)
{
Expand Down Expand Up @@ -113,6 +115,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$cpuTypeOption = $input->getOption('cpu-type');
$autoscalingIndicator = '<comment>(A)</comment>';
$hasAutoscalingIndicator = false;
$hasObjectStorage = false;
foreach ($services as $name => $service) {
$properties = $service->getProperties();
if (!$this->table->formatIsMachineReadable() && !empty($autoscalingEnabled[$name])) {
Expand All @@ -127,6 +130,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
'base_memory' => $empty,
'memory_ratio' => $empty,
'disk' => $empty,
'object_storage' => $empty,
'instance_count' => $empty,
'cpu_type' => $empty,
'cpu' => $empty,
Expand Down Expand Up @@ -162,12 +166,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
}

// Object storage is only available on apps.
if (!$service instanceof WebApp) {
$row['object_storage'] = $notApplicable;
} elseif (isset($properties['resources']['disk']['object'])) {
$row['object_storage'] = (string) $properties['resources']['disk']['object'];
if ($properties['resources']['disk']['object'] > 0) {
$hasObjectStorage = true;
}
}

$row['instance_count'] = isset($properties['instance_count']) ? $this->propertyFormatter->format($properties['instance_count'], 'instance_count') : '1';

$rows[] = $row;
}

$this->table->render($rows, $this->tableHeader, $this->defaultColumns);
$defaultColumns = $this->defaultColumns;
if (!$hasObjectStorage) {
$defaultColumns = array_values(array_diff($defaultColumns, ['object_storage']));
}
$this->table->render($rows, $this->tableHeader, $defaultColumns);

if (!$this->table->formatIsMachineReadable()) {
Comment thread
pjcdawkins marked this conversation as resolved.
if ($hasAutoscalingIndicator) {
Expand Down
55 changes: 54 additions & 1 deletion legacy/src/Command/Resources/ResourcesSetCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ protected function configure(): void
. "\nItems are in the format <info>name:value</info> as above."
. "\nA value of 'default' will use the default size, and 'min' or 'minimum' will use the minimum.",
)
->addOption(
'object-storage',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Set the object storage size (in MB) of apps.'
. "\nItems are in the format <info>name:value</info> as above."
. "\nOnly applicable to apps; a value of 0 disables the bucket.",
)
->addOption('force', 'f', InputOption::VALUE_NONE, 'Try to run the update, even if it might exceed your limits')
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Show the changes that would be made, without changing anything');

Expand Down Expand Up @@ -88,6 +96,7 @@ protected function configure(): void
$this->addExample('Set profile sizes for two apps and a service', '--size frontend:0.1,backend:.25,database:1');
$this->addExample('Give the "backend" app 3 instances', '--count backend:3');
$this->addExample('Give 512 MB disk to the "backend" app and 2 GB to the "database" service', '--disk backend:512,database:2048');
$this->addExample('Give 524288 MB (512 GB) of object storage to the "backend" app', '--object-storage backend:524288');
$this->addExample('Set the same profile size for the "backend" and "frontend" apps using a wildcard', '--size ' . OsUtil::escapeShellArg('*end:0.1'));
$this->addExample('Set the same instance count for all apps using a wildcard', '--count ' . OsUtil::escapeShellArg('*:3'));
}
Expand Down Expand Up @@ -143,6 +152,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
// Validate the --disk option.
[$givenDiskSizes, $diskErrored] = $this->parseSetting($input, 'disk', $services, fn($v, $serviceName, $service) => $this->validateDiskSize($v, $serviceName, $service));
$errored = $errored || $diskErrored;

// Validate the --object-storage option.
[$givenObjectStorage, $objectStorageErrored] = $this->parseSetting($input, 'object-storage', $services, fn($v, $serviceName, $service) => $this->validateObjectStorage($v, $serviceName, $service));
$errored = $errored || $objectStorageErrored;
if ($errored) {
return 1;
}
Expand Down Expand Up @@ -171,7 +184,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$showCompleteForm = $input->isInteractive()
&& $input->getOption('size') === []
&& $input->getOption('count') === []
&& $input->getOption('disk') === [];
&& $input->getOption('disk') === []
&& $input->getOption('object-storage') === [];

$updates = [];
$current = [];
Expand Down Expand Up @@ -304,6 +318,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
}

// Set the object storage size (apps only).
if ($service instanceof WebApp && isset($givenObjectStorage[$name])) {
$currentObject = $properties['resources']['disk']['object'] ?? null;
if ($givenObjectStorage[$name] !== $currentObject) {
$updates[$group][$name]['resources']['disk']['object'] = $givenObjectStorage[$name];
}
}

if ($headerShown) {
$this->stdErr->writeln('');
}
Expand Down Expand Up @@ -455,6 +477,13 @@ private function summarizeChangesPerService(string $name, WebApp|Worker|Service
' MB',
));
}
if (isset($updates['resources']['disk']['object'])) {
$this->stdErr->writeln(' Object storage: ' . $this->resourcesUtil->formatChange(
$properties['resources']['disk']['object'] ?? null,
$updates['resources']['disk']['object'],
' MB',
));
}
}

/**
Expand Down Expand Up @@ -553,6 +582,30 @@ protected function validateDiskSize(string $value, string $serviceName, WebApp|W
return $size;
}

/**
* Validates a given object storage size in MB.
*
* @throws InvalidArgumentException
*/
protected function validateObjectStorage(string $value, string $serviceName, WebApp|Worker|Service $service): int
{
if (!$service instanceof WebApp) {
throw new InvalidArgumentException(sprintf(
'Object storage is only available on apps; <error>%s</error> is a %s.',
$serviceName,
$this->typeName($service),
));
}
$size = (int) $value;
if ($size != $value || $value < 0) {
throw new InvalidArgumentException(sprintf(
'Invalid object storage size <error>%s</error>: it must be a non-negative integer in MB.',
$value,
));
}
return $size;
}

/**
* Validates a given profile size.
*
Expand Down
Loading