use of com.yahoo.component.Version in project vespa by vespa-engine.
the class DockerProvisioningTest method docker_application_deployment.
@Test
public void docker_application_deployment() {
ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")));
ApplicationId application1 = tester.makeApplicationId();
for (int i = 1; i < 10; i++) tester.makeReadyDockerNodes(1, dockerFlavor, "dockerHost" + i);
Version wantedVespaVersion = Version.fromString("6.39");
int nodeCount = 7;
List<HostSpec> hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), wantedVespaVersion, false), nodeCount, 1, dockerFlavor);
tester.activate(application1, new HashSet<>(hosts));
NodeList nodes = tester.getNodes(application1, Node.State.active);
assertEquals(nodeCount, nodes.size());
assertEquals(dockerFlavor, nodes.asList().get(0).flavor().canonicalName());
// Upgrade Vespa version on nodes
Version upgradedWantedVespaVersion = Version.fromString("6.40");
List<HostSpec> upgradedHosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), upgradedWantedVespaVersion, false), nodeCount, 1, dockerFlavor);
tester.activate(application1, new HashSet<>(upgradedHosts));
NodeList upgradedNodes = tester.getNodes(application1, Node.State.active);
assertEquals(nodeCount, upgradedNodes.size());
assertEquals(dockerFlavor, upgradedNodes.asList().get(0).flavor().canonicalName());
assertEquals(hosts, upgradedHosts);
}
use of com.yahoo.component.Version in project vespa by vespa-engine.
the class ApplicationController method deployApplication.
/**
* Deploys an application. If the application does not exist it is created.
*/
// TODO: Get rid of the options arg
public ActivateResult deployApplication(ApplicationId applicationId, ZoneId zone, Optional<ApplicationPackage> applicationPackageFromDeployer, DeployOptions options) {
try (Lock lock = lock(applicationId)) {
LockedApplication application = get(applicationId).map(app -> new LockedApplication(app, lock)).orElseGet(() -> new LockedApplication(createApplication(applicationId, Optional.empty()), lock));
final boolean canDeployDirectly = canDeployDirectlyTo(zone, options);
// Determine Vespa version to use
Version version;
if (options.deployCurrentVersion) {
version = application.versionIn(zone, controller);
} else if (canDeployDirectlyTo(zone, options)) {
version = options.vespaVersion.map(Version::new).orElse(controller.systemVersion());
} else if (!application.change().isPresent() && !zone.environment().isManuallyDeployed()) {
return unexpectedDeployment(applicationId, zone, applicationPackageFromDeployer);
} else {
version = application.deployVersionIn(zone, controller);
}
// Determine application package to use
Pair<ApplicationPackage, ApplicationVersion> artifact = artifactFor(zone, application, applicationPackageFromDeployer, canDeployDirectly, options.deployCurrentVersion);
ApplicationPackage applicationPackage = artifact.getFirst();
ApplicationVersion applicationVersion = artifact.getSecond();
validate(applicationPackage.deploymentSpec());
// Update application with information from application package
if (!options.deployCurrentVersion) {
// Store information about application package
application = application.with(applicationPackage.deploymentSpec());
application = application.with(applicationPackage.validationOverrides());
// Delete zones not listed in DeploymentSpec, if allowed
// We do this at deployment time to be able to return a validation failure message when necessary
application = deleteRemovedDeployments(application);
// Clean up deployment jobs that are no longer referenced by deployment spec
application = deleteUnreferencedDeploymentJobs(application);
// TODO jvenstad: Store triggering information here, including versions, when job status is read from the build service.
// store missing information even if we fail deployment below
store(application);
}
// Validate the change being deployed
if (!canDeployDirectly) {
validateChange(application, zone, version);
}
// Assign global rotation
application = withRotation(application, zone);
Set<String> rotationNames = new HashSet<>();
Set<String> cnames = new HashSet<>();
application.rotation().ifPresent(applicationRotation -> {
rotationNames.add(applicationRotation.id().asString());
cnames.add(applicationRotation.dnsName());
cnames.add(applicationRotation.secureDnsName());
});
// Carry out deployment
options = withVersion(version, options);
ConfigServerClient.PreparedApplication preparedApplication = configServer.prepare(new DeploymentId(applicationId, zone), options, cnames, rotationNames, applicationPackage.zippedContent());
preparedApplication.activate();
application = application.withNewDeployment(zone, applicationVersion, version, clock.instant());
store(application);
return new ActivateResult(new RevisionId(applicationPackage.hash()), preparedApplication.prepareResponse(), applicationPackage.zippedContent().length);
}
}
use of com.yahoo.component.Version in project vespa by vespa-engine.
the class DeploymentTrigger method changeDeployed.
/**
* Returns whether the given application should skip deployment of its current change to the given production job zone.
*
* If the currently deployed application has a newer platform or application version than the application's
* current change, the method returns {@code true}, to avoid a downgrade.
* Otherwise, it returns whether the current change is redundant, i.e., all its components are already deployed.
*/
private boolean changeDeployed(Application application, JobType job) {
if (!job.isProduction())
throw new IllegalArgumentException(job + " is not a production job!");
Deployment deployment = application.deployments().get(job.zone(controller.system()).get());
if (deployment == null)
return false;
int applicationComparison = application.change().application().map(version -> version.compareTo(deployment.applicationVersion())).orElse(0);
int platformComparion = application.change().platform().map(version -> version.compareTo(deployment.version())).orElse(0);
if (applicationComparison == -1 || platformComparion == -1)
// Avoid downgrades!
return true;
return applicationComparison == 0 && platformComparion == 0;
}
use of com.yahoo.component.Version in project vespa by vespa-engine.
the class DeploymentTrigger method triggerReadyJobs.
// --- End of methods which triggers deployment jobs ----------------------------
/**
* Find the next step to trigger if any, and triggers it
*/
private void triggerReadyJobs(LockedApplication application) {
List<JobType> jobs = order.jobsFrom(application.deploymentSpec());
// Should the first step be triggered?
if (!jobs.isEmpty() && jobs.get(0).equals(JobType.systemTest)) {
JobStatus systemTestStatus = application.deploymentJobs().jobStatus().get(JobType.systemTest);
if (application.change().platform().isPresent()) {
Version target = application.change().platform().get();
if (systemTestStatus == null || !systemTestStatus.lastTriggered().isPresent() || !systemTestStatus.isSuccess() || !systemTestStatus.lastTriggered().get().version().equals(target) || systemTestStatus.isHanging(jobTimeoutLimit())) {
application = trigger(new Triggering(application, JobType.systemTest, false, "Upgrade to " + target), Collections.emptySet(), false);
applications().store(application);
}
}
}
// Find next steps to trigger based on the state of the previous step
for (JobType jobType : (Iterable<JobType>) Stream.concat(Stream.of(JobType.component), jobs.stream())::iterator) {
JobStatus jobStatus = application.deploymentJobs().jobStatus().get(jobType);
// job has never run
if (jobStatus == null)
continue;
// Collect the subset of next jobs which have not run with the last changes
// TODO jvenstad: Change to be step-centric.
List<JobType> nextJobs = order.nextAfter(jobType, application);
for (JobType nextJobType : nextJobs) {
JobStatus nextStatus = application.deploymentJobs().jobStatus().get(nextJobType);
if (changesAvailable(application, jobStatus, nextStatus) || nextStatus.isHanging(jobTimeoutLimit())) {
boolean isRetry = nextStatus != null && nextStatus.jobError().filter(JobError.outOfCapacity::equals).isPresent();
application = trigger(new Triggering(application, nextJobType, isRetry, isRetry ? "Retrying on out of capacity" : "Available change in " + jobType.jobName()), nextJobs, false);
}
}
applications().store(application);
}
}
use of com.yahoo.component.Version in project vespa by vespa-engine.
the class DeploymentIssueReporter method maintainPlatformIssue.
/**
* When the confidence for the system version is BROKEN, file an issue listing the
* applications that have been failing the upgrade to the system version for
* longer than the set grace period, or update this list if the issue already exists.
*/
private void maintainPlatformIssue(List<Application> applications) {
Version systemVersion = controller().systemVersion();
if ((controller().versionStatus().version(systemVersion).confidence() != broken))
return;
if (ApplicationList.from(applications).failingUpgradeToVersionSince(systemVersion, controller().clock().instant().minus(upgradeGracePeriod)).isEmpty())
return;
List<ApplicationId> failingApplications = ApplicationList.from(applications).failingUpgradeToVersionSince(systemVersion, controller().clock().instant()).idList();
deploymentIssues.fileUnlessOpen(failingApplications, systemVersion);
}
Aggregations