// Module included in the following assemblies:
//
// * virt/managing_vms/virt-customize-web-console.adoc

:_mod-docs-content-type: PROCEDURE
[id="virt-enable-bulk-operations-web-console_{context}"]
= Enable bulk operations for virtual machines

[role="_abstract"]
You can enable virtual machine (VM) owners to perform large-scale management tasks, such as backups and storage migrations, across many virtual machines simultaneously, by creating a dynamic plugin that enables bulk actions in the web console.

This integration reduces manual tasks for multi-VM environments and ensures that custom actions are available as native, selectable bulk actions from within the *Virtualization* page.

.Prerequisites

* You have created a dynamic plugin.
* You have cluster administrator permissions.
* You have access to an {product-title} cluster where {VirtProductName} is installed.

.Procedure

. In the configuration file of your plugin, add a `console.action/provider` extension.
+
To enable bulk actions, you must use a `contextId` field that targets an array of `VirtualMachine` resources.
+
Example `console-extensions.json` file excerpt:
+
[source,json]
----
{
   type: 'console.action/provider',
   properties: {
     contextId: 'kubevirt.io~v1~VirtualMachine[]',
     provider: {
       $codeRef: 'useSimpleBulkActions',
     },
   },
 }
----
** `properties.contextId` specifies a string for which the `KubeVirt` plugin declares support.
** `properties.provider` specifies the React hook or function in your source code that generates the action items.

. In the source file referenced by the extension, implement a hook that handles the array of selected resources.
+
Example plugin:
+
[source,ts]
----
import {
  type ExtensionHook,
  AccessReviewResourceAttributes,
  Action,
} from '@openshift-console/dynamic-plugin-sdk';
import { V1VirtualMachine } from '@kubevirt-ui-ext/kubevirt-api/kubevirt';
import { VirtualMachineModel } from '@kubevirt-ui-ext/kubevirt-api/console';
import { useMemo } from 'react';

const useSimpleBulkActions: ExtensionHook<Action[], (V1VirtualMachine & { cluster?: string })[]> = (
  vms,
) => {
  const areAllRunning = vms.every((vm) => vm.status?.printableStatus === 'Running');
  const isCrossCluster = new Set(vms.map((vm) => vm.cluster)).size > 1;
  const firstVm = vms[0];

  const accessReview: AccessReviewResourceAttributes = useMemo(
    () => ({
      cluster: firstVm?.cluster,
      group: VirtualMachineModel.apiGroup,
      name: firstVm?.metadata?.name,
      namespace: firstVm?.metadata?.namespace,
      resource: VirtualMachineModel.plural,
      verb: 'delete',
    }),
    [firstVm?.cluster, firstVm?.metadata?.name, firstVm?.metadata?.namespace],
  );

  const checkAllRunningAction: Action = useMemo(
    () => ({
      id: 'check-all-running',
      cta: () => console.log('All selected VMs are running?', areAllRunning),
      label: 'Check VMs are running',
      disabled: isCrossCluster,
      disabledTooltip: isCrossCluster ? 'VMs from different clusters detected' : '',
      accessReview,
    }),
    [areAllRunning, isCrossCluster, accessReview],
  );

  const actions = useMemo(() => [checkAllRunningAction], [checkAllRunningAction]);
  return [actions, true, null];
};

export default useSimpleBulkActions;
----
+
The plugin shown in the previous example checks if all selected VMs are running and prints a log message to the console.

. Deploy the plugin to the cluster.

.Verification

. Log in to the {product-title} web console.

. Verify that you can apply bulk actions to VMs.
.. Go to *Virtualization* -> *VirtualMachines*.
.. Select the checkboxes for two or more existing VMs.
.. Click the *Actions* drop-down menu. Confirm that you can run the custom action you created.
