Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIX JENKINS-33663] - Upgrade wizard
Add Upgrade Wizard
Add 'replace' handlebars method in jenkins.js
Fix state transitions to follow a single basic pattern
Suggested plugins selected by default
Add an install state for INITIAL_SECURITY_SETUP
Removed duplicate setupWizard.js on page [FIX JENKINS-34676]
Exclude plugins which are already installed when determining platform
Change 'snooze' to not look like a 'close' button
Make sure unlock screen doesn't show up after new install
Add compatibility check when offering suggested plugins
More appropriate handling of security token filter
  • Loading branch information
kzantow committed May 20, 2016
1 parent 74d0412 commit 89a24ab
Show file tree
Hide file tree
Showing 41 changed files with 1,122 additions and 508 deletions.
18 changes: 7 additions & 11 deletions core/src/main/java/hudson/PluginManager.java
Expand Up @@ -670,7 +670,7 @@ protected static void addDependencies(URL hpiResUrl, String fromPath, Set<URL> d
*/
protected void loadDetachedPlugins() {
InstallState installState = Jenkins.getActiveInstance().getInstallState();
if (installState == InstallState.UPGRADE) {
if (InstallState.UPGRADE.equals(installState)) {
VersionNumber lastExecVersion = new VersionNumber(InstallUtil.getLastExecVersion());

LOGGER.log(INFO, "Upgrading Jenkins. The last running version was {0}. This Jenkins is version {1}.",
Expand Down Expand Up @@ -1199,9 +1199,7 @@ public HttpResponse doUpdateSources(StaplerRequest req) throws IOException {
public void doInstallPluginsDone() {
Jenkins j = Jenkins.getInstance();
j.checkPermission(Jenkins.ADMINISTER);
if(InstallState.INITIAL_PLUGINS_INSTALLING.equals(j.getInstallState())) {
Jenkins.getInstance().setInstallState(InstallState.INITIAL_PLUGINS_INSTALLING.getNextState());
}
InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING);
}

/**
Expand Down Expand Up @@ -1313,20 +1311,18 @@ private List<Future<UpdateCenter.UpdateCenterJob>> install(@Nonnull Collection<S
installJobs.add(jobFuture);
}

if (Jenkins.getActiveInstance().getInstallState() == InstallState.NEW) {
trackInitialPluginInstall(installJobs);
}
trackInitialPluginInstall(installJobs);

return installJobs;
}

private void trackInitialPluginInstall(@Nonnull final List<Future<UpdateCenter.UpdateCenterJob>> installJobs) {
final Jenkins jenkins = Jenkins.getActiveInstance();
final Jenkins jenkins = Jenkins.getInstance();
final UpdateCenter updateCenter = jenkins.getUpdateCenter();

updateCenter.persistInstallStatus();
if (jenkins.getInstallState() == InstallState.NEW) {
if (!Jenkins.getInstance().getInstallState().isSetupComplete()) {
jenkins.setInstallState(InstallState.INITIAL_PLUGINS_INSTALLING);
updateCenter.persistInstallStatus();
new Thread() {
@Override
public void run() {
Expand All @@ -1352,7 +1348,7 @@ public void run() {
}
updateCenter.persistInstallStatus();
if(!failures) {
jenkins.setInstallState(InstallState.INITIAL_PLUGINS_INSTALLING.getNextState());
InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING);
}
}
}.start();
Expand Down
147 changes: 127 additions & 20 deletions core/src/main/java/jenkins/install/InstallState.java
Expand Up @@ -24,66 +24,137 @@
package jenkins.install;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import jenkins.model.Jenkins;

/**
* Jenkins install state.
*
* In order to hook into the setup wizard lifecycle, you should
* include something in a script that call
* to `onSetupWizardInitialized` with a callback, for example:
*
* See <em><code>upgradeWizard.js</code></em> for an example
*
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
@Restricted(NoExternalUse.class)
public enum InstallState {
public class InstallState implements ExtensionPoint {
/**
* Need InstallState != NEW for tests by default
*/
UNKNOWN(true, null),
@Extension
public static final InstallState UNKNOWN = new InstallState("UNKNOWN", true);

/**
* After any setup / restart / etc. hooks are done, states hould be running
*/
@Extension
public static final InstallState RUNNING = new InstallState("RUNNING", true);

/**
* The initial set up has been completed
*/
INITIAL_SETUP_COMPLETED(true, null),
@Extension
public static final InstallState INITIAL_SETUP_COMPLETED = new InstallState("INITIAL_SETUP_COMPLETED", true) {
public void initializeState() {
Jenkins j = Jenkins.getInstance();
try {
j.getSetupWizard().completeSetup();
} catch (Exception e) {
throw new RuntimeException(e);
}
j.setInstallState(RUNNING);
}
};

/**
* Creating an admin user for an initial Jenkins install.
*/
CREATE_ADMIN_USER(false, INITIAL_SETUP_COMPLETED),
@Extension
public static final InstallState CREATE_ADMIN_USER = new InstallState("CREATE_ADMIN_USER", false);

/**
* New Jenkins install. The user has kicked off the process of installing an
* initial set of plugins (via the install wizard).
*/
INITIAL_PLUGINS_INSTALLING(false, CREATE_ADMIN_USER),
@Extension
public static final InstallState INITIAL_PLUGINS_INSTALLING = new InstallState("INITIAL_PLUGINS_INSTALLING", false);

/**
* Security setup for a new Jenkins install.
*/
@Extension
public static final InstallState INITIAL_SECURITY_SETUP = new InstallState("INITIAL_SECURITY_SETUP", false) {
public void initializeState() {
try {
Jenkins.getInstance().getSetupWizard().init(true);
} catch (Exception e) {
throw new RuntimeException(e);
}

InstallUtil.proceedToNextStateFrom(INITIAL_SECURITY_SETUP);
}
};

/**
* New Jenkins install.
*/
NEW(false, INITIAL_PLUGINS_INSTALLING),
@Extension
public static final InstallState NEW = new InstallState("NEW", false);

/**
* Restart of an existing Jenkins install.
*/
RESTART(true, INITIAL_SETUP_COMPLETED),
@Extension
public static final InstallState RESTART = new InstallState("RESTART", true) {
public void initializeState() {
InstallUtil.saveLastExecVersion();
}
};

/**
* Upgrade of an existing Jenkins install.
*/
UPGRADE(true, INITIAL_SETUP_COMPLETED),
@Extension
public static final InstallState UPGRADE = new UpgradeWizard();

/**
* Downgrade of an existing Jenkins install.
*/
DOWNGRADE(true, INITIAL_SETUP_COMPLETED),
@Extension
public static final InstallState DOWNGRADE = new InstallState("DOWNGRADE", true) {
public void initializeState() {
InstallUtil.saveLastExecVersion();
}
};

/**
* Jenkins started in test mode (JenkinsRule).
*/
TEST(true, INITIAL_SETUP_COMPLETED),
public static final InstallState TEST = new InstallState("TEST", true);

/**
* Jenkins started in development mode: Bolean.getBoolean("hudson.Main.development").
* Can be run normally with the -Djenkins.install.runSetupWizard=true
*/
DEVELOPMENT(true, INITIAL_SETUP_COMPLETED);
public static final InstallState DEVELOPMENT = new InstallState("DEVELOPMENT", true);

private final boolean isSetupComplete;
private final InstallState nextState;
private final String name;

private InstallState(boolean isSetupComplete, InstallState nextState) {
public InstallState(@Nonnull String name, boolean isSetupComplete) {
this.name = name;
this.isSetupComplete = isSetupComplete;
this.nextState = nextState;
}

/**
* Process any initialization this install state requires
*/
public void initializeState() {
}

/**
Expand All @@ -93,11 +164,47 @@ public boolean isSetupComplete() {
return isSetupComplete;
}

public String name() {
return name;
}

@Override
public int hashCode() {
return name.hashCode();
}

@Override
public boolean equals(Object obj) {
if(obj instanceof InstallState) {
return name.equals(((InstallState)obj).name());
}
return false;
}

@Override
public String toString() {
return "InstallState (" + name + ")";
}

/**
* Gets the next state
* Find an install state by name
* @param name
* @return
*/
@CheckForNull
public InstallState getNextState() {
return nextState;
public static InstallState valueOf(@Nonnull String name) {
for (InstallState state : all()) {
if (name.equals(state.name)) {
return state;
}
}
return null;
}

/**
* Returns all install states in the system
*/
static ExtensionList<InstallState> all() {
return ExtensionList.lookup(InstallState.class);
}
}
26 changes: 26 additions & 0 deletions core/src/main/java/jenkins/install/InstallStateFilter.java
@@ -0,0 +1,26 @@
package jenkins.install;

import java.util.List;

import javax.inject.Provider;

import hudson.ExtensionList;
import hudson.ExtensionPoint;

/**
* Allows plugging in to the lifecycle when determining InstallState
* from {@link InstallUtil#getNextInstallState(InstallState)}
*/
public abstract class InstallStateFilter implements ExtensionPoint {
/**
* Determine the current or next install state, proceed with `return proceed.next()`
*/
public abstract InstallState getNextInstallState(InstallState current, Provider<InstallState> proceed);

/**
* Get all the InstallStateFilters, in extension order
*/
public static List<InstallStateFilter> all() {
return ExtensionList.lookup(InstallStateFilter.class);
}
}

0 comments on commit 89a24ab

Please sign in to comment.