<commit_before>package io.cattle.platform.docker.process.instancehostmap;

import static io.cattle.platform.core.model.tables.IpAddressTable.IP_ADDRESS;
import static io.cattle.platform.core.model.tables.MountTable.MOUNT;
import static io.cattle.platform.core.model.tables.PortTable.PORT;
import static io.cattle.platform.docker.constants.DockerVolumeConstants.READ_ONLY;
import static io.cattle.platform.docker.constants.DockerVolumeConstants.READ_WRITE;
import io.cattle.platform.archaius.util.ArchaiusUtil;
import io.cattle.platform.core.constants.NetworkServiceConstants;
import io.cattle.platform.core.constants.PortConstants;
import io.cattle.platform.core.constants.VolumeConstants;
import io.cattle.platform.core.dao.ClusterHostMapDao;
import io.cattle.platform.core.dao.GenericMapDao;
import io.cattle.platform.core.dao.IpAddressDao;
import io.cattle.platform.core.dao.NetworkDao;
import io.cattle.platform.core.dao.NicDao;
import io.cattle.platform.core.model.Host;
import io.cattle.platform.core.model.HostIpAddressMap;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.InstanceHostMap;
import io.cattle.platform.core.model.IpAddress;
import io.cattle.platform.core.model.Mount;
import io.cattle.platform.core.model.Nic;
import io.cattle.platform.core.model.Port;
import io.cattle.platform.core.model.StoragePool;
import io.cattle.platform.core.model.Volume;
import io.cattle.platform.core.model.VolumeStoragePoolMap;
import io.cattle.platform.core.util.PortSpec;
import io.cattle.platform.docker.constants.DockerInstanceConstants;
import io.cattle.platform.docker.constants.DockerIpAddressConstants;
import io.cattle.platform.docker.process.dao.DockerComputeDao;
import io.cattle.platform.docker.process.lock.DockerStoragePoolVolumeCreateLock;
import io.cattle.platform.docker.process.util.DockerProcessUtils;
import io.cattle.platform.docker.storage.DockerStoragePoolDriver;
import io.cattle.platform.engine.handler.HandlerResult;
import io.cattle.platform.engine.handler.ProcessPostListener;
import io.cattle.platform.engine.process.ProcessInstance;
import io.cattle.platform.engine.process.ProcessState;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallback;
import io.cattle.platform.lock.LockManager;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.process.common.handler.AbstractObjectProcessLogic;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.config.DynamicBooleanProperty;

public class DockerPostInstanceHostMapActivate extends AbstractObjectProcessLogic implements ProcessPostListener {

    public static final DynamicBooleanProperty DYNAMIC_ADD_IP = ArchaiusUtil.getBoolean("docker.compute.auto.add.host.ip");

    private static final Logger log = LoggerFactory.getLogger(DockerPostInstanceHostMapActivate.class);

    JsonMapper jsonMapper;
    IpAddressDao ipAddressDao;
    DockerComputeDao dockerDao;
    NicDao nicDao;
    NetworkDao networkDao;
    GenericMapDao mapDao;
    LockManager lockManager;

    @Inject
    ClusterHostMapDao clusterHostMapDao;

    @Override
    public String[] getProcessNames() {
        return new String[] { "instancehostmap.activate" };
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public HandlerResult handle(ProcessState state, ProcessInstance process) {
        InstanceHostMap map = (InstanceHostMap) state.getResource();
        Instance instance = getObjectManager().loadResource(Instance.class, map.getInstanceId());
        Host host = getObjectManager().loadResource(Host.class, map.getHostId());

        String dockerIp = DockerProcessUtils.getDockerIp(instance);
        Nic nic = nicDao.getPrimaryNic(instance);

        IpAddress ipAddress = clusterHostMapDao.getIpAddressForHost(host.getId());
        Map ports = DataAccessor.fields(instance).withKey(DockerInstanceConstants.FIELD_DOCKER_PORTS).as(jsonMapper, Map.class);

        if (dockerIp != null) {
            processDockerIp(instance, nic, dockerIp);
        }

        if (ipAddress != null && ports != null) {
            processPorts(ipAddress, ports, instance, nic, host);
        }

        processVolumes(instance, host, state);

        return null;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected void processVolumes(Instance instance, Host host, ProcessState state) {
        StoragePool storagePool = null;
        for (StoragePool pool : objectManager.mappedChildren(host, StoragePool.class)) {
            if (DockerStoragePoolDriver.isDockerPool(pool)) {
                storagePool = pool;
                break;
            }
        }

        if (storagePool == null) {
            log.warn("Could not find docker storage pool for host [{}]. Volumes will not be created.", host.getId());
            return;
        }

        Map<String, Object> inspect = (Map<String, Object>) instance.getData().get("dockerInspect");
        if (inspect == null) {
            return;
        }
        Map<String, String> volumes = (Map<String, String>) inspect.get("Volumes");
        Map<String, Boolean> volumesRW = (Map<String, Boolean>) inspect.get("VolumesRW");
        Map<String, String> hostBindMounts = extractHostBindMounts((List<String>) ((Map) inspect.get("HostConfig")).get("Binds"));

        for (Map.Entry<String, String> volumeKV : volumes.entrySet()) {
            String pathInContainer = volumeKV.getKey();
            String pathOnHost = volumeKV.getValue();

            String volumeUri = String.format(VolumeConstants.URI_FORMAT, pathOnHost);
            boolean isHostPath = hostBindMounts.containsKey(pathInContainer);
            Volume volume = createVolumeInStoragePool(storagePool, instance, volumeUri, isHostPath);
            log.debug("Created volume and storage pool mapping. Volume id [{}], storage pool id [{}].", volume.getId(), storagePool.getId());
            createIgnoreCancel(volume, state.getData());

            for (VolumeStoragePoolMap map : mapDao.findNonRemoved(VolumeStoragePoolMap.class, Volume.class, volume.getId())) {
                if (map.getStoragePoolId().equals(storagePool.getId()))
                    createThenActivate(map, state.getData());
            }<commit_msg>Don't warn about missing pool when there are no volumes<commit_after>package io.cattle.platform.docker.process.instancehostmap;

import static io.cattle.platform.core.model.tables.IpAddressTable.IP_ADDRESS;
import static io.cattle.platform.core.model.tables.MountTable.MOUNT;
import static io.cattle.platform.core.model.tables.PortTable.PORT;
import static io.cattle.platform.docker.constants.DockerVolumeConstants.READ_ONLY;
import static io.cattle.platform.docker.constants.DockerVolumeConstants.READ_WRITE;
import io.cattle.platform.archaius.util.ArchaiusUtil;
import io.cattle.platform.core.constants.NetworkServiceConstants;
import io.cattle.platform.core.constants.PortConstants;
import io.cattle.platform.core.constants.VolumeConstants;
import io.cattle.platform.core.dao.ClusterHostMapDao;
import io.cattle.platform.core.dao.GenericMapDao;
import io.cattle.platform.core.dao.IpAddressDao;
import io.cattle.platform.core.dao.NetworkDao;
import io.cattle.platform.core.dao.NicDao;
import io.cattle.platform.core.model.Host;
import io.cattle.platform.core.model.HostIpAddressMap;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.InstanceHostMap;
import io.cattle.platform.core.model.IpAddress;
import io.cattle.platform.core.model.Mount;
import io.cattle.platform.core.model.Nic;
import io.cattle.platform.core.model.Port;
import io.cattle.platform.core.model.StoragePool;
import io.cattle.platform.core.model.Volume;
import io.cattle.platform.core.model.VolumeStoragePoolMap;
import io.cattle.platform.core.util.PortSpec;
import io.cattle.platform.docker.constants.DockerInstanceConstants;
import io.cattle.platform.docker.constants.DockerIpAddressConstants;
import io.cattle.platform.docker.process.dao.DockerComputeDao;
import io.cattle.platform.docker.process.lock.DockerStoragePoolVolumeCreateLock;
import io.cattle.platform.docker.process.util.DockerProcessUtils;
import io.cattle.platform.docker.storage.DockerStoragePoolDriver;
import io.cattle.platform.engine.handler.HandlerResult;
import io.cattle.platform.engine.handler.ProcessPostListener;
import io.cattle.platform.engine.process.ProcessInstance;
import io.cattle.platform.engine.process.ProcessState;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallback;
import io.cattle.platform.lock.LockManager;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.process.common.handler.AbstractObjectProcessLogic;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.config.DynamicBooleanProperty;

public class DockerPostInstanceHostMapActivate extends AbstractObjectProcessLogic implements ProcessPostListener {

    public static final DynamicBooleanProperty DYNAMIC_ADD_IP = ArchaiusUtil.getBoolean("docker.compute.auto.add.host.ip");

    private static final Logger log = LoggerFactory.getLogger(DockerPostInstanceHostMapActivate.class);

    JsonMapper jsonMapper;
    IpAddressDao ipAddressDao;
    DockerComputeDao dockerDao;
    NicDao nicDao;
    NetworkDao networkDao;
    GenericMapDao mapDao;
    LockManager lockManager;

    @Inject
    ClusterHostMapDao clusterHostMapDao;

    @Override
    public String[] getProcessNames() {
        return new String[] { "instancehostmap.activate" };
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public HandlerResult handle(ProcessState state, ProcessInstance process) {
        InstanceHostMap map = (InstanceHostMap) state.getResource();
        Instance instance = getObjectManager().loadResource(Instance.class, map.getInstanceId());
        Host host = getObjectManager().loadResource(Host.class, map.getHostId());

        String dockerIp = DockerProcessUtils.getDockerIp(instance);
        Nic nic = nicDao.getPrimaryNic(instance);

        IpAddress ipAddress = clusterHostMapDao.getIpAddressForHost(host.getId());
        Map ports = DataAccessor.fields(instance).withKey(DockerInstanceConstants.FIELD_DOCKER_PORTS).as(jsonMapper, Map.class);

        if (dockerIp != null) {
            processDockerIp(instance, nic, dockerIp);
        }

        if (ipAddress != null && ports != null) {
            processPorts(ipAddress, ports, instance, nic, host);
        }

        processVolumes(instance, host, state);

        return null;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected void processVolumes(Instance instance, Host host, ProcessState state) {

        Map<String, Object> inspect = (Map<String, Object>) instance.getData().get("dockerInspect");
        if (inspect == null) {
            return;
        }
        Map<String, String> volumes = (Map<String, String>) inspect.get("Volumes");
        Map<String, Boolean> volumesRW = (Map<String, Boolean>) inspect.get("VolumesRW");
        Map<String, String> hostBindMounts = extractHostBindMounts((List<String>) ((Map) inspect.get("HostConfig")).get("Binds"));

        if (volumes.size() == 0) {
            /* If there are no volumes avoid looking for a pool because one may not exists
             * for this host and we don't want to warn about that
             */
            return;
        }

        StoragePool storagePool = null;
        for (StoragePool pool : objectManager.mappedChildren(host, StoragePool.class)) {
            if (DockerStoragePoolDriver.isDockerPool(pool)) {
                storagePool = pool;
                break;
            }
        }

        if (storagePool == null) {
            log.warn("Could not find docker storage pool for host [{}]. Volumes will not be created.", host.getId());
            return;
        }

        for (Map.Entry<String, String> volumeKV : volumes.entrySet()) {
            String pathInContainer = volumeKV.getKey();
            String pathOnHost = volumeKV.getValue();

            String volumeUri = String.format(VolumeConstants.URI_FORMAT, pathOnHost);
            boolean isHostPath = hostBindMounts.containsKey(pathInContainer);
            Volume volume = createVolumeInStoragePool(storagePool, instance, volumeUri, isHostPath);
            log.debug("Created volume and storage pool mapping. Volume id [{}], storage pool id [{}].", volume.getId(), storagePool.getId());
            createIgnoreCancel(volume, state.getData());

            for (VolumeStoragePoolMap map : mapDao.findNonRemoved(VolumeStoragePoolMap.class, Volume.class, volume.getId())) {
                if (map.getStoragePoolId().equals(storagePool.getId()))
                    createThenActivate(map, state.getData());
            }
{'fraction_non_alphanumeric': 0.10701191567369386, 'fraction_numerical': 0.0005346776657500764, 'mean_word_length': 4.006883365200765, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4830144', 'n_tokens_mistral': 3742, 'n_tokens_neox': 3743, 'n_words': 687}