package io.fathom.cloud.compute.scheduler; import io.fathom.cloud.CloudException; import io.fathom.cloud.compute.networks.HostNetworkPool; import io.fathom.cloud.compute.networks.NetworkPoolAllocation; import io.fathom.cloud.compute.networks.NetworkPools; import io.fathom.cloud.compute.state.ComputeRepository; import io.fathom.cloud.protobuf.CloudModel.InstanceData; import io.fathom.cloud.protobuf.CloudModel.NetworkAddressData; import io.fathom.cloud.server.model.Project; import io.fathom.cloud.state.NumberedItemCollection; import java.util.List; import java.util.Random; import javax.inject.Inject; import javax.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.persist.Transactional; @Singleton @Transactional public class SchedulerServices { private static final Logger log = LoggerFactory.getLogger(SchedulerServices.class); @Inject private ComputeRepository computeStore; @Inject NetworkPools networkPools; public InstanceData updateInstance(final InstanceData instance, final InstanceData.Builder changes) throws CloudException { NumberedItemCollection<InstanceData> instances = computeStore.getInstances(instance.getProjectId()); InstanceData read = instances.find(instance.getId()); InstanceData.Builder b = InstanceData.newBuilder(read); b.mergeFrom(changes.build()); return instances.update(b); } private String buildMac() { // TODO: We should verify that this is in fact unique! // See here for a discussion of the first byte: // https://bugs.launchpad.net/nova/+bug/921838 Random random = new Random(); int b0 = 0xfa; int b1 = random.nextInt(256); int b2 = random.nextInt(256); int b3 = random.nextInt(256); int b4 = random.nextInt(256); int b5 = random.nextInt(256); String mac = String.format("%02X:%02X:%02X:%02X:%02X:%02X", b0, b1, b2, b3, b4, b5); return mac; } public InstanceData assignIps(Project project, SchedulerHost host, InstanceData instance) throws CloudException { List<NetworkPoolAllocation> addresses = networkPools.allocateIps(project, host, instance); InstanceData.Builder i = InstanceData.newBuilder(instance); for (NetworkPoolAllocation address : addresses) { NetworkAddressData.Builder addressData = NetworkAddressData .newBuilder(((HostNetworkPool.Allocation) address).getData()); addressData.setMacAddress(buildMac()); i.getNetworkBuilder().addAddresses(addressData); } return updateInstance(instance, i); } }