use of io.fabric8.kubernetes.client.Watch in project fabric8-maven-plugin by fabric8io.
the class WatchMojo method executeInternal.
@Override
protected synchronized void executeInternal(ServiceHub hub) throws DockerAccessException, MojoExecutionException {
this.hub = hub;
URL masterUrl = kubernetes.getMasterUrl();
KubernetesResourceUtil.validateKubernetesMasterUrl(masterUrl);
File manifest;
boolean isOpenshift = KubernetesHelper.isOpenShift(kubernetes);
if (isOpenshift) {
manifest = openshiftManifest;
} else {
manifest = kubernetesManifest;
}
try {
Set<HasMetadata> resources = KubernetesResourceUtil.loadResources(manifest);
WatcherContext context = getWatcherContext();
WatcherManager.watch(getResolvedImages(), resources, context);
} catch (KubernetesClientException ex) {
KubernetesResourceUtil.handleKubernetesClientException(ex, this.log);
} catch (Exception ex) {
throw new MojoExecutionException("An error has occurred while while trying to watch the resources", ex);
}
}
use of io.fabric8.kubernetes.client.Watch in project fabric8-maven-plugin by fabric8io.
the class PortForwardService method forwardPortAsync.
/**
* Forwards a port to the newest pod matching the given selector.
* If another pod is created, it forwards connections to the new pod once it's ready.
*/
public Closeable forwardPortAsync(final Logger externalProcessLogger, final LabelSelector podSelector, final int remotePort, final int localPort) throws Fabric8ServiceException {
final Lock monitor = new ReentrantLock(true);
final Condition podChanged = monitor.newCondition();
final Pod[] nextForwardedPod = new Pod[1];
final Thread forwarderThread = new Thread() {
@Override
public void run() {
Pod currentPod = null;
Closeable currentPortForward = null;
try {
monitor.lock();
while (true) {
if (podEquals(currentPod, nextForwardedPod[0])) {
podChanged.await();
} else {
// may be null
Pod nextPod = nextForwardedPod[0];
try {
monitor.unlock();
if (currentPortForward != null) {
log.info("Closing port-forward from pod %s", KubernetesHelper.getName(currentPod));
currentPortForward.close();
currentPortForward = null;
}
if (nextPod != null) {
log.info("Starting port-forward to pod %s", KubernetesHelper.getName(nextPod));
currentPortForward = forwardPortAsync(externalProcessLogger, KubernetesHelper.getName(nextPod), remotePort, localPort);
} else {
log.info("Waiting for a pod to become ready before starting port-forward");
}
currentPod = nextPod;
} finally {
monitor.lock();
}
}
}
} catch (InterruptedException e) {
log.debug("Port-forwarding thread interrupted", e);
Thread.currentThread().interrupt();
} catch (Exception e) {
log.warn("Error while port-forwarding to pod", e);
} finally {
monitor.unlock();
if (currentPortForward != null) {
try {
currentPortForward.close();
} catch (Exception e) {
}
}
}
}
};
// Switching forward to the current pod if present
Pod newPod = getNewestPod(podSelector);
nextForwardedPod[0] = newPod;
final Watch watch = KubernetesClientUtil.withSelector(kubernetes.pods(), podSelector, log).watch(new Watcher<Pod>() {
@Override
public void eventReceived(Action action, Pod pod) {
monitor.lock();
try {
List<Pod> candidatePods;
if (nextForwardedPod[0] != null) {
candidatePods = new LinkedList<>();
candidatePods.add(nextForwardedPod[0]);
candidatePods.add(pod);
} else {
candidatePods = Collections.singletonList(pod);
}
// may be null
Pod newPod = getNewestPod(candidatePods);
if (!podEquals(nextForwardedPod[0], newPod)) {
nextForwardedPod[0] = newPod;
podChanged.signal();
}
} finally {
monitor.unlock();
}
}
@Override
public void onClose(KubernetesClientException e) {
// don't care
}
});
forwarderThread.start();
final Closeable handle = new Closeable() {
@Override
public void close() throws IOException {
try {
watch.close();
} catch (Exception e) {
}
try {
forwarderThread.interrupt();
forwarderThread.join(15000);
} catch (Exception e) {
}
}
};
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
handle.close();
} catch (Exception e) {
// suppress
}
}
});
return handle;
}
use of io.fabric8.kubernetes.client.Watch in project fabric8-maven-plugin by fabric8io.
the class PodLogService method tailAppPodsLogs.
public void tailAppPodsLogs(final KubernetesClient kubernetes, final String namespace, final Set<HasMetadata> entities, boolean watchAddedPodsOnly, String onExitOperation, boolean followLog, Date ignorePodsOlderThan, boolean waitInCurrentThread) {
LabelSelector selector = KubernetesResourceUtil.getPodLabelSelector(entities);
if (selector != null) {
String ctrlCMessage = "stop tailing the log";
if (Strings.isNotBlank(onExitOperation)) {
final String onExitOperationLower = onExitOperation.toLowerCase().trim();
if (onExitOperationLower.equals(OPERATION_UNDEPLOY)) {
ctrlCMessage = "undeploy the app";
} else if (onExitOperationLower.equals(OPERATION_STOP)) {
ctrlCMessage = "scale down the app and stop tailing the log";
} else {
log.warn("Unknown on-exit command: `%s`", onExitOperationLower);
}
resizeApp(kubernetes, namespace, entities, 1, log);
Runtime.getRuntime().addShutdownHook(new Thread("pod log service shutdown hook") {
@Override
public void run() {
if (onExitOperationLower.equals(OPERATION_UNDEPLOY)) {
log.info("Undeploying the app:");
deleteEntities(kubernetes, namespace, entities, context.getS2iBuildNameSuffix(), log);
} else if (onExitOperationLower.equals(OPERATION_STOP)) {
log.info("Stopping the app:");
resizeApp(kubernetes, namespace, entities, 0, log);
}
if (podWatcher != null) {
podWatcher.close();
}
closeLogWatcher();
}
});
}
waitAndLogPods(kubernetes, namespace, selector, watchAddedPodsOnly, ctrlCMessage, followLog, ignorePodsOlderThan, waitInCurrentThread);
} else {
log.warn("No selector in deployment so cannot watch pods!");
}
}
use of io.fabric8.kubernetes.client.Watch in project fabric8-maven-plugin by fabric8io.
the class PodLogService method waitAndLogPods.
private void waitAndLogPods(final KubernetesClient kubernetes, final String namespace, LabelSelector selector, final boolean watchAddedPodsOnly, final String ctrlCMessage, final boolean followLog, Date ignorePodsOlderThan, boolean waitInCurrentThread) {
FilterWatchListDeletable<Pod, PodList, Boolean, Watch, Watcher<Pod>> pods = withSelector(kubernetes.pods().inNamespace(namespace), selector, log);
if (context.getPodName() != null) {
log.info("Watching pod with selector %s, and name %s waiting for a running pod...", selector, context.getPodName());
pods = pods.withField("metadata.name", context.getPodName());
} else {
log.info("Watching pods with selector %s waiting for a running pod...", selector);
}
Pod latestPod = null;
boolean runningPod = false;
PodList list = pods.list();
if (list != null) {
List<Pod> items = list.getItems();
if (items != null) {
for (Pod pod : items) {
PodStatusType status = getPodStatus(pod);
switch(status) {
case WAIT:
case OK:
if (latestPod == null || KubernetesResourceUtil.isNewerResource(pod, latestPod)) {
if (ignorePodsOlderThan != null) {
Date podCreateTime = KubernetesResourceUtil.getCreationTimestamp(pod);
if (podCreateTime != null && podCreateTime.compareTo(ignorePodsOlderThan) > 0) {
latestPod = pod;
}
} else {
latestPod = pod;
}
}
runningPod = true;
break;
case ERROR:
default:
continue;
}
}
}
}
// we may have missed the ADDED event so lets simulate one
if (latestPod != null) {
onPod(Watcher.Action.ADDED, latestPod, kubernetes, namespace, ctrlCMessage, followLog);
}
if (!watchAddedPodsOnly) {
// lets watch the current pods then watch for changes
if (!runningPod) {
log.warn("No pod is running yet. Are you sure you deployed your app via `fabric8:deploy`?");
log.warn("Or did you stop it via `fabric8:stop`? If so try running the `fabric8:start` goal");
}
}
podWatcher = pods.watch(new Watcher<Pod>() {
@Override
public void eventReceived(Action action, Pod pod) {
onPod(action, pod, kubernetes, namespace, ctrlCMessage, followLog);
}
@Override
public void onClose(KubernetesClientException e) {
// ignore
}
});
if (waitInCurrentThread) {
while (terminateLatch.getCount() > 0) {
try {
terminateLatch.await();
} catch (InterruptedException e) {
// ignore
}
}
}
}
use of io.fabric8.kubernetes.client.Watch in project fabric8-maven-plugin by fabric8io.
the class DockerImageWatcher method watch.
@Override
public void watch(List<ImageConfiguration> configs, final Set<HasMetadata> resources, PlatformMode mode) {
BuildService.BuildContext buildContext = getContext().getBuildContext();
WatchService.WatchContext watchContext = getContext().getWatchContext();
// add a image customizer
watchContext = new WatchService.WatchContext.Builder(watchContext).imageCustomizer(new Task<ImageConfiguration>() {
@Override
public void execute(ImageConfiguration imageConfiguration) throws DockerAccessException, MojoExecutionException, MojoFailureException {
buildImage(imageConfiguration);
}
}).containerRestarter(new Task<WatchService.ImageWatcher>() {
@Override
public void execute(WatchService.ImageWatcher imageWatcher) throws DockerAccessException, MojoExecutionException, MojoFailureException {
restartContainer(imageWatcher, resources);
}
}).build();
ServiceHub hub = getContext().getServiceHub();
try {
hub.getWatchService().watch(watchContext, buildContext, configs);
} catch (Exception ex) {
throw new RuntimeException("Error while watching", ex);
}
}
Aggregations