Attach an existing disk to an existing instance.

    CLI Example:

    .. code-block:: bash

        salt-cloud -a attach_disk myinstance disk_name=mydisk mode=READ_WRITE
507060
def attach_disk(name=None, kwargs=None, call=None):
    '''
    
    '''
    if call != 'action':
        raise SaltCloudSystemExit(
            'The attach_disk action must be called with -a or --action.'
        )

    if not name:
        log.error(
            'Must specify an instance name.'
        )
        return False
    if not kwargs or 'disk_name' not in kwargs:
        log.error(
            'Must specify a disk_name to attach.'
        )
        return False

    node_name = name
    disk_name = kwargs['disk_name']
    mode = kwargs.get('mode', 'READ_WRITE').upper()
    boot = kwargs.get('boot', False)
    auto_delete = kwargs.get('auto_delete', False)
    if boot and boot.lower() in ['true', 'yes', 'enabled']:
        boot = True
    else:
        boot = False

    if mode not in ['READ_WRITE', 'READ_ONLY']:
        log.error(
            'Mode must be either READ_ONLY or (default) READ_WRITE.'
        )
        return False

    conn = get_conn()
    node = conn.ex_get_node(node_name)
    disk = conn.ex_get_volume(disk_name)

    __utils__['cloud.fire_event'](
        'event',
        'attach disk',
        'salt/cloud/disk/attaching',
        args={
            'name': node_name,
            'disk_name': disk_name,
            'mode': mode,
            'boot': boot,
        },
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )

    result = conn.attach_volume(node, disk, ex_mode=mode, ex_boot=boot,
                                ex_auto_delete=auto_delete)

    __utils__['cloud.fire_event'](
        'event',
        'attached disk',
        'salt/cloud/disk/attached',
        args={
            'name': node_name,
            'disk_name': disk_name,
            'mode': mode,
            'boot': boot,
        },
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )
    return result
1219739
def create(name, allocated_storage, db_instance_class, engine,
           master_username, master_user_password, db_name=None,
           db_security_groups=None, vpc_security_group_ids=None,
           vpc_security_groups=None, availability_zone=None,
           db_subnet_group_name=None, preferred_maintenance_window=None,
           db_parameter_group_name=None, backup_retention_period=None,
           preferred_backup_window=None, port=None, multi_az=None,
           engine_version=None, auto_minor_version_upgrade=None,
           license_model=None, iops=None, option_group_name=None,
           character_set_name=None, publicly_accessible=None, wait_status=None,
           tags=None, db_cluster_identifier=None, storage_type=None,
           tde_credential_arn=None, tde_credential_password=None,
           storage_encrypted=None, kms_key_id=None, domain=None,
           copy_tags_to_snapshot=None, monitoring_interval=None,
           monitoring_role_arn=None, domain_iam_role_name=None, region=None,
           promotion_tier=None, key=None, keyid=None, profile=None):
    '''
    
    '''
    if not allocated_storage:
        raise SaltInvocationError('allocated_storage is required')
    if not db_instance_class:
        raise SaltInvocationError('db_instance_class is required')
    if not engine:
        raise SaltInvocationError('engine is required')
    if not master_username:
        raise SaltInvocationError('master_username is required')
    if not master_user_password:
        raise SaltInvocationError('master_user_password is required')
    if availability_zone and multi_az:
        raise SaltInvocationError('availability_zone and multi_az are mutually'
                                  ' exclusive arguments.')
    if wait_status:
        wait_stati = ['available', 'modifying', 'backing-up']
        if wait_status not in wait_stati:
            raise SaltInvocationError(
                'wait_status can be one of: {0}'.format(wait_stati))
    if vpc_security_groups:
        v_tmp = __salt__['boto_secgroup.convert_to_group_ids'](
                groups=vpc_security_groups, region=region, key=key, keyid=keyid,
                profile=profile)
        vpc_security_group_ids = (vpc_security_group_ids + v_tmp
                                  if vpc_security_group_ids else v_tmp)

    try:
        conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
        if not conn:
            return {'results': bool(conn)}

        kwargs = {}
        boto_params = set(boto3_param_map.keys())
        keys = set(locals().keys())
        tags = _tag_doc(tags)

        for param_key in keys.intersection(boto_params):
            val = locals()[param_key]
            if val is not None:
                mapped = boto3_param_map[param_key]
                kwargs[mapped[0]] = mapped[1](val)

        # Validation doesn't want parameters that are None
        # https://github.com/boto/boto3/issues/400
        kwargs = dict((k, v) for k, v in six.iteritems(kwargs) if v is not None)

        rds = conn.create_db_instance(**kwargs)

        if not rds:
            return {'created': False}
        if not wait_status:
            return {'created': True, 'message':
                    'RDS instance {0} created.'.format(name)}

        while True:
            jmespath = 'DBInstances[*].DBInstanceStatus'
            status = describe_db_instances(name=name, jmespath=jmespath,
                                           region=region, key=key, keyid=keyid,
                                           profile=profile)
            if status:
                stat = status[0]
            else:
                # Whoops, something is horribly wrong...
                return {'created': False,
                        'error': "RDS instance {0} should have been created but"
                                 " now I can't find it.".format(name)}
            if stat == wait_status:
                return {'created': True,
                        'message': 'RDS instance {0} created (current status '
                        '{1})'.format(name, stat)}
            time.sleep(10)
            log.info('Instance status after 10 seconds is: %s', stat)

    except ClientError as e:
        return {'error': __utils__['boto3.get_error'](e)}
788129
def _storage_attach(self, params):
        

        args = shlex.split(params)
        yield from self.manager.execute("storageattach", [self._vmname] + args)
96998
def mount(device, mountpoint, options=None, persist=False, filesystem="ext3"):
    """"""
    cmd_args = ['mount']
    if options is not None:
        cmd_args.extend(['-o', options])
    cmd_args.extend([device, mountpoint])
    try:
        subprocess.check_output(cmd_args)
    except subprocess.CalledProcessError as e:
        log('Error mounting {} at {}\n{}'.format(device, mountpoint, e.output))
        return False

    if persist:
        return fstab_add(device, mountpoint, filesystem, options=options)
    return True
222527
def sync_persistent_disk(instance_plan)
      instance = instance_plan.instance
      return if instance.model.persistent_disks.empty?

      agent_disk_cid = agent_mounted_disks(instance.model).first

      if agent_disk_cid.nil? && !instance_plan.needs_disk?
        @logger.debug('Disk is already detached')
      elsif agent_disk_cid != instance.model.managed_persistent_disk_cid
        handle_disk_mismatch(agent_disk_cid, instance, instance_plan)
      end

      instance.model.persistent_disks.each do |disk|
        unless disk.active
          @logger.warn("'#{instance}' has inactive disk #{disk.disk_cid}")
        end
      end
    end
97573
def update_disk(kwargs=None, conn=None, call=None):
    '''
    
    '''
    if call != 'function':
        raise SaltCloudSystemExit(
            'The show_disk function must be called with -f or --function.'
        )

    if not conn:
        conn = get_conn()

    if kwargs is None:
        kwargs = {}

    if 'name' not in kwargs:
        raise SaltCloudSystemExit('A name must be specified as "name"')

    old_data = show_disk(kwargs={'name': kwargs['name']}, call='function')
    data = conn.update_disk(
        disk_name=kwargs['name'],
        has_operating_system=kwargs.get('has_operating_system', old_data['has_operating_system']),
        label=kwargs.get('label', old_data['label']),
        media_link=kwargs.get('media_link', old_data['media_link']),
        name=kwargs.get('new_name', old_data['name']),
        os=kwargs.get('os', old_data['os']),
    )
    return show_disk(kwargs={'name': kwargs['name']}, call='function')
1310876
def attach(self, id, filename, url):
        
        Attachment = self.client.model('ir.attachment')
        return Attachment.add_attachment_from_url(
            filename, url, '%s,%s' % (self.model_name, id)
        )
977811
def create(self, *args, **kwargs):
        
        try:
            return super(CloudBlockStorageManager, self).create(*args,
                    **kwargs)
        except exc.BadRequest as e:
            msg = e.message
            if "Clones currently must be >= original volume size" in msg:
                raise exc.VolumeCloneTooSmall(msg)
            else:
                raise
22204
def _clone_disk(self, configuration):
        """"""
        disk_clone(self._hypervisor, self.identifier, self._storage_pool,
                   configuration, self.provider_image, self.logger)
        disk_name = self._storage_pool.listVolumes()[0]

        return self._storage_pool.storageVolLookupByName(disk_name).path()
77530
def attach_file_to_idea(self, filename, *args, **kwargs):
        
        kwargs.update({'file': {'attachment': open(filename, 'rb')}})
        return bind_api(
            api=self,
            path='/ideas/{ideaId}/attach',
            method='POST',
            payload_type='idea',
            allowed_param=['ideaId']
        )(*args, **kwargs)
900219
def volume_attached(name, server_name, provider=None, **kwargs):
    '''
    
    '''
    ret = _check_name(name)
    if not ret['result']:
        return ret

    ret = _check_name(server_name)
    if not ret['result']:
        return ret

    volumes = __salt__['cloud.volume_list'](provider=provider)
    instance = __salt__['cloud.action'](
        fun='show_instance',
        names=server_name
    )

    if name in volumes and volumes[name]['attachments']:
        volume = volumes[name]
        ret['comment'] = (
            'Volume {name} is already attached: {attachments}'.format(
                **volumes[name]
            )
        )
        ret['result'] = True
        return ret
    elif name not in volumes:
        ret['comment'] = 'Volume {0} does not exist'.format(name)
        ret['result'] = False
        return ret
    elif not instance:
        ret['comment'] = 'Server {0} does not exist'.format(server_name)
        ret['result'] = False
        return ret
    elif __opts__['test']:
        ret['comment'] = 'Volume {0} will be will be attached.'.format(
            name
        )
        ret['result'] = None
        return ret

    response = __salt__['cloud.volume_attach'](
        provider=provider,
        names=name,
        server_name=server_name,
        **kwargs
    )
    if response:
        ret['result'] = True
        ret['comment'] = 'Volume {0} was created'.format(name)
        ret['changes'] = {'old': volumes[name], 'new': response}
    else:
        ret['result'] = False
        ret['comment'] = 'Volume {0} failed to attach.'.format(name)
    return ret
1152067
def create_swap_disk(vm_, linode_id, swap_size=None):
    
    '''
    kwargs = {}

    if not swap_size:
        swap_size = get_swap_size(vm_)

    kwargs.update({'LinodeID': linode_id,
                   'Label': vm_['name'],
                   'Type': 'swap',
                   'Size': swap_size
                  })

    result = _query('linode', 'disk.create', args=kwargs)

    return _clean_data(result)
471686
def attach_to_container(self, container_id):
        
        sock = self._docker.containers.get(container_id).attach_socket(params={
            'stdin': 1,
            'stdout': 1,
            'stderr': 0,
            'stream': 1,
        })
        # fix a problem with docker-py; we must keep a reference of sock at every time
        return FixDockerSocket(sock)
930874
def _reattach_linked_hdds(self):
        

        hdd_info_file = os.path.join(self.working_dir, self._vmname, "hdd_info.json")
        try:
            with open(hdd_info_file, "r", encoding="utf-8") as f:
                hdd_table = json.load(f)
        except (ValueError, OSError) as e:
            # The VM has never be started
            return

        for hdd_info in hdd_table:
            hdd_file = os.path.join(self.working_dir, self._vmname, "Snapshots", hdd_info["hdd"])
            if os.path.exists(hdd_file):
                log.info("VirtualBox VM '{name}' [{id}] attaching HDD {controller} {port} {device} {medium}".format(name=self.name,
                                                                                                                    id=self.id,
                                                                                                                    controller=hdd_info["controller"],
                                                                                                                    port=hdd_info["port"],
                                                                                                                    device=hdd_info["device"],
                                                                                                                    medium=hdd_file))

                try:
                    yield from self._storage_attach('--storagectl "{}" --port {} --device {} --type hdd --medium "{}"'.format(hdd_info["controller"],
                                                                                                                              hdd_info["port"],
                                                                                                                              hdd_info["device"],
                                                                                                                              hdd_file))

                except VirtualBoxError as e:
                    log.warn("VirtualBox VM '{name}' [{id}] error reattaching HDD {controller} {port} {device} {medium}: {error}".format(name=self.name,
                                                                                                                                         id=self.id,
                                                                                                                                         controller=hdd_info["controller"],
                                                                                                                                         port=hdd_info["port"],
                                                                                                                                         device=hdd_info["device"],
                                                                                                                                         medium=hdd_file,
                                                                                                                                         error=e))
                    continue
1146568
def add(self, origin):
        

        digest = self._calc_digest(origin)

        if self.exists(digest):
            self.logger.debug('Added File: [{0}] ( Already exists. Skipping transfer)'.format(digest))
            return digest

        absPath = self.get_file_path(digest)
        absFolderPath = os.path.dirname(absPath)

        # make all parent directories if they do not exist
        self._makedirs(absFolderPath)
        self._copy_content(origin, absPath)

        self.logger.debug('Added file: "{0}" [{1}]'.format(digest, absPath))

        return digest
332884
def attach(gandi, disk, vm, position, read_only, background, force):
    
    if not force:
        proceed = click.confirm("Are you sure you want to attach disk '%s'"
                                " to vm '%s'?" % (disk, vm))
        if not proceed:
            return

    disk_info = gandi.disk.info(disk)
    attached = disk_info.get('vms_id', False)
    if attached and not force:
        gandi.echo('This disk is still attached')
        proceed = click.confirm('Are you sure you want to detach %s?' % disk)

        if not proceed:
            return

    result = gandi.disk.attach(disk, vm, background, position, read_only)
    if background and result:
        gandi.pretty_echo(result)

    return result
47306
public boolean attachVolumes() {

		boolean allAttached = true;
		String zoneName = OpenstackIaasHandler.findZoneName( this.novaApi, this.targetProperties );
		for( Map.Entry<String,String> entry : this.storageIdToVolumeId.entrySet()) {

			String volumeId = entry.getValue();
			String storageId = entry.getKey();

			VolumeApi volumeApi = this.novaApi.getVolumeExtensionForZone( zoneName ).get();
			Volume createdVolume = volumeApi.get( volumeId );

			// Already attached? Skip...
			Boolean attached = this.volumeIdToAttached.get( volumeId );
			if( attached != null && attached )
				continue;

			// Otherwise, try to attach it, if possible.
			if( createdVolume.getStatus() == Volume.Status.AVAILABLE ) {
				String device = OpenstackIaasHandler.findStorageProperty( this.targetProperties, storageId, VOLUME_MOUNT_POINT_PREFIX );
				VolumeAttachmentApi volumeAttachmentApi = this.novaApi.getVolumeAttachmentExtensionForZone( zoneName ).get();
				volumeAttachmentApi.attachVolumeToServerAsDevice( volumeId, this.machineId, device );

				// Notice: there is no way, unlike in AWS, to specify a volume should be deleted when the
				// server terminates. This option is only available with BlockDeviceMapping, which means
				// booting a server from a volume (which is not the same than attaching a volume to a server).
				// See https://review.openstack.org/#/c/67067/

				// BlockDeviceMapping would rather be used when creating the server with Nova.
				// And it is a real mess to understand.

				// FIXME: how about when attachment fails (e.g. if the volume is already attached to another VM)?
				this.volumeIdToAttached.put( volumeId, Boolean.TRUE );
				this.logger.info( "Volume " + volumeId + " was successfully attached to " + this.scopedInstance.getName());
			}

			// Not available, we will attach it later.
			else {
				this.logger.fine( "Volume " + volumeId + " is not yet available to be attached to " + this.scopedInstance.getName());
				allAttached = false;
			}
		}

		return allAttached;
	}