public void run() { log.info("Starting {} on machine {}", entity(), machine); Collection<Location> oldLocs = entity().getLocations(); if (!oldLocs.isEmpty()) { List<MachineLocation> oldSshLocs = ImmutableList.copyOf(Iterables.filter(oldLocs, MachineLocation.class)); if (!oldSshLocs.isEmpty()) { // check if existing locations are compatible log.debug( "Entity " + entity() + " had machine locations " + oldSshLocs + " when starting at " + machine + "; checking if they are compatible"); for (MachineLocation oldLoc : oldSshLocs) { // machines are deemed compatible if hostname and address are the same, or they are // localhost // this allows a machine create by jclouds to then be defined with an ip-based spec if (!"localhost".equals(machine.getConfig(AbstractLocation.ORIGINAL_SPEC))) { checkLocationParametersCompatible( machine, oldLoc, "hostname", oldLoc.getAddress().getHostName(), machine.getAddress().getHostName()); checkLocationParametersCompatible( machine, oldLoc, "address", oldLoc.getAddress().getHostAddress(), machine.getAddress().getHostAddress()); } } log.debug( "Entity " + entity() + " old machine locations " + oldSshLocs + " were compatible, removing them to start at " + machine); entity().removeLocations(oldSshLocs); } } entity().addLocations(ImmutableList.of((Location) machine)); // elsewhere we rely on (public) hostname being set _after_ subnet_hostname // (to prevent the tiny possibility of races resulting in hostname being returned // simply because subnet is still being looked up) Maybe<String> lh = Machines.getSubnetHostname(machine); Maybe<String> la = Machines.getSubnetIp(machine); if (lh.isPresent()) entity().sensors().set(Attributes.SUBNET_HOSTNAME, lh.get()); if (la.isPresent()) entity().sensors().set(Attributes.SUBNET_ADDRESS, la.get()); entity().sensors().set(Attributes.HOSTNAME, machine.getAddress().getHostName()); entity().sensors().set(Attributes.ADDRESS, machine.getAddress().getHostAddress()); if (machine instanceof SshMachineLocation) { SshMachineLocation sshMachine = (SshMachineLocation) machine; UserAndHostAndPort sshAddress = UserAndHostAndPort.fromParts( sshMachine.getUser(), sshMachine.getAddress().getHostName(), sshMachine.getPort()); // FIXME: Who or what is SSH_ADDRESS intended for? It's not necessarily the address that // the SshMachineLocation is using for ssh connections (because it accepts SSH_HOST as an // override). entity().sensors().set(Attributes.SSH_ADDRESS, sshAddress); } if (Boolean.TRUE.equals(entity().getConfig(SoftwareProcess.OPEN_IPTABLES))) { if (machine instanceof SshMachineLocation) { @SuppressWarnings("unchecked") Iterable<Integer> inboundPorts = (Iterable<Integer>) machine.config().get(CloudLocationConfig.INBOUND_PORTS); machineInitTasks.openIptablesAsync(inboundPorts, (SshMachineLocation) machine); } else { log.warn("Ignoring flag OPEN_IPTABLES on non-ssh location {}", machine); } } if (Boolean.TRUE.equals(entity().getConfig(SoftwareProcess.STOP_IPTABLES))) { if (machine instanceof SshMachineLocation) { machineInitTasks.stopIptablesAsync((SshMachineLocation) machine); } else { log.warn("Ignoring flag STOP_IPTABLES on non-ssh location {}", machine); } } if (Boolean.TRUE.equals(entity().getConfig(SoftwareProcess.DONT_REQUIRE_TTY_FOR_SUDO))) { if (machine instanceof SshMachineLocation) { machineInitTasks.dontRequireTtyForSudoAsync((SshMachineLocation) machine); } else { log.warn("Ignoring flag DONT_REQUIRE_TTY_FOR_SUDO on non-ssh location {}", machine); } } resolveOnBoxDir(entity(), machine); preStartCustom(machine); }