branding/img/action-order.gif
|binary
branding/spacewalk-branding.spec
| 5
java/code/src/com/redhat/rhn/common/db/datasource/xml/General_queries.xml
| 2
java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java
| 33 -
java/code/src/com/redhat/rhn/domain/kickstart/KickstartScript.java
| 76 ++
java/code/src/com/redhat/rhn/frontend/action/kickstart/KickstartScriptOrderAction.java
| 236 ++++++++
java/code/src/com/redhat/rhn/frontend/action/kickstart/ScriptsSetupAction.java
| 42 +
java/code/src/com/redhat/rhn/frontend/dto/kickstart/ScriptDto.java
| 144 -----
java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
| 18
java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
| 50 +
java/code/src/com/redhat/rhn/frontend/xmlrpc/kickstart/profile/ProfileHandler.java
| 122 ++++
java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/KickstartScriptSerializer.java
| 9
java/code/src/com/redhat/rhn/manager/kickstart/KickstartFormatter.java
| 266 ++++------
java/code/src/com/redhat/rhn/manager/kickstart/KickstartLister.java
| 47 +
java/code/webapp/WEB-INF/pages/activationkeys/configuration/rank.jsp
| 4
java/code/webapp/WEB-INF/pages/common/fragments/configuration/rankchannels.jspf
| 8
java/code/webapp/WEB-INF/pages/configuration/sdc/rankchannels.jsp
| 4
java/code/webapp/WEB-INF/pages/configuration/ssm/rankchannels.jsp
| 4
java/code/webapp/WEB-INF/pages/kickstart/scriptedit.jsp
| 14
java/code/webapp/WEB-INF/pages/kickstart/scriptorder.jsp
| 139 +++++
java/code/webapp/WEB-INF/pages/kickstart/scripts.jsp
| 79 +-
java/code/webapp/WEB-INF/struts-config.xml
| 38 +
java/spacewalk-java.spec
| 5
rel-eng/packages/spacewalk-branding
| 2
rel-eng/packages/spacewalk-java
| 2
schema/spacewalk/upgrade/spacewalk-schema-2.0-to-spacewalk-schema-2.1/021-rhnKickstartScript.sql
| 1
web/html/javascript/config_channel_ranks.js
| 102 ---
web/html/javascript/rank_options.js
| 120 ++++
28 files changed, 1095 insertions(+), 477 deletions(-)
New commits:
commit 40ea51f66b680e1ccd18d716e5f7d103d33683dd
Author: Stephen Herr <sherr(a)redhat.com>
Date: Thu Oct 17 15:02:45 2013 -0400
Automatic commit of package [spacewalk-branding] release [2.1.5-1].
diff --git a/branding/spacewalk-branding.spec b/branding/spacewalk-branding.spec
index 27e50fc..56822da 100644
--- a/branding/spacewalk-branding.spec
+++ b/branding/spacewalk-branding.spec
@@ -9,7 +9,7 @@
%endif
Name: spacewalk-branding
-Version: 2.1.4
+Version: 2.1.5
Release: 1%{?dist}
Summary: Spacewalk branding data
@@ -74,6 +74,9 @@ rm -rf %{buildroot}
%doc LICENSE
%changelog
+* Thu Oct 17 2013 Stephen Herr <sherr(a)redhat.com> 2.1.5-1
+- 1020497 - provide a way to order kickstart scripts
+
* Tue Oct 08 2013 Stephen Herr <sherr(a)redhat.com> 2.1.4-1
- 1006142 - non-roman character languages had bad wrapping for thin table
columns
diff --git a/rel-eng/packages/spacewalk-branding b/rel-eng/packages/spacewalk-branding
index c28e28c..5a36726 100644
--- a/rel-eng/packages/spacewalk-branding
+++ b/rel-eng/packages/spacewalk-branding
@@ -1 +1 @@
-2.1.4-1 branding/
+2.1.5-1 branding/
commit 707133564982d1bfd8e9c8635625080b6ae39ace
Author: Stephen Herr <sherr(a)redhat.com>
Date: Thu Oct 17 15:02:33 2013 -0400
Automatic commit of package [spacewalk-java] release [2.1.56-1].
diff --git a/java/spacewalk-java.spec b/java/spacewalk-java.spec
index e2ea77f..678a35c 100644
--- a/java/spacewalk-java.spec
+++ b/java/spacewalk-java.spec
@@ -28,7 +28,7 @@ Name: spacewalk-java
Summary: Spacewalk Java site packages
Group: Applications/Internet
License: GPLv2
-Version: 2.1.55
+Version: 2.1.56
Release: 1%{?dist}
URL:
https://fedorahosted.org/spacewalk
Source0:
https://fedorahosted.org/releases/s/p/spacewalk/%{name}-%{version}.tar.gz
@@ -785,6 +785,9 @@ fi
%{jardir}/postgresql-jdbc.jar
%changelog
+* Thu Oct 17 2013 Stephen Herr <sherr(a)redhat.com> 2.1.56-1
+- 1020497 - provide a way to order kickstart scripts
+
* Thu Oct 17 2013 Tomas Lestach <tlestach(a)redhat.com> 2.1.55-1
- 676828 - distinguish bash interpreter in ks non-chroot post scripts
diff --git a/rel-eng/packages/spacewalk-java b/rel-eng/packages/spacewalk-java
index 04e4857..ade0068 100644
--- a/rel-eng/packages/spacewalk-java
+++ b/rel-eng/packages/spacewalk-java
@@ -1 +1 @@
-2.1.55-1 java/
+2.1.56-1 java/
commit c821c7ee2d93635471930d5419a54494db34afb5
Author: Stephen Herr <sherr(a)redhat.com>
Date: Thu Oct 17 15:01:08 2013 -0400
1020497 - provide a way to order kickstart scripts
diff --git a/branding/img/action-order.gif b/branding/img/action-order.gif
new file mode 100644
index 0000000..c475c25
Binary files /dev/null and b/branding/img/action-order.gif differ
diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/General_queries.xml
b/java/code/src/com/redhat/rhn/common/db/datasource/xml/General_queries.xml
index ec35dc1..e6804f0 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/General_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/General_queries.xml
@@ -63,7 +63,7 @@ ORDER BY KS.label, KS.id
</query>
</mode>
-<mode name="scripts_for_kickstart"
class="com.redhat.rhn.frontend.dto.kickstart.ScriptDto">
+<mode name="scripts_for_kickstart"
class="com.redhat.rhn.domain.kickstart.KickstartScript">
<query params="kickstart_id">
SELECT KS.id, KS.script_type, KS.chroot, KS.interpreter, KS.script_name, KS.position
FROM rhnKickstartScript KS
diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java
b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java
index c305a2c..34fba87 100644
--- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java
+++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartData.java
@@ -929,16 +929,33 @@ public class KickstartData {
* @param ksIn to add
*/
public void addScript(KickstartScript ksIn) {
- // Calc the max position and add this script at the end
- Iterator i = scripts.iterator();
- long maxPosition = 0;
- while (i.hasNext()) {
- KickstartScript kss = (KickstartScript) i.next();
- if (kss.getPosition().longValue() > maxPosition) {
- maxPosition = kss.getPosition().longValue();
+ // The ordering goes: Pre scripts and post (chroot) scripts have
+ // positive positions, post nochroot scripts have negative
+ // positions where the most negative script is run right before
+ // Red Hat's scripts. The user can adjust these default positions
+ // later, but this allows us to preserve previous behavor where
+ // adding a nochroot post script added it right before Red Hat's
+ // post scripts and adding a post (chroot) script added it as the
+ // last script that runs.
+ if (ksIn.getScriptType().equals(KickstartScript.TYPE_POST) &&
+ !ksIn.thisScriptIsChroot()) {
+ Long minPosition = 0L;
+ for (KickstartScript script : scripts) {
+ if (script.getPosition() < minPosition) {
+ minPosition = script.getPosition();
+ }
+ }
+ ksIn.setPosition(minPosition - 1);
+ }
+ else {
+ Long maxPosition = 0L;
+ for (KickstartScript script : scripts) {
+ if (script.getPosition() > maxPosition) {
+ maxPosition = script.getPosition();
+ }
}
+ ksIn.setPosition(maxPosition + 1);
}
- ksIn.setPosition(new Long(maxPosition + 1));
ksIn.setKsdata(this);
scripts.add(ksIn);
diff --git a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartScript.java
b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartScript.java
index 3abcfc5..32676f3 100644
--- a/java/code/src/com/redhat/rhn/domain/kickstart/KickstartScript.java
+++ b/java/code/src/com/redhat/rhn/domain/kickstart/KickstartScript.java
@@ -15,17 +15,24 @@
package com.redhat.rhn.domain.kickstart;
import com.redhat.rhn.common.hibernate.HibernateFactory;
+import com.redhat.rhn.frontend.dto.BaseDto;
import java.util.Date;
+import org.apache.commons.lang.StringUtils;
+
/**
* KickstartScript - Class representation of the table rhnKickstartScript.
* @version $Rev: 1 $
*/
-public class KickstartScript implements Comparable<KickstartScript> {
+public class KickstartScript extends BaseDto implements Comparable<KickstartScript>
{
public static final String TYPE_PRE = "pre";
public static final String TYPE_POST = "post";
+ private static final String BASH = "bash";
+ private static final String PRE = "Pre";
+ private static final String POST = "Post";
+ private static final String NOCHROOTPOST = "Nochroot Post";
private Long id;
private Long position;
@@ -38,9 +45,24 @@ public class KickstartScript implements
Comparable<KickstartScript> {
private Date created;
private Date modified;
private Boolean raw = true;
+ private boolean editable = true;
private KickstartData ksdata;
+ /**
+ * @return True if the script is editable
+ */
+ public boolean getEditable() {
+ return this.editable;
+ }
+
+ /**
+ * @param editableIn Set if script is editable
+ */
+ public void setEditable(boolean editableIn) {
+ this.editable = editableIn;
+ }
+
/** Setup the default value for
* chroot and other fields.
*/
@@ -106,6 +128,28 @@ public class KickstartScript implements
Comparable<KickstartScript> {
}
/**
+ * Has to have the horrible name because "isChroot" is magic
+ * and causes a "can't cast boolean to String" error in hibernate.
+ * @return true if the script is run in a chrooted environment
+ */
+ public boolean thisScriptIsChroot() {
+ return !this.chroot.toLowerCase().equals("n");
+ }
+
+ /**
+ * @return script "prettyified" type for this script
+ */
+ public String getPrettyScriptType() {
+ if (this.scriptType.equals(TYPE_POST)) {
+ if (!this.thisScriptIsChroot()) {
+ return NOCHROOTPOST;
+ }
+ return POST;
+ }
+ return PRE;
+ }
+
+ /**
* Setter for scriptType
* @param scriptTypeIn to set
*/
@@ -157,6 +201,17 @@ public class KickstartScript implements
Comparable<KickstartScript> {
}
/**
+ *
+ * @return interpreter for this script
+ */
+ public String getPrettyInterpreter() {
+ if (StringUtils.isBlank(this.interpreter)) {
+ return BASH;
+ }
+ return interpreter;
+ }
+
+ /**
* Setter for interpreter
* @param interpreterIn to set
*/
@@ -268,6 +323,25 @@ public class KickstartScript implements
Comparable<KickstartScript> {
final int before = -1;
final int after = 1;
+ // pre scripts always come first
+ if (!scriptIn.getScriptType().equals(this.getScriptType())) {
+ if (scriptIn.getScriptType().equals(TYPE_PRE)) {
+ return after;
+ }
+ return before;
+ }
+
+ // If both positions are negative then -2 should come *after* -1.
+ // This is so that we can give a new script the most negative number
+ // and have it come right before Red Hat's scripts, preserving
+ // existing behavior.
+ if (scriptIn.getPosition() < 0 && this.getPosition() < 0) {
+ if (scriptIn.getPosition() > this.getPosition()) {
+ return after;
+ }
+ return before;
+ }
+
if (scriptIn.getPosition() < this.getPosition()) {
return after;
}
diff --git
a/java/code/src/com/redhat/rhn/frontend/action/kickstart/KickstartScriptOrderAction.java
b/java/code/src/com/redhat/rhn/frontend/action/kickstart/KickstartScriptOrderAction.java
new file mode 100644
index 0000000..ef6c008
--- /dev/null
+++
b/java/code/src/com/redhat/rhn/frontend/action/kickstart/KickstartScriptOrderAction.java
@@ -0,0 +1,236 @@
+/**
+ * Copyright (c) 2009--2010 Red Hat, Inc.
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ *
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+package com.redhat.rhn.frontend.action.kickstart;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.DynaActionForm;
+import org.apache.struts.util.LabelValueBean;
+
+import com.redhat.rhn.common.db.datasource.DataResult;
+import com.redhat.rhn.common.hibernate.HibernateFactory;
+import com.redhat.rhn.domain.kickstart.KickstartData;
+import com.redhat.rhn.domain.kickstart.KickstartFactory;
+import com.redhat.rhn.domain.kickstart.KickstartScript;
+import
com.redhat.rhn.domain.org.Org;
+import com.redhat.rhn.frontend.struts.RequestContext;
+import com.redhat.rhn.frontend.struts.RhnHelper;
+import com.redhat.rhn.frontend.struts.RhnLookupDispatchAction;
+import com.redhat.rhn.frontend.taglibs.list.ListTagHelper;
+import com.redhat.rhn.manager.kickstart.KickstartLister;
+
+/**
+ * KickstartScriptCreateAction action for creating a new kickstart script
+ * @version $Rev: 1 $
+ */
+public class KickstartScriptOrderAction extends RhnLookupDispatchAction {
+
+ static final String PRE_SCRIPTS = "preScripts";
+ static final String POST_SCRIPTS = "postScripts";
+ static final String SELECTED_PRE = "selectedPre";
+ static final String SELECTED_POST = "selectedPost";
+ static final String RANKED_PRE = "rankedPreValues";
+ static final String RANKED_POST = "rankedPostValues";
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public ActionForward handleNoScript(ActionMapping mapping, ActionForm formIn,
+ HttpServletRequest request, HttpServletResponse response) {
+ RequestContext rctx = new RequestContext(request);
+
+ if (!rctx.isJavaScriptEnabled()) {
+
getStrutsDelegate().saveMessage("common.config.rank.jsp.error.nojavascript",
+ request);
+ }
+
+ setup((DynaActionForm) formIn, rctx);
+
+ return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
+ }
+
+ protected void setup(DynaActionForm formIn, RequestContext rctx) {
+ Org org = rctx.getCurrentUser().getOrg();
+ KickstartData ksdata = KickstartFactory.lookupKickstartDataByIdAndOrg(org,
+ rctx.getRequiredParam(RequestContext.KICKSTART_ID));
+ DataResult<KickstartScript> dataSet = getDataResult(ksdata.getId(), org);
+
+ List<LabelValueBean> preScripts = new ArrayList<LabelValueBean>();
+ List<LabelValueBean> postScripts = new ArrayList<LabelValueBean>();
+ for (KickstartScript ks : dataSet) {
+ if (ks.getScriptType().equals(KickstartScript.TYPE_PRE)) {
+ preScripts.add(lv(ks.getScriptName(), ks.getPosition().toString()));
+ }
+ else {
+ postScripts.add(lv(ks.getScriptName(), ks.getPosition().toString()));
+ }
+ }
+ if (!preScripts.isEmpty()) {
+ if (StringUtils.isEmpty((String) formIn.get(SELECTED_PRE))) {
+ String selected = ((LabelValueBean) preScripts.get(0)).getLabel();
+ formIn.set(SELECTED_PRE, selected);
+ }
+ }
+ if (!postScripts.isEmpty()) {
+ if (StringUtils.isEmpty((String) formIn.get(SELECTED_POST))) {
+ String selected = ((LabelValueBean) postScripts.get(0)).getLabel();
+ formIn.set(SELECTED_POST, selected);
+ }
+ }
+
+ rctx.getRequest().setAttribute(ListTagHelper.PARENT_URL,
+ rctx.getRequest().getRequestURI());
+ formIn.set(PRE_SCRIPTS, preScripts);
+ formIn.set(POST_SCRIPTS, postScripts);
+ rctx.getRequest().setAttribute(RequestContext.KICKSTART, ksdata);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ protected DataResult<KickstartScript> getDataResult(Long ksid, Org org) {
+ return KickstartLister.getInstance().scriptsInKickstartWithFakeEntry(org, ksid);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected Map<String, String> getKeyMethodMap() {
+ Map<String, String> keys = new HashMap<String, String>();
+ keys.put("kickstartscript.order.update", "update");
+ keys.put("ssm.config.rank.jsp.up", "handleNoScript");
+ keys.put("ssm.config.rank.jsp.down", "handleNoScript");
+ return keys;
+ }
+
+ /**
+ * Updates the set and then applies changes to the server
+ * @param mapping struts ActionMapping
+ * @param formIn struts ActionForm
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @return An action forward to the success page
+ */
+ public ActionForward update(ActionMapping mapping, ActionForm formIn,
+ HttpServletRequest request, HttpServletResponse response) {
+ RequestContext context = new RequestContext(request);
+ Org org = context.getCurrentUser().getOrg();
+ KickstartData ksdata = KickstartFactory.lookupKickstartDataByIdAndOrg(org,
+ context.getRequiredParam(RequestContext.KICKSTART_ID));
+ DynaActionForm form = (DynaActionForm) formIn;
+ // if its not javascript enabled, can't do much report error
+ if (!context.isJavaScriptEnabled()) {
+ return handleNoScript(mapping, (DynaActionForm) formIn, request, response);
+ }
+
+ Set<KickstartScript> scripts = ksdata.getScripts();
+
+ List<String> orderedPrePriorities = getScriptPriority(form, RANKED_PRE);
+ List<String> orderedPostPriorities = getScriptPriority(form, RANKED_POST);
+ Map<Long, Long> oldToNew = new HashMap<Long, Long>();
+
+ Long nextPosition = 1L;
+ Long nextNegativePosition = -1L;
+ boolean beforeRedHat = true;
+
+ // map the old priorities to the new updated ones
+ for (String pre : orderedPrePriorities) {
+ Long oldPriority = Long.parseLong(pre);
+ oldToNew.put(oldPriority, nextPosition);
+ nextPosition += 1;
+ }
+ for (String post : orderedPostPriorities) {
+ Long oldPriority = Long.parseLong(post);
+ if (oldPriority == 0L) {
+ beforeRedHat = false;
+ continue;
+ }
+ if (beforeRedHat) {
+ oldToNew.put(oldPriority, nextNegativePosition);
+ nextNegativePosition -= 1;
+ }
+ else {
+ oldToNew.put(oldPriority, nextPosition);
+ nextPosition += 1;
+ }
+ }
+
+ // in order to avoid a db constraint error about two scripts having the same
+ // position, first we'll set them to something huge and then set them to the
+ // correct new value.
+ Map<Long, Long> fakeToOld = new HashMap<Long, Long>();
+ Long next = 10000L;
+ for (KickstartScript script : scripts) {
+ fakeToOld.put(next, script.getPosition());
+ script.setPosition(next);
+ next += 1;
+ HibernateFactory.getSession().save(script);
+ }
+ KickstartFactory.saveKickstartData(ksdata);
+
+ // update scripts with the appropriate priorities
+ for (KickstartScript script : scripts) {
+ script.setPosition(oldToNew.get(fakeToOld.get(script.getPosition())));
+ }
+
+ getStrutsDelegate().saveMessage("kickstart.script.order.success",
request);
+ return
getStrutsDelegate().forwardParam(mapping.findForward("success"),
+ RequestContext.KICKSTART_ID, ksdata.getId().toString());
+ }
+
+ /**
+ * Returns the position ranking info retrieved after one
+ * has clicked Update button.
+ * @param form the submitted form.
+ * @param preOrPost either
+ * @return List containing the channel ids in the order of
+ * their new rankings.
+ */
+ protected List<String> getScriptPriority(DynaActionForm form, String preOrPost)
{
+ List<String> scripts = new ArrayList<String>();
+ String rankedValues = (String) form.get(preOrPost);
+ if (StringUtils.isNotBlank(rankedValues)) {
+ String[] values = rankedValues.split(",");
+ for (String value : values) {
+ scripts.add(value);
+ }
+ }
+ return scripts;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ActionForward unspecified(ActionMapping mapping, ActionForm form,
+ HttpServletRequest request, HttpServletResponse response) {
+ RequestContext context = new RequestContext(request);
+ setup((DynaActionForm) form, context);
+ return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
+ }
+
+}
diff --git
a/java/code/src/com/redhat/rhn/frontend/action/kickstart/ScriptsSetupAction.java
b/java/code/src/com/redhat/rhn/frontend/action/kickstart/ScriptsSetupAction.java
index f77121d..88895c2 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/kickstart/ScriptsSetupAction.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/kickstart/ScriptsSetupAction.java
@@ -14,42 +14,56 @@
*/
package com.redhat.rhn.frontend.action.kickstart;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.domain.kickstart.KickstartData;
import com.redhat.rhn.domain.kickstart.KickstartFactory;
+import com.redhat.rhn.domain.kickstart.KickstartScript;
import
com.redhat.rhn.domain.org.Org;
-import com.redhat.rhn.frontend.listview.PageControl;
-import com.redhat.rhn.frontend.struts.BaseListAction;
import com.redhat.rhn.frontend.struts.RequestContext;
+import com.redhat.rhn.frontend.struts.RhnAction;
+import com.redhat.rhn.frontend.struts.RhnHelper;
+import com.redhat.rhn.frontend.taglibs.list.ListTagHelper;
import com.redhat.rhn.manager.kickstart.KickstartLister;
/**
* KickstartsSetupAction.
* @version $Rev: 1 $
*/
-public class ScriptsSetupAction extends BaseListAction {
+public class ScriptsSetupAction extends RhnAction {
+
+ static final String LIST_NAME = "kickstart_scripts";
/**
*
* {@inheritDoc}
*/
- protected DataResult getDataResult(RequestContext rctx, PageControl pc) {
- Long ksid = rctx.getRequiredParam(RequestContext.KICKSTART_ID);
+ public ActionForward execute(ActionMapping mapping, ActionForm formIn,
+ HttpServletRequest request, HttpServletResponse response) {
+ RequestContext rctx = new RequestContext(request);
Org org = rctx.getCurrentUser().getOrg();
- return KickstartLister.getInstance().scriptsInKickstart(org, ksid, pc);
+ KickstartData ksdata = KickstartFactory.lookupKickstartDataByIdAndOrg(org,
+ rctx.getRequiredParam(RequestContext.KICKSTART_ID));
+ DataResult<KickstartScript> dataSet = getDataResult(ksdata.getId(), org);
+
+ request.setAttribute(ListTagHelper.PARENT_URL, request.getRequestURI());
+ request.setAttribute(LIST_NAME, dataSet);
+ request.setAttribute(RequestContext.KICKSTART, ksdata);
+
+ return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
}
/**
*
* {@inheritDoc}
*/
- protected void processRequestAttributes(RequestContext rctx) {
- super.processRequestAttributes(rctx);
-
- KickstartData ksdata = KickstartFactory
- .lookupKickstartDataByIdAndOrg(rctx.getCurrentUser().getOrg(),
- rctx.getRequiredParam(RequestContext.KICKSTART_ID));
- rctx.getRequest().setAttribute(RequestContext.KICKSTART, ksdata);
+ protected DataResult<KickstartScript> getDataResult(Long ksid, Org org) {
+ return KickstartLister.getInstance().scriptsInKickstartWithFakeEntry(org, ksid);
}
-
}
diff --git a/java/code/src/com/redhat/rhn/frontend/dto/kickstart/ScriptDto.java
b/java/code/src/com/redhat/rhn/frontend/dto/kickstart/ScriptDto.java
deleted file mode 100644
index 3e2fbeb..0000000
--- a/java/code/src/com/redhat/rhn/frontend/dto/kickstart/ScriptDto.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Copyright (c) 2009--2012 Red Hat, Inc.
- *
- * This software is licensed to you under the GNU General Public License,
- * version 2 (GPLv2). There is NO WARRANTY for this software, express or
- * implied, including the implied warranties of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
- * along with this software; if not, see
- *
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
- */
-package com.redhat.rhn.frontend.dto.kickstart;
-
-import com.redhat.rhn.common.localization.LocalizationService;
-import com.redhat.rhn.frontend.dto.BaseDto;
-
-import org.apache.commons.lang.StringUtils;
-
-/**
- * DTO for a com.redhat.rhn.domain.kickstart.KickStartScript
- * @version $Rev: 50942 $
- */
-public class ScriptDto extends BaseDto {
-
- private Long id;
- private String scriptType;
- private String chroot;
- private String interpreter;
- private int position;
- private String scriptName;
- private static final String BASH = "bash";
- private static final String PRE = "Pre";
- private static final String POST = "Post";
- private static final String CHROOTPOST = "Nochroot Post";
-
- /**
- *
- * @return scriptName
- */
- public String getScriptName() {
- return scriptName;
- }
-
- /**
- *
- * @param scriptNameIn to set
- */
- public void setScriptName(String scriptNameIn) {
- this.scriptName = scriptNameIn;
- }
-
- /**
- *
- * @return chroot
- */
- public String getChroot() {
- return chroot;
- }
-
- /**
- *
- * @param chrootIn to set
- */
- public void setChroot(String chrootIn) {
- this.chroot = chrootIn;
- }
-
- /**
- *
- * {@inheritDoc}
- */
- public Long getId() {
- return id;
- }
-
- /**
- *
- * @param idIn to set
- */
- public void setId(Long idIn) {
- this.id = idIn;
- }
-
- /**
- *
- * @return interpreter for this script
- */
- public String getInterpreter() {
- if (StringUtils.isBlank(interpreter)) {
- return BASH;
- }
- return interpreter;
- }
-
- /**
- *
- * @param interpreterIn to set
- */
- public void setInterpreter(String interpreterIn) {
- this.interpreter = interpreterIn;
- }
-
- /**
- *
- * @return script type for this script
- */
- public String getScriptType() {
- if (scriptType.equals("post")) {
- if (this.chroot.toLowerCase().equals("n")) {
- return CHROOTPOST;
- }
- return POST;
- }
- return PRE;
- }
-
- /**
- *
- * @param scriptTypeIn to set
- */
- public void setScriptType(String scriptTypeIn) {
- this.scriptType = scriptTypeIn;
- }
-
- /**
- *
- * @return position in listview
- */
- public String getPosition() {
- return LocalizationService.getInstance().formatNumber(new Integer(position));
- }
-
- /**
- *
- * @param positionIn to set
- */
- public void setPosition(int positionIn) {
- this.position = positionIn;
- }
-
-}
diff --git a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
index 27c217e..827d626 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
@@ -5637,6 +5637,24 @@ Follow this url to see the full list of inactive systems:
<context
context-type="sourcefile">/rhn/kickstart/KickstartScriptEdit.do</context>
</context-group>
</trans-unit>
+ <trans-unit id="kickstart.script.order.fakename">
+ <source>Registration and server actions</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts.do</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstart.script.order.fakeinterpreter">
+ <source>Not Applicable</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts.do</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstart.script.order.success">
+ <source>Kickstart Script order was successfully updated.</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts.do</context>
+ </context-group>
+ </trans-unit>
<trans-unit id="listdisplaytag.viewall">
<source>View All</source>
<context-group name="ctx">
diff --git a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
index 0a464b9..b60ae43 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
@@ -8820,7 +8820,7 @@ Please note that some manual configuration of these scripts may
still be require
</context-group>
</trans-unit>
<trans-unit id="kickstartscript.jsp.summary2">
- <source>You may view or edit the scripts for this kickstart below. You may
add a new script using the add new kickstart script button above to the
right.</source>
+ <source>You may view or edit the scripts for this kickstart below. You may
add a new script or order the existing scripts using links above to the
right.</source>
<context-group name="ctx">
<context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
</context-group>
@@ -8831,6 +8831,42 @@ Please note that some manual configuration of these scripts may
still be require
<context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
</context-group>
</trans-unit>
+ <trans-unit id="kickstartscript.order.header">
+ <source>Update kickstart script order</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/KickstartScriptOrder</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstartscript.order.summary">
+ <source>You can update the order that your kickstart scripts will run in by
changing the order below. Pre scripts will always run before the installation happens, and
Post scripts will always run afterwards.</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstartscript.order.prescripts">
+ <source>Pre Scripts</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstartscript.order.postscripts">
+ <source>Post Scripts</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstartscript.order.update">
+ <source>Update Order</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="kickstartscript.order.noscript">
+ <source><strong>Warning:</strong> Javascript is
required for the kickstart script ordering to succeed. Please enable Javascript in order
to continue.</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/kickstart/Scripts</context>
+ </context-group>
+ </trans-unit>
<trans-unit id="kickstartips.jsp.baremetal_summary">
<source><p> In order to kickstart "bare metal
systems", you will need to provide them with a boot image that is compatible with the
version of the operating system you are kickstarting to via boot CD. </p>
<p> Once these systems have booted using the appropriate image, you will
need to provide a kickstart file. You may use the following URL in your Boot CD or in your
PXE configuration to provide these systems with the kickstart file associated with this
kickstart profile:</p></source>
<context-group name="ctx">
@@ -9582,6 +9618,18 @@ Please note that some manual configuration of these scripts may
still be require
<context
context-type="sourcefile">/rhn/systems/provisioning/preservation/PreservationList.do</context>
</context-group>
</trans-unit>
+ <trans-unit id="toolbar.misc.kickstartscript">
+ <source>order kickstart scripts</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/systems/provisioning/preservation/PreservationList.do</context>
+ </context-group>
+ </trans-unit>
+ <trans-unit id="toolbar.misc.kickstartscriptalt">
+ <source>Change the order kickstart scripts run in.</source>
+ <context-group name="ctx">
+ <context
context-type="sourcefile">/rhn/systems/provisioning/preservation/PreservationList.do</context>
+ </context-group>
+ </trans-unit>
<trans-unit id="preservationlist.jsp.updatelist">
<source>Update List</source>
<context-group name="ctx">
diff --git
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/kickstart/profile/ProfileHandler.java
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/kickstart/profile/ProfileHandler.java
index 6e1b5c6..e1e6f14 100644
--- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/kickstart/profile/ProfileHandler.java
+++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/kickstart/profile/ProfileHandler.java
@@ -64,6 +64,7 @@ import org.cobbler.Profile;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -389,12 +390,14 @@ public class ProfileHandler extends BaseHandler {
}
/**
- * List the pre and post scripts for a kickstart profile.
+ * List the pre and post scripts for a kickstart profile in the order
+ * they will run.
* @param sessionKey key
* @param label the kickstart label
* @return list of kickstartScript objects
*
- * @xmlrpc.doc List the pre and post scripts for a kickstart profile.
+ * @xmlrpc.doc List the pre and post scripts for a kickstart profile
+ * in the order they will run.
* profile
* @xmlrpc.param #session_key()
* @xmlrpc.param #param_desc("string", "ksLabel", "The label
of the
@@ -406,8 +409,121 @@ public class ProfileHandler extends BaseHandler {
checkKickstartPerms(loggedInUser);
KickstartData data = lookupKsData(label, loggedInUser.getOrg());
- return new ArrayList<KickstartScript>(data.getScripts());
+ ArrayList<KickstartScript> scripts = new ArrayList<KickstartScript>(
+ data.getScripts());
+ Collections.sort(scripts);
+ return scripts;
+
+ }
+
+ /**
+ * Change the order that kickstart scripts will run for this kickstart
+ * profile. Scripts will run in the order they appear in the array.
+ * There are three arrays, one for all pre scripts, one for the post
+ * scripts that run before registration and server actions happen,
+ * and one for post scripts that run after registration and server
+ * actinos. All scripts must be included in one of these lists, as
+ * appropriate.
+ * @param sessionKey key
+ * @param ksLabel the kickstart label
+ * @param preScripts the ordered list of pre scripts
+ * @param postScriptsBeforeRegistration the ordered list of post
+ * scripts that run before registration
+ * @param postScriptsAfterRegistration the ordered list of post
+ * scripts that run after registration
+ * @return 1 on success
+ *
+ * @xmlrpc.doc Change the order that kickstart scripts will run for
+ * this kickstart profile. Scripts will run in the order they appear
+ * in the array. There are three arrays, one for all pre scripts, one
+ * for the post scripts that run before registration and server
+ * actions happen, and one for post scripts that run after registration
+ * and server actions. All scripts must be included in one of these
+ * lists, as appropriate.
+ * @xmlrpc.param #session_key()
+ * @xmlrpc.param #param_desc("string", "ksLabel", "The label
of the
+ * kickstart")
+ * @xmlrpc.param #array_single("int",
+ * "IDs of the ordered pre scripts")
+ * @xmlrpc.param #array_single("int",
+ * "IDs of the ordered post scripts that will run
+ * before registration")
+ * @xmlrpc.param #array_single("int",
+ * "IDs of the ordered post scripts that will run
+ * after registration")
+ * @xmlrpc.returntype #return_int_success()
+ */
+ public int orderScripts(String sessionKey, String ksLabel, List<Integer>
preScripts,
+ List<Integer> postScriptsBeforeRegistration,
+ List<Integer> postScriptsAfterRegistration) {
+ User loggedInUser = getLoggedInUser(sessionKey);
+ checkKickstartPerms(loggedInUser);
+ KickstartData data = lookupKsData(ksLabel, loggedInUser.getOrg());
+ if (data == null) {
+ throw new FaultException(-3, "kickstartProfileNotFound",
+ "No Kickstart Profile found with label: " + ksLabel);
+ }
+ Set<KickstartScript> scripts = data.getScripts();
+
+ // validate the input
+ List<KickstartScript> myPreScripts = new
ArrayList<KickstartScript>();
+ List<KickstartScript> myPostScripts = new
ArrayList<KickstartScript>();
+ Map<Integer, KickstartScript> idToScript = new HashMap<Integer,
KickstartScript>();
+ for (KickstartScript script : scripts) {
+ idToScript.put(script.getId().intValue(), script);
+ if (script.getScriptType().equals(KickstartScript.TYPE_PRE)) {
+ myPreScripts.add(script);
+ if (!preScripts.contains(script.getId().intValue())) {
+ throw new IllegalArgumentException("Kickstart Script ID missing:
" +
+ script.getId());
+ }
+ }
+ else {
+ myPostScripts.add(script);
+ if (!(postScriptsBeforeRegistration.contains(script.getId().intValue())
||
+ postScriptsAfterRegistration.contains(
+ script.getId().intValue()))) {
+ throw new IllegalArgumentException("Kickstart Script ID missing:
" +
+ script.getId());
+ }
+ }
+ }
+ if (preScripts.size() != myPreScripts.size()) {
+ throw new IllegalArgumentException("Too many pre script IDs.");
+ }
+ if ((postScriptsBeforeRegistration.size() + postScriptsAfterRegistration.size()
!=
+ myPostScripts.size())) {
+ throw new IllegalArgumentException("Too many post script IDs.");
+ }
+
+ // To avoid db constraint error about two scripts having same position,
+ // make them something else
+ Long fakePosition = 10000L;
+ for (KickstartScript script : scripts) {
+ script.setPosition(fakePosition);
+ fakePosition += 1;
+ HibernateFactory.getSession().save(script);
+ }
+ KickstartFactory.saveKickstartData(data);
+
+ // create new position values
+ Long nextPosition = 1L;
+ Long nextNegativePosition = -1L;
+ for (Integer id : preScripts) {
+ idToScript.get(id).setPosition(nextPosition);
+ nextPosition += 1;
+ }
+ for (Integer id : postScriptsBeforeRegistration) {
+ idToScript.get(id).setPosition(nextNegativePosition);
+ nextNegativePosition -= 1;
+ }
+ for (Integer id : postScriptsAfterRegistration) {
+ idToScript.get(id).setPosition(nextPosition);
+ nextPosition += 1;
+ }
+
+ return 1;
}
/**
diff --git
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/KickstartScriptSerializer.java
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/KickstartScriptSerializer.java
index 8fb2b46..cb51241 100755
---
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/KickstartScriptSerializer.java
+++
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/KickstartScriptSerializer.java
@@ -31,6 +31,7 @@ import com.redhat.rhn.frontend.xmlrpc.serializer.util.SerializerHelper;
* @xmlrpc.doc
* #struct("kickstart script")
* #prop("int", "id")
+ * #prop("string", "name")
* #prop("string", "contents")
* #prop_desc("string", "script_type", "Which type of
script ('pre' or 'post').")
* #prop_desc("string", "interpreter", "The scripting
language interpreter to use
@@ -41,6 +42,8 @@ import com.redhat.rhn.frontend.xmlrpc.serializer.util.SerializerHelper;
* #prop_desc("boolean", "erroronfail", "True if the
script will throw an error if
* it fails.")
* #prop_desc("boolean", "template", "True if
templating using cobbler is enabled")
+ * #prop_desc("boolean", "beforeRegistration", "True if
script will run before the
+ * server registers and performs server actions.")
* #struct_end()
*/
public class KickstartScriptSerializer extends RhnXmlRpcCustomSerializer {
@@ -62,6 +65,7 @@ public class KickstartScriptSerializer extends RhnXmlRpcCustomSerializer
{
SerializerHelper helper = new SerializerHelper(serializer);
helper.add("id", script.getId());
+ helper.add("name", script.getScriptName());
helper.add("contents", script.getDataContents());
helper.add("script_type", script.getScriptType());
@@ -83,6 +87,11 @@ public class KickstartScriptSerializer extends
RhnXmlRpcCustomSerializer {
helper.add("template", !script.getRaw());
+ helper.add(
+ "beforeRegistration",
+ script.getScriptType().equals(KickstartScript.TYPE_PRE) ||
+ script.getPosition() < 0L);
+
helper.writeTo(output);
}
}
diff --git a/java/code/src/com/redhat/rhn/manager/kickstart/KickstartFormatter.java
b/java/code/src/com/redhat/rhn/manager/kickstart/KickstartFormatter.java
index 4e53948..75dfbfa 100644
--- a/java/code/src/com/redhat/rhn/manager/kickstart/KickstartFormatter.java
+++ b/java/code/src/com/redhat/rhn/manager/kickstart/KickstartFormatter.java
@@ -170,6 +170,8 @@ public class KickstartFormatter {
private final String ksHost;
private final User user;
private KickstartSession session;
+ private int postLogPostfix;
+ private int preLogPostfix;
/**
* constructor
@@ -181,6 +183,8 @@ public class KickstartFormatter {
this.ksdata = ksdataIn;
this.ksHost = hostIn;
this.user = UserFactory.findRandomOrgAdmin(this.ksdata.getOrg());
+ this.postLogPostfix = 1;
+ this.preLogPostfix = 1;
}
/**
@@ -233,6 +237,22 @@ public class KickstartFormatter {
*/
public String getFileData() {
RegistrationType regType = ksdata.getRegistrationType(user);
+ List<KickstartScript> l = new
LinkedList<KickstartScript>(this.ksdata.getScripts());
+ Collections.sort(l);
+ List<KickstartScript> preScripts = new ArrayList<KickstartScript>();
+ List<KickstartScript> postBeforeRedHatScripts = new
ArrayList<KickstartScript>();
+ List<KickstartScript> postAfterRedHatScripts = new
ArrayList<KickstartScript>();
+ for (KickstartScript ks : l) {
+ if (ks.getScriptType().equals(KickstartScript.TYPE_PRE)) {
+ preScripts.add(ks);
+ }
+ else if (ks.getPosition() < 0L) {
+ postBeforeRedHatScripts.add(ks);
+ }
+ else {
+ postAfterRedHatScripts.add(ks);
+ }
+ }
StringBuilder buf = new StringBuilder();
buf.append(getHeader());
buf.append(getCommands());
@@ -271,9 +291,18 @@ public class KickstartFormatter {
addEnd(buf);
}
- buf.append(getPrePost(KickstartScript.TYPE_PRE));
+ buf.append(renderScripts(preScripts));
buf.append(NEWLINE);
- buf.append(getNoChroot());
+
+ // This script should always be the first post script to run
+ buf.append("%" + KickstartScript.TYPE_POST + SPACE + NOCHROOT +
NEWLINE);
+ buf.append(RHN_NOCHROOT + NEWLINE);
+ if (this.ksdata.getKsCfg()) {
+ buf.append(SAVE_KS_CFG + NEWLINE);
+ }
+ addEnd(buf);
+
+ buf.append(renderScripts(postBeforeRedHatScripts));
buf.append(NEWLINE);
if (RegistrationType.REACTIVATION.equals(regType)) {
@@ -288,7 +317,7 @@ public class KickstartFormatter {
buf.append(NEWLINE);
buf.append(getRhnPost());
buf.append(NEWLINE);
- buf.append(getPrePost(KickstartScript.TYPE_POST));
+ buf.append(renderScripts(postAfterRedHatScripts));
buf.append(NEWLINE);
buf.append("%" + KickstartScript.TYPE_POST); //new %post for last
kernel stuff
addCobblerSnippet(buf, "post_install_kernel_options");
@@ -343,7 +372,7 @@ public class KickstartFormatter {
LinkedList l = new LinkedList(this.ksdata.getCommands());
Collections.sort(l);
for (Iterator itr = l.iterator(); itr.hasNext();) {
- KickstartCommand command = (KickstartCommand)itr.next();
+ KickstartCommand command = (KickstartCommand) itr.next();
String cname = command.getCommandName().getName();
log.debug("getCommands name: " + cname);
@@ -532,8 +561,8 @@ public class KickstartFormatter {
*/
private String getPackages() {
StringBuffer buf = new StringBuffer();
- for (Iterator itr = ksdata.getKsPackages().iterator(); itr.hasNext();) {
- buf.append(((KickstartPackage)itr.next()).getPackageName().getName() +
NEWLINE);
+ for (KickstartPackage kp : ksdata.getKsPackages()) {
+ buf.append(kp.getPackageName().getName() + NEWLINE);
}
if (KickstartVirtualizationType.paraHost().equals(ksdata.getKickstartDefaults().
getVirtualizationType())) {
@@ -550,123 +579,69 @@ public class KickstartFormatter {
}
/**
- * @param typeIn type of script to render (pre or post)
+ * @param scrupts the kickstart scripts we want to render
* @return rendered script(s)
*/
- private String getPrePost(String typeIn) {
+ private String renderScripts(List<KickstartScript> scripts) {
StringBuilder retval = new StringBuilder();
- if (this.ksdata.getScripts() != null) {
- List<KickstartScript> l =
- new LinkedList<KickstartScript>(this.ksdata.getScripts());
- Collections.sort(l);
- Iterator<KickstartScript> i = l.iterator();
- for (KickstartScript kss : l) {
-
- // render either pre or chroot posts
- if (kss.getScriptType().equals(typeIn)) {
- if (typeIn.equals(KickstartScript.TYPE_PRE) ||
- (typeIn.equals(KickstartScript.TYPE_POST) &&
- (kss.getChroot().equals("Y")))) {
- retval.append(NEWLINE);
- if (kss.getRaw()) {
- retval.append(RAW_START + NEWLINE);
- }
- String command = "%" + typeIn;
- if (kss.getErrorOnFail()) {
- command += SPACE + ERRORONFAIL;
- }
- if (!StringUtils.isBlank(kss.getInterpreter())) {
- command += SPACE + INTERPRETER_OPT + SPACE +
- kss.getInterpreter();
- }
- retval.append(command);
- if (typeIn.equals(KickstartScript.TYPE_POST) &&
- ksdata.getPostLog()) {
- addLogBegin(retval, POST_LOG_FILE + "." +
kss.getPosition(),
- kss.getInterpreter());
- }
- else if (typeIn.equals(KickstartScript.TYPE_PRE) &&
- ksdata.getPreLog()) {
- addLogBegin(retval, PRE_LOG_FILE + "." +
kss.getPosition(),
- kss.getInterpreter());
- }
- else {
- retval.append(NEWLINE);
- }
- retval.append(kss.getDataContents() + NEWLINE);
-
- if (typeIn.equals(KickstartScript.TYPE_POST) &&
- ksdata.getPostLog()) {
- addLogEnd(retval, POST_LOG_FILE + "." +
kss.getPosition(),
- kss.getInterpreter());
- }
- else if (typeIn.equals(KickstartScript.TYPE_PRE) &&
- ksdata.getPreLog()) {
- addLogEnd(retval, PRE_LOG_FILE + "." +
kss.getPosition(),
- kss.getInterpreter());
- }
- if (kss.getRaw()) {
- retval.append(RAW_END + NEWLINE);
- }
- addEnd(retval);
- }
- } // end script type and chroot = y
+ for (KickstartScript kss : scripts) {
+ boolean isPre = kss.getScriptType().equals(KickstartScript.TYPE_PRE);
- } // end iterator
- } // end if have scripts
- return retval.toString();
- }
-
- /**
- *
- * @return string containing nochroot post contents
- */
- private String getNoChroot() {
- StringBuilder retval = new StringBuilder();
- if (this.ksdata.getScripts() != null) {
- retval.append("%" + KickstartScript.TYPE_POST + SPACE +
- NOCHROOT + NEWLINE);
- retval.append(RHN_NOCHROOT + NEWLINE);
- if (this.ksdata.getKsCfg()) {
- retval.append(SAVE_KS_CFG + NEWLINE);
+ retval.append(NEWLINE);
+ if (kss.getRaw()) {
+ retval.append(RAW_START + NEWLINE);
+ }
+ String command = "%" + kss.getScriptType();
+ if (!isPre && !kss.thisScriptIsChroot()) {
+ command += SPACE + NOCHROOT;
+ }
+ if (kss.getErrorOnFail()) {
+ command += SPACE + ERRORONFAIL;
+ }
+ if (!StringUtils.isBlank(kss.getInterpreter())) {
+ command += SPACE + INTERPRETER_OPT + SPACE + kss.getInterpreter();
+ }
+ retval.append(command);
+ if (ksdata.getPreLog() && isPre) {
+ addLogBegin(retval, PRE_LOG_FILE + "." + this.preLogPostfix,
+ kss.getInterpreter());
+ }
+ else if (ksdata.getPostLog() && !isPre &&
kss.thisScriptIsChroot()) {
+ addLogBegin(retval, POST_LOG_FILE + "." + this.postLogPostfix,
+ kss.getInterpreter());
+ }
+ else if (ksdata.getNonChrootPost() && !isPre &&
!kss.thisScriptIsChroot()) {
+ addLogBegin(retval, POST_LOG_NOCHROOT_FILE + "." +
this.postLogPostfix,
+ kss.getInterpreter());
+ retval.append(RHN_TRACE);
+ }
+ else {
+ retval.append(NEWLINE);
}
- addEnd(retval);
- for (KickstartScript kss : this.ksdata.getScripts()) {
- if (kss.getScriptType().equals(KickstartScript.TYPE_POST) &&
- kss.getChroot().equals("N")) {
- // Put a blank line in between the scripts
- retval.append(NEWLINE);
- String scriptCommand = "%" + KickstartScript.TYPE_POST +
SPACE +
- NOCHROOT;
- if (kss.getErrorOnFail()) {
- scriptCommand += SPACE + ERRORONFAIL;
- }
- String kssInterpreter = kss.getInterpreter();
- if (!StringUtils.isBlank(kssInterpreter)) {
- scriptCommand += SPACE + INTERPRETER_OPT + SPACE +
- kssInterpreter;
- }
- retval.append(scriptCommand);
-
- if (ksdata.getNonChrootPost()) {
- addLogBegin(retval, POST_LOG_NOCHROOT_FILE + "." +
- kss.getPosition(), kssInterpreter);
- if (isBashInterpreter(kssInterpreter)) {
- retval.append(RHN_TRACE);
- }
- }
- retval.append(NEWLINE);
- retval.append(kss.getDataContents() + NEWLINE);
- if (ksdata.getNonChrootPost()) {
- addLogEnd(retval, POST_LOG_NOCHROOT_FILE + "." +
kss.getPosition(),
- kssInterpreter);
- }
- addEnd(retval);
- }
- } // end iterator
- } // end if we have scripts to process
+ retval.append(kss.getDataContents() + NEWLINE);
+ if (ksdata.getPreLog() && isPre) {
+ addLogEnd(retval, PRE_LOG_FILE + "." + kss.getPosition(),
+ kss.getInterpreter());
+ this.preLogPostfix += 1;
+ }
+ else if (ksdata.getPostLog() && !isPre &&
kss.thisScriptIsChroot()) {
+ addLogEnd(retval, POST_LOG_FILE + "." + this.postLogPostfix,
+ kss.getInterpreter());
+ this.postLogPostfix += 1;
+ }
+ else if (ksdata.getNonChrootPost() && !isPre &&
!kss.thisScriptIsChroot()) {
+ addLogEnd(retval, POST_LOG_NOCHROOT_FILE + "." +
this.postLogPostfix,
+ kss.getInterpreter());
+ this.postLogPostfix += 1;
+ }
+
+ if (kss.getRaw()) {
+ retval.append(RAW_END + NEWLINE);
+ }
+ addEnd(retval);
+ } // end loop
return retval.toString();
}
@@ -914,9 +889,9 @@ public class KickstartFormatter {
*
* @return list of packages we need to up2date
*/
- private HashSet getUpdatePackages(List<ActivationKey> keys) {
+ private HashSet<String> getUpdatePackages(List<ActivationKey> keys) {
log.debug("getUpdatePackages() ..");
- HashSet retval = new HashSet();
+ HashSet<String> retval = new HashSet<String>();
Channel c = ksdata.getKickstartDefaults().getKstree().getChannel();
for (ActivationKey key : keys) {
if (key.getChannels() != null) {
@@ -960,37 +935,35 @@ public class KickstartFormatter {
*
* @return list of optional packages we need to up2date to the latest nvr
*/
- private HashSet getFreshPackages(List<ActivationKey> keys) {
-
- Channel c = ksdata.getKickstartDefaults().getKstree().getChannel();
- for (ActivationKey key : keys) {
- for (Channel chan : key.getChannels()) {
- if (chan.isBaseChannel()) {
- c = chan;
- break;
- }
+ private HashSet<String> getFreshPackages(List<ActivationKey> keys) {
+ Channel c = ksdata.getKickstartDefaults().getKstree().getChannel();
+ for (ActivationKey key : keys) {
+ for (Channel chan : key.getChannels()) {
+ if (chan.isBaseChannel()) {
+ c = chan;
+ break;
}
}
+ }
- String [] pkglist = {};
- if (ksdata.isRhel2()) {
- pkglist = FRESH_PKG_NAMES_RHEL2;
- }
- else if (ksdata.isRhel3() || ksdata.isRhel4()) {
- pkglist = FRESH_PKG_NAMES_RHEL34;
- }
- HashSet retval = new HashSet();
- for (int i = 0; i < pkglist.length; i++) {
- Long packageId = ChannelManager.getLatestPackageEqualInTree(c.getId(),
- pkglist[i]);
- if (packageId != null) {
- Package p = PackageFactory.lookupByIdAndUser(packageId, user);
- if (p != null) {
- retval.add(getSHA1PackagePath(p));
- }
+ String[] pkglist = {};
+ if (ksdata.isRhel2()) {
+ pkglist = FRESH_PKG_NAMES_RHEL2;
+ }
+ else if (ksdata.isRhel3() || ksdata.isRhel4()) {
+ pkglist = FRESH_PKG_NAMES_RHEL34;
+ }
+ HashSet<String> retval = new HashSet<String>();
+ for (String pkg : pkglist) {
+ Long packageId = ChannelManager.getLatestPackageEqualInTree(c.getId(), pkg);
+ if (packageId != null) {
+ Package p = PackageFactory.lookupByIdAndUser(packageId, user);
+ if (p != null) {
+ retval.add(getSHA1PackagePath(p));
}
}
- return retval;
+ }
+ return retval;
}
/**
@@ -998,12 +971,11 @@ public class KickstartFormatter {
* @param setIn of gpg keys for this kickstart
* @return rendered gpg key string for kickstart
*/
- private String renderGpgKeys(HashSet setIn) {
+ private String renderGpgKeys(HashSet<CryptoKey> setIn) {
StringBuffer retval = new StringBuffer();
int peg = 1;
- for (Iterator itr = setIn.iterator(); itr.hasNext();) {
+ for (CryptoKey myKey : setIn) {
retval.append("cat > /tmp/gpg-key-" + peg + "
<<'EOF'" + NEWLINE);
- CryptoKey myKey = (CryptoKey)itr.next();
retval.append(myKey.getKeyString() + NEWLINE);
retval.append("EOF\n# gpg-key" + peg + NEWLINE);
if (this.ksdata.isRhel2()) {
diff --git a/java/code/src/com/redhat/rhn/manager/kickstart/KickstartLister.java
b/java/code/src/com/redhat/rhn/manager/kickstart/KickstartLister.java
index b35db1a..c7c3d86 100644
--- a/java/code/src/com/redhat/rhn/manager/kickstart/KickstartLister.java
+++ b/java/code/src/com/redhat/rhn/manager/kickstart/KickstartLister.java
@@ -17,7 +17,9 @@ package com.redhat.rhn.manager.kickstart;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.db.datasource.ModeFactory;
import com.redhat.rhn.common.db.datasource.SelectMode;
+import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.domain.kickstart.KickstartFactory;
+import com.redhat.rhn.domain.kickstart.KickstartScript;
import com.redhat.rhn.domain.kickstart.KickstartableTree;
import
com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.user.User;
@@ -49,6 +51,7 @@ import java.util.Set;
*/
public class KickstartLister extends BaseManager {
+ public static final String FAKE_SCRIPT_LABEL =
"kickstart.script.order.fakename";
/**
* Logger for this class
*/
@@ -126,25 +129,55 @@ public class KickstartLister extends BaseManager {
*
* @param orgIn Org coming in.
* @param ksIn Kickstart Id we want to fetch scripts for
- * @param pc PageControl
* @return the kickstart profiles for <code>orgIn</code>
*/
- public DataResult scriptsInKickstart(Org orgIn, Long ksIn, PageControl pc) {
-
+ public DataResult<KickstartScript> scriptsInKickstart(Org orgIn, Long ksIn) {
SelectMode m = ModeFactory.getMode("General_queries",
"scripts_for_kickstart");
- Map params = new HashMap();
+ Map<String, Object> params = new HashMap<String, Object>();
params.put("kickstart_id", ksIn);
params.put("org_id", orgIn.getId());
- Map elabParams = new HashMap();
- DataResult returnDataResult = makeDataResult(params, elabParams, pc, m);
+ Map<String, String> elabParams = new HashMap<String, String>();
+ DataResult<KickstartScript> returnDataResult =
makeDataResultNoPagination(params,
+ elabParams, m);
if (logger.isDebugEnabled()) {
- logger.debug("scriptsInKickstart(KS, PageControl) - end - return
value=" +
+ logger.debug("scriptsInKickstart(KS) - end - return value=" +
returnDataResult);
}
return returnDataResult;
}
/**
+ * List the kickstart scripts for a particular kickstart.
+ * Inserts a fake result to mark where the Red Hat registration
+ * and Server Actions will occur.
+ *
+ * @param orgIn Org coming in.
+ * @param ksIn Kickstart Id we want to fetch scripts for
+ * @return the kickstart profiles for <code>orgIn</code>
+ */
+ public DataResult<KickstartScript>
+ scriptsInKickstartWithFakeEntry(Org orgIn, Long ksIn) {
+ DataResult<KickstartScript> scripts = scriptsInKickstart(orgIn, ksIn);
+
+ KickstartScript fakeScript = new KickstartScript();
+ fakeScript.setPosition(0L);
+ fakeScript.setScriptType(KickstartScript.TYPE_POST);
+ fakeScript.setScriptName(LocalizationService.getInstance().getMessage(
+ FAKE_SCRIPT_LABEL));
+ fakeScript.setInterpreter(LocalizationService.getInstance().getMessage(
+ "kickstart.script.order.fakeinterpreter"));
+ fakeScript.setEditable(false);
+ fakeScript.setChroot("y");
+
+ if (scripts.size() != 0) {
+ scripts.add(fakeScript);
+ Collections.sort(scripts);
+ }
+
+ return scripts;
+ }
+
+ /**
* List the kickstart ip ranges in the Org.
* Returns the list of Maps with x fields: , , .
*
diff --git a/java/code/webapp/WEB-INF/pages/activationkeys/configuration/rank.jsp
b/java/code/webapp/WEB-INF/pages/activationkeys/configuration/rank.jsp
index aeb3852..3862b8f 100644
--- a/java/code/webapp/WEB-INF/pages/activationkeys/configuration/rank.jsp
+++ b/java/code/webapp/WEB-INF/pages/activationkeys/configuration/rank.jsp
@@ -6,7 +6,7 @@
<html:xhtml/>
<html>
<head>
-<script src="/javascript/config_channel_ranks.js"
type="text/javascript"></script>
+<script src="/javascript/rank_options.js"
type="text/javascript"></script>
</head>
<body>
<%@ include
file="/WEB-INF/pages/common/fragments/activationkeys/common-header.jspf" %>
@@ -42,7 +42,7 @@
<html:hidden property="dispatch"
value="${rhn:localize('sdc.config.rank.jsp.update')}"/>
<input type=submit name="dispatcher"
value="${rhn:localize('sdc.config.rank.jsp.update')}"
-
onclick="handle_config_channels_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
+
onclick="handle_ranking_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
</div>
</html:form>
</body>
diff --git
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/rankchannels.jspf
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/rankchannels.jspf
index cb5567b..7955f67 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/rankchannels.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/rankchannels.jspf
@@ -16,15 +16,15 @@
altKey="ssm.config.rank.jsp.up"
property="dispatch"
value="up"
- onclick="return config_channel_up('ranksWidget');"
+ onclick="return move_selected_up('ranksWidget');"
styleClass="button"/>
- <td></tr>
+ </td></tr>
<tr>
<td><html:image src="/img/button-down.gif"
altKey="ssm.config.rank.jsp.down"
property="dispatch"
value="down"
- onclick="return config_channel_down('ranksWidget');"
+ onclick="return move_selected_down('ranksWidget');"
styleClass="button"/>
</td></tr>
</table>
@@ -33,4 +33,4 @@
<html:hidden name="channelRanksForm"
property="rankedValues" styleId="rankedValues"/>
<rhn:noscript/>
-</td>
\ No newline at end of file
+</td>
diff --git a/java/code/webapp/WEB-INF/pages/configuration/sdc/rankchannels.jsp
b/java/code/webapp/WEB-INF/pages/configuration/sdc/rankchannels.jsp
index eed8245..031a4b0 100644
--- a/java/code/webapp/WEB-INF/pages/configuration/sdc/rankchannels.jsp
+++ b/java/code/webapp/WEB-INF/pages/configuration/sdc/rankchannels.jsp
@@ -6,7 +6,7 @@
<html:xhtml/>
<html>
<head>
-<script src="/javascript/config_channel_ranks.js"
type="text/javascript"></script>
+<script src="/javascript/rank_options.js"
type="text/javascript"></script>
</head>
<body>
<%@ include
file="/WEB-INF/pages/common/fragments/systems/system-header.jspf" %>
@@ -42,7 +42,7 @@
<html:hidden property="dispatch"
value="${rhn:localize('sdc.config.rank.jsp.update')}"/>
<input type=submit name="dispatcher"
value="${rhn:localize('sdc.config.rank.jsp.update')}"
-
onclick="handle_config_channels_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
+
onclick="handle_ranking_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
</div>
</html:form>
</body>
diff --git a/java/code/webapp/WEB-INF/pages/configuration/ssm/rankchannels.jsp
b/java/code/webapp/WEB-INF/pages/configuration/ssm/rankchannels.jsp
index 324f7a4..afe2550 100644
--- a/java/code/webapp/WEB-INF/pages/configuration/ssm/rankchannels.jsp
+++ b/java/code/webapp/WEB-INF/pages/configuration/ssm/rankchannels.jsp
@@ -7,7 +7,7 @@
<html>
<head>
<script src="/javascript/prototype.js" type="text/javascript">
</script>
-<script src="/javascript/config_channel_ranks.js"
type="text/javascript"> </script>
+<script src="/javascript/rank_options.js"
type="text/javascript"> </script>
</head>
<body>
<%@ include file="/WEB-INF/pages/common/fragments/ssm/header.jspf"
%>
@@ -57,7 +57,7 @@
<html:hidden property="dispatch"
value="${rhn:localize('ssm.config.rank.jsp.apply')}"/>
<input type=submit name="dispatcher"
value="${rhn:localize('ssm.config.rank.jsp.apply')}"
-
onclick="handle_config_channels_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
+
onclick="handle_ranking_dispatch('ranksWidget','rankedValues','channelRanksForm');"/>
</div>
</html:form>
</body>
diff --git a/java/code/webapp/WEB-INF/pages/kickstart/scriptedit.jsp
b/java/code/webapp/WEB-INF/pages/kickstart/scriptedit.jsp
index 8e588c6..83decbd 100644
--- a/java/code/webapp/WEB-INF/pages/kickstart/scriptedit.jsp
+++ b/java/code/webapp/WEB-INF/pages/kickstart/scriptedit.jsp
@@ -2,6 +2,7 @@
<%@ taglib
uri="http://rhn.redhat.com/rhn" prefix="rhn" %>
<%@ taglib
uri="http://struts.apache.org/tags-bean" prefix="bean"
%>
<%@ taglib
uri="http://struts.apache.org/tags-html" prefix="html"
%>
+<%@ taglib
uri="http://java.sun.com/jsp/jstl/functions"
prefix="fn" %>
<head>
<%@ include file="/WEB-INF/pages/common/fragments/editarea.jspf" %>
@@ -10,18 +11,17 @@
<html:xhtml/>
<html>
<body>
-<%@ include
file="/WEB-INF/pages/common/fragments/kickstart/kickstart-toolbar.jspf" %>
-
+<rhn:toolbar base="h1" img="/img/rhn-kickstart_profile.gif"
+
deletionUrl="/rhn/kickstart/KickstartScriptDelete.do?kssid=${kssid}&ksid=${ksdata.id}"
+ deletionType="kickstartscript" >
+ <bean:message key="kickstartdetails.jsp.header1"
arg0="${fn:escapeXml(ksdata.label)}"/>
+</rhn:toolbar>
<rhn:dialogmenu mindepth="0" maxdepth="1"
definition="/WEB-INF/nav/kickstart_details.xml"
renderer="com.redhat.rhn.frontend.nav.DialognavRenderer" />
<p>
-<rhn:toolbar base="h2" img="/img/rhn-kickstart_profile.gif"
-
deletionUrl="/rhn/kickstart/KickstartScriptDelete.do?kssid=${kssid}&ksid=${ksdata.id}"
- deletionType="kickstartscript" >
-<bean:message key="kickstart.script.header1"/>
-</rhn:toolbar>
+<h2><bean:message key="kickstart.script.header1"/></h2>
<div>
<p>
diff --git a/java/code/webapp/WEB-INF/pages/kickstart/scriptorder.jsp
b/java/code/webapp/WEB-INF/pages/kickstart/scriptorder.jsp
new file mode 100644
index 0000000..907380a
--- /dev/null
+++ b/java/code/webapp/WEB-INF/pages/kickstart/scriptorder.jsp
@@ -0,0 +1,139 @@
+<%@ taglib
uri="http://rhn.redhat.com/rhn" prefix="rhn" %>
+<%@ taglib
uri="http://java.sun.com/jsp/jstl/core" prefix="c"
%>
+<%@ taglib
uri="http://struts.apache.org/tags-html" prefix="html"
%>
+<%@ taglib
uri="http://struts.apache.org/tags-bean" prefix="bean"
%>
+<%@ taglib
uri="http://rhn.redhat.com/tags/config-managment"
prefix="cfg" %>
+<html:xhtml/>
+<html>
+<head>
+<script src="/javascript/rank_options.js"
type="text/javascript"></script>
+</head>
+<body>
+<%@ include
file="/WEB-INF/pages/common/fragments/kickstart/kickstart-toolbar.jspf" %>
+
+
+
+<rhn:dialogmenu mindepth="0" maxdepth="1"
+ definition="/WEB-INF/nav/kickstart_details.xml"
+ renderer="com.redhat.rhn.frontend.nav.DialognavRenderer" />
+
+<h2><bean:message key="kickstartscript.order.header"/></h2>
+
+<div>
+ <p>
+ <bean:message key="kickstartscript.order.summary"/>
+ </p>
+
+ <html:form method="post"
action="/kickstart/KickstartScriptOrder.do">
+ <rhn:csrf />
+ <rhn:submitted />
+
+ <noscript>
+ <p><bean:message
key="kickstartscript.order.noscript"/></p>
+ </noscript>
+ <table style="width:100%;">
+ <tr>
+ <td colspan="2">
+ <h2><bean:message
key="kickstartscript.order.prescripts"/></h2>
+ </td>
+ <td colspan="2">
+ <h2><bean:message
key="kickstartscript.order.postscripts"/></h2>
+ </td>
+ </tr>
+ <tr>
+ <td style="width:40%;">
+ <c:if test="${empty
kickstartScriptOrderForm.map.preScripts}">
+ <html:select name="kickstartScriptOrderForm"
+ property="selectedPre"
+ disabled="true"
+ size="15" styleId="preRanksWidget"
style="width:100%;">
+ <html:optionsCollection name="kickstartScriptOrderForm"
+ property="preScripts"/>
+ </html:select>
+ </c:if>
+ <c:if test="${not empty
kickstartScriptOrderForm.map.preScripts}">
+ <html:select name="kickstartScriptOrderForm"
+ property="selectedPre"
+ size="15" styleId="preRanksWidget"
style="width:100%;">
+ <html:optionsCollection name="kickstartScriptOrderForm"
+ property="preScripts"/>
+ </html:select>
+ </c:if>
+ </td>
+ <td valign="top">
+ <table>
+ <tr>
+ <td><html:image src="/img/button-up.gif"
+ altKey="ssm.config.rank.jsp.up"
+ property="dispatch"
+ value="up"
+ onclick="return
move_selected_up('preRanksWidget');"
+ styleClass="button"/>
+ </td></tr>
+ <tr>
+ <td><html:image src="/img/button-down.gif"
+ altKey="ssm.config.rank.jsp.down"
+ property="dispatch"
+ value="down"
+ onclick="return
move_selected_down('preRanksWidget');"
+ styleClass="button"/>
+ </td></tr>
+ </table>
+ <rhn:noscript/>
+ </td>
+ <td style="width:40%;">
+ <c:if test="${empty
kickstartScriptOrderForm.map.postScripts}">
+ <html:select name ="kickstartScriptOrderForm"
+ property="selectedPost"
+ disabled="true"
+ size="15" styleId="postRanksWidget"
style="width:100%;">
+ <html:optionsCollection name="kickstartScriptOrderForm"
+ property="postScripts"/>
+ </html:select>
+ </c:if>
+ <c:if test="${not empty
kickstartScriptOrderForm.map.postScripts}">
+ <html:select name ="kickstartScriptOrderForm"
+ property="selectedPost"
+ size="15" styleId="postRanksWidget"
style="width:100%;">
+ <html:optionsCollection name="kickstartScriptOrderForm"
+ property="postScripts"/>
+ </html:select>
+ </c:if>
+ </td>
+ <td valign="top">
+ <table>
+ <tr>
+ <td><html:image src="/img/button-up.gif"
+ altKey="ssm.config.rank.jsp.up"
+ property="dispatch"
+ value="up"
+ onclick="return
move_selected_up('postRanksWidget');"
+ styleClass="button"/>
+ </td></tr>
+ <tr>
+ <td><html:image src="/img/button-down.gif"
+ altKey="ssm.config.rank.jsp.down"
+ property="dispatch"
+ value="down"
+ onclick="return
move_selected_down('postRanksWidget');"
+ styleClass="button"/>
+ </td></tr>
+ </table>
+ <rhn:noscript/>
+ </td>
+ </tr>
+ </table>
+ <html:hidden property="ksid" value="${ksdata.id}"/>
+ <html:hidden property="submitted" value="true"/>
+ <html:hidden property="dispatch"
value="${rhn:localize('kickstartscript.order.update')}"/>
+ <html:hidden name="kickstartScriptOrderForm"
property="rankedPreValues" styleId="rankedPreValues"/>
+ <html:hidden name="kickstartScriptOrderForm"
property="rankedPostValues" styleId="rankedPostValues"/>
+ <div align="right">
+ <input type="submit" name="dispatcher"
+ value="${rhn:localize('kickstartscript.order.update')}"
+
onclick="handle_ranking('preRanksWidget','rankedPreValues','kickstartScriptOrderForm');
handle_ranking_dispatch('postRanksWidget','rankedPostValues','kickstartScriptOrderForm');"/>
+ </div>
+ </html:form>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/java/code/webapp/WEB-INF/pages/kickstart/scripts.jsp
b/java/code/webapp/WEB-INF/pages/kickstart/scripts.jsp
index 8be640b..44537f0 100644
--- a/java/code/webapp/WEB-INF/pages/kickstart/scripts.jsp
+++ b/java/code/webapp/WEB-INF/pages/kickstart/scripts.jsp
@@ -3,15 +3,30 @@
<%@ taglib
uri="http://struts.apache.org/tags-bean" prefix="bean"
%>
<%@ taglib
uri="http://struts.apache.org/tags-html" prefix="html"
%>
<%@ taglib
uri="http://java.sun.com/jsp/jstl/functions"
prefix="fn" %>
+<%@ taglib
uri="http://rhn.redhat.com/tags/list" prefix="rl"
%>
<html:html xhtml="true">
<body>
-<rhn:toolbar base="h1" img="/img/rhn-kickstart_profile.gif"
+<c:if test="${! empty kickstart_scripts}">
+ <rhn:toolbar base="h1" img="/img/rhn-kickstart_profile.gif"
creationUrl="/rhn/kickstart/KickstartScriptCreate.do?ksid=${ksdata.id}"
creationType="kickstartscript"
+
miscUrl="/rhn/kickstart/KickstartScriptOrder.do?ksid=${ksdata.id}"
+ miscText="toolbar.misc.kickstartscript"
+ miscImg="action-order.gif"
+ miscAlt="toolbar.misc.kickstartscriptalt"
imgAlt="kickstarts.alt.img">
- <bean:message key="kickstartdetails.jsp.header1"
arg0="${fn:escapeXml(ksdata.label)}"/>
-</rhn:toolbar>
+ <bean:message key="kickstartdetails.jsp.header1"
arg0="${fn:escapeXml(ksdata.label)}"/>
+ </rhn:toolbar>
+</c:if>
+<c:if test="${empty kickstart_scripts}">
+ <rhn:toolbar base="h1" img="/img/rhn-kickstart_profile.gif"
+
creationUrl="/rhn/kickstart/KickstartScriptCreate.do?ksid=${ksdata.id}"
+ creationType="kickstartscript"
+ imgAlt="kickstarts.alt.img">
+ <bean:message key="kickstartdetails.jsp.header1"
arg0="${fn:escapeXml(ksdata.label)}"/>
+ </rhn:toolbar>
+</c:if>
<rhn:dialogmenu mindepth="0" maxdepth="1"
definition="/WEB-INF/nav/kickstart_details.xml"
@@ -26,31 +41,39 @@
<p>
<bean:message key="kickstartscript.jsp.summary2"/>
</p>
- <form method="post" name="rhn_list"
action="/rhn/kickstart/Scripts.do">
- <rhn:csrf />
- <rhn:submitted />
-
- <rhn:list pageList="${requestScope.pageList}"
noDataText="kickstartscript.jsp.noscripts">
-
- <rhn:listdisplay renderDisabled="true"
- set="${requestScope.set}">
-
- <rhn:column header="kickstartscript.jsp.type"
style="text-align: center;">
- ${current.scriptType}
- </rhn:column>
- <rhn:column header="kickstartscript.jsp.scriptnum">
- <a
href="/rhn/kickstart/KickstartScriptEdit.do?kssid=${current.id}&ksid=${ksdata.id}"><bean:message
key="kickstartscript.jsp.script"/> ${current.position}</a>
- </rhn:column>
- <rhn:column header="kickstartscript.jsp.scriptname">
- <a
href="/rhn/kickstart/KickstartScriptEdit.do?kssid=${current.id}&ksid=${ksdata.id}">${current.scriptName}</a>
- </rhn:column>
- <rhn:column header="kickstartscript.jsp.language">
- ${current.interpreter}
- </rhn:column>
-
- </rhn:listdisplay>
- </rhn:list>
- </form>
+
+ <rl:listset name="kickstartScriptsSet">
+ <rhn:csrf />
+ <rl:list dataset="kickstart_scripts"
+ width="100%"
+ name="kickstartPreScripts"
+ styleclass="list"
+ emptykey="kickstartscript.jsp.noscripts">
+
+ <rl:column bound="false"
+ sortable="false"
+ headerkey="kickstartscript.jsp.type">
+ ${current.prettyScriptType}
+ </rl:column>
+
+ <rl:column bound="false"
+ sortable="false"
+ headerkey="kickstartscript.jsp.scriptname">
+ <c:if test="${current.editable}">
+ <a
href="/rhn/kickstart/KickstartScriptEdit.do?kssid=${current.id}&ksid=${ksdata.id}">${current.scriptName}</a>
+ </c:if>
+ <c:if test="${not current.editable}">
+ ${current.scriptName}
+ </c:if>
+ </rl:column>
+
+ <rl:column bound="false"
+ sortable="false"
+ headerkey="kickstartscript.jsp.language">
+ ${current.prettyInterpreter}
+ </rl:column>
+ </rl:list>
+ </rl:listset>
</div>
</body>
diff --git a/java/code/webapp/WEB-INF/struts-config.xml
b/java/code/webapp/WEB-INF/struts-config.xml
index 96489bc..f8a68b3 100644
--- a/java/code/webapp/WEB-INF/struts-config.xml
+++ b/java/code/webapp/WEB-INF/struts-config.xml
@@ -720,6 +720,18 @@
<form-property name="submitted"
type="java.lang.Boolean"/>
<form-property name="no_scrub" type="java.lang.String"
initial="contents"/>
</form-bean>
+
+
+ <form-bean name="kickstartScriptOrderForm"
+ type="com.redhat.rhn.frontend.struts.ScrubbingDynaActionForm">
+ <form-property name="preScripts"
type="java.util.ArrayList"/>
+ <form-property name="postScripts"
type="java.util.ArrayList"/>
+ <form-property name="selectedPre"
type="java.lang.String"/>
+ <form-property name="selectedPost"
type="java.lang.String"/>
+ <form-property name="submitted"
type="java.lang.Boolean" />
+ <form-property name="rankedPreValues"
type="java.lang.String"/>
+ <form-property name="rankedPostValues"
type="java.lang.String"/>
+ </form-bean>
<form-bean name="kickstartPackages"
type="org.apache.struts.action.DynaActionForm">
@@ -6020,6 +6032,17 @@
path="/WEB-INF/pages/kickstart/scripts.jsp"/>
</action>
+ <action path="/kickstart/Scripts"
+ scope="request"
+ input="/WEB-INF/pages/kickstart/scripts.jsp"
+ type="com.redhat.rhn.frontend.action.kickstart.ScriptsSetupAction"
+ className="com.redhat.rhn.frontend.struts.RhnActionMapping">
+ <set-property property="postRequiredIfSubmitted"
value="true" />
+ <set-property property="acls"
value="org_entitlement(rhn_provisioning); user_role(config_admin)"/>
+ <forward name="default"
+ path="/WEB-INF/pages/kickstart/scripts.jsp"/>
+ </action>
+
<action path="/kickstart/KickstartIpRanges"
scope="request"
input="/WEB-INF/pages/kickstart/kickstartranges.jsp"
@@ -6743,6 +6766,21 @@
path="/kickstart/Scripts.do"/>
</action>
+ <action path="/kickstart/KickstartScriptOrder"
+ scope="request"
+ name="kickstartScriptOrderForm"
+ input="/WEB-INF/pages/kickstart/scriptorder.jsp"
+
type="com.redhat.rhn.frontend.action.kickstart.KickstartScriptOrderAction"
+ parameter="dispatch"
+ className="com.redhat.rhn.frontend.struts.RhnActionMapping">
+ <set-property property="postRequiredIfSubmitted"
value="true" />
+ <set-property property="acls"
value="org_entitlement(rhn_provisioning); user_role(config_admin)"/>
+ <forward name="default"
+ path="/WEB-INF/pages/kickstart/scriptorder.jsp"/>
+ <forward name="success"
+ redirect="true" path="/kickstart/Scripts.do"/>
+ </action>
+
<action path="/kickstart/KickstartClone"
scope="request"
name="kickstartCloneForm"
diff --git
a/schema/spacewalk/upgrade/spacewalk-schema-2.0-to-spacewalk-schema-2.1/021-rhnKickstartScript.sql
b/schema/spacewalk/upgrade/spacewalk-schema-2.0-to-spacewalk-schema-2.1/021-rhnKickstartScript.sql
new file mode 100644
index 0000000..290f8e8
--- /dev/null
+++
b/schema/spacewalk/upgrade/spacewalk-schema-2.0-to-spacewalk-schema-2.1/021-rhnKickstartScript.sql
@@ -0,0 +1 @@
+update rhnkickstartscript set position = position * -1 where script_type = 'post'
and chroot = 'N';
diff --git a/web/html/javascript/config_channel_ranks.js
b/web/html/javascript/config_channel_ranks.js
deleted file mode 100644
index 2751f12..0000000
--- a/web/html/javascript/config_channel_ranks.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright (c) 2008--2012 Red Hat, Inc.
- * All Rights Reserved.
- *
- * This software is licensed to you under the GNU General Public License,
- * version 2 (GPLv2). There is NO WARRANTY for this software, express or
- * implied, including the implied warranties of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
- * along with this software; if not, see
- *
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
- *
- */
-
-/**
-This file contains java script code related to ConfigChannel Rankings page.
-Basically functions to handle things like the up and down buttons.
-Note this file uses a couple of functions from 'Prototype' library
-to asynchronously post to the channel rankings update page.
-*/
-
-function config_channel_up(rankingWidgetName) {
- return config_channel_move(rankingWidgetName, true);
-}
-function config_channel_down(rankingWidgetName) {
- return config_channel_move(rankingWidgetName, false);
-}
-
-
-/**
-This function gets called when the 'up'/'down' button/arrow/image is
pressed.
-Behaviour, moves the selected Item in the rankingWidget up/down by one step
-depending on the boolean value moveUp.
-Also calls the update Url action asynchronously if provided(who does things like
-saving to a set etc..)..
-@param rankingWidgetName the name of the ranking widget list box.
-@param updateUrl the url that will be called asynchronously, if some set
- has to be updated as a result of this action. Pass
- null if no such actions are required...
-@param moveUp the direction in which the selected item must be moved
- (up if true, down if false).
-*/
-function config_channel_move(rankingWidgetName, moveUp) {
-
- var element = document.getElementById(rankingWidgetName);
- var index = element.selectedIndex;
- if (index > -1) {
- var selected = element.options[index];
- if ((moveUp && index > 0) ||
- (!moveUp && index < element.options.length - 1)) {
- moveToIndex = index - 1;
- if (!moveUp) {
- moveToIndex = index + 1;
- }
-
- element.options[index] = new Option(element.options[moveToIndex].text,
- element.options[moveToIndex].value, false, false);
- element.options[moveToIndex] = selected;
- }
- }
- // return false so that a form submit doesnot happen
- return false;
-}
-
-/**
-This function gets called when a form submit / 'update subscriptions' action is
clicked.
-Behaviour:
-1) Basically joins the values of the rankingWidgetElements into a comma separated
string,
-2) Stores the value in the element provided by 'storerName'
-3) Does a form submit..
-This comma separated magic is required for handling cases where the browser
-supports javascript but does not support ajax..
-@param rankingWidgetName the name of the ranking widget list box.
-@param storerName name of the element in whom the CS string will be stored
- ('rankedValues' in the case of SDC channel rankings)
-@param formName name of the form who has to be submitted.
-*/
-function handle_config_channels_dispatch (rankingWidgetName, storerName, formName) {
- element = document.getElementById(rankingWidgetName);
- storer = document.getElementById(storerName);
- form = document.getElementById(formName);
- storer.value = make_config_channels_csv(rankingWidgetName);
- form.submit();
- return true;
-}
-
-/**
-This function binds the values of each element of a list box ('listBox') in a
comma separated string.
-@param listBoxName the name of the list box element who's transform is desired
-@return a comma separated list of list elements...
-*/
-function make_config_channels_csv(listBoxName) {
- var values = new Array();
- var listBox = document.getElementById(listBoxName);
- for (var i = 0; i < listBox.options.length; i++) {
- values.push(listBox.options[i].value);
- }
- return values.join(',');
-}
diff --git a/web/html/javascript/rank_options.js b/web/html/javascript/rank_options.js
new file mode 100644
index 0000000..1be071d
--- /dev/null
+++ b/web/html/javascript/rank_options.js
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2008--2013 Red Hat, Inc.
+ * All Rights Reserved.
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ *
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ *
+ */
+
+/**
+This file contains java script code related to ConfigChannel Rankings and Kickstart
Scripts Ordering pages.
+Basically functions to handle things like the up and down buttons.
+Note this file uses a couple of functions from 'Prototype' library
+to asynchronously post to the channel rankings update page.
+*/
+
+function move_selected_up(rankingWidgetName) {
+ return move_selected(rankingWidgetName, true);
+}
+function move_selected_down(rankingWidgetName) {
+ return move_selected(rankingWidgetName, false);
+}
+
+
+/**
+This function gets called when the 'up'/'down' button/arrow/image is
pressed.
+Behaviour, moves the selected Item in the rankingWidget up/down by one step
+depending on the boolean value moveUp.
+Also calls the update Url action asynchronously if provided(who does things like
+saving to a set etc..)..
+@param rankingWidgetName the name of the ranking widget list box.
+@param updateUrl the url that will be called asynchronously, if some set
+ has to be updated as a result of this action. Pass
+ null if no such actions are required...
+@param moveUp the direction in which the selected item must be moved
+ (up if true, down if false).
+*/
+function move_selected(rankingWidgetName, moveUp) {
+
+ var element = document.getElementById(rankingWidgetName);
+ var index = element.selectedIndex;
+ if (index > -1) {
+ var selected = element.options[index];
+ if ((moveUp && index > 0) ||
+ (!moveUp && index < element.options.length - 1)) {
+ moveToIndex = index - 1;
+ if (!moveUp) {
+ moveToIndex = index + 1;
+ }
+
+ element.options[index] = new Option(element.options[moveToIndex].text,
+ element.options[moveToIndex].value, false, false);
+ element.options[moveToIndex] = selected;
+ }
+ }
+ // return false so that a form submit doesnot happen
+ return false;
+}
+
+/**
+This function should get called when a form submit action is clicked.
+Behaviour:
+1) Basically joins the values of the rankingWidgetElements into a comma separated
string,
+2) Stores the value in the element provided by 'storerName'
+3) Does a form submit..
+This comma separated magic is required for handling cases where the browser
+supports javascript but does not support ajax..
+@param rankingWidgetName the name of the ranking widget list box.
+@param storerName name of the element in whom the CS string will be stored
+ ('rankedValues' in the case of SDC channel rankings)
+@param formName name of the form who has to be submitted.
+*/
+function handle_ranking_dispatch (rankingWidgetName, storerName, formName) {
+ element = document.getElementById(rankingWidgetName);
+ storer = document.getElementById(storerName);
+ form = document.getElementById(formName);
+ storer.value = make_ranking_csv(rankingWidgetName);
+ form.submit();
+ return true;
+}
+
+/**
+ * This function does the same thing that handle_ranking_dispatch does,
+ * but without submitting the form. This is necessary so that you can submit
+ * a form with more than one rankingWidget in it. The last rakingWidget should
+ * call handle_config_channels_dispatch to submit the form.
+ * @param rankingWidgetName the name of the ranking widget list box.
+ * @param storerName name of the element in whom the CS string will be stored
+ * ('rankedValues' in the case of SDC channel rankings)
+ * @param formName name of the form who has to be submitted.
+ */
+function handle_ranking (rankingWidgetName, storerName, formName) {
+ element = document.getElementById(rankingWidgetName);
+ storer = document.getElementById(storerName);
+ form = document.getElementById(formName);
+ storer.value = make_ranking_csv(rankingWidgetName);
+ return false;
+}
+
+/**
+This function binds the values of each element of a list box ('listBox') in a
comma separated string.
+@param listBoxName the name of the list box element who's transform is desired
+@return a comma separated list of list elements...
+*/
+function make_ranking_csv(listBoxName) {
+ var values = new Array();
+ var listBox = document.getElementById(listBoxName);
+ for (var i = 0; i < listBox.options.length; i++) {
+ values.push(listBox.options[i].value);
+ }
+ return values.join(',');
+}