The following patches improve the status of a channel by taking into account both download/mirror _and_ repodata generation.

The download/sync status was a bit tricky to get, as the taskomatic table is made polymorphic by serializing java objects which in turn contain the channel_id, so you can't just SQL it.

Some bugs are fixed in order to get everything working, specially
failing when exit code of external programs is not successful, and
getting the tail log for logs smaller than the requested tail.

The status is exposed as a ChannelStatus class.

This could be displayed as icons (spinning wheel, exclamation) in the overview lists, but as I don't have a concept for the UI I kept it in the channel details page, as the "half" status was already there.

The patches are intended for review, but are not yet rebased against master.

commit c523b18667ace8acd5dd835378e87d0be45f9473
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Thu Jan 31 17:45:25 2013 +0100

     Improve the Channel Details page by using the status generated
     by ChannelStatus, which includes also repo-sync information.

commit 080232549c07e6c38caaebbaa640530efebcd614
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Thu Jan 31 11:31:36 2013 +0100

     Introduce ChannelStatus as an agregate way to query both the repo-sync
     and repodata generation status of a channel.

     The class also carries a log to transport debug information to the
     admin. In the future, more data or sub-statuses could be added to
     this class.

     The ChannelStatus is exposed in ChannelManager::statusForLabel(label)
     and ChannelManager::isChannelLabelInProgress(label) gets deprecated
     and reimplemented using ChannelManager::statusForLabel(label).

     The Task queries get a new query to ask for candidate repodata
     generation workers and the active ones gets renamed to keep the
     names meanful and consistent.

commit caec97d8d2b88f008cb0e70391cb572207f6b1da
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Wed Jan 30 18:37:52 2013 +0100

     RhnJavaJob: Do not ignore the exit code for external programs.

commit 630870f813d2deaf2b95d8a133fdfd78e110c05a
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Wed Jan 30 18:31:01 2013 +0100

     TaskoRun Log tail: Handle the case where more bytes are requested
     than the current size of the log.

commit 6f445ce3e1f85fecbe4010f3cfce1a5724dab286
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Wed Jan 30 18:30:09 2013 +0100

     Do not silence catched exceptions. Debugging can be hard.

commit ce3c088b4890e40273aa846bad0501bd62367080
Author: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date:   Wed Jan 30 18:29:25 2013 +0100

     FileNotFoundException inherits IOException so no need for a separate
     catch block if the catch code is the same (none).




>From ce3c088b4890e40273aa846bad0501bd62367080 Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Wed, 30 Jan 2013 18:29:25 +0100
Subject: [PATCH 1/6] FileNotFoundException inherits IOException so no need
 for a separate catch block if the catch code is the
 same (none).

---
 java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java |    3 ---
 1 file changed, 3 deletions(-)

diff --git a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
index c58a296..b521513 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
@@ -188,9 +188,6 @@ public class TaskoRun {
                 file.close();
                 return tail;
             }
-            catch (FileNotFoundException e) {
-                // return "";
-            }
             catch (IOException e) {
                 // return "";
             }
-- 
1.7.10.4


>From 6f445ce3e1f85fecbe4010f3cfce1a5724dab286 Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Wed, 30 Jan 2013 18:30:09 +0100
Subject: [PATCH 2/6] Do not silence catched exceptions. Debugging can be
 hard.

---
 java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java |    1 +
 1 file changed, 1 insertion(+)

diff --git a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
index b521513..3dfd595 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
@@ -189,6 +189,7 @@ public class TaskoRun {
                 return tail;
             }
             catch (IOException e) {
+                log.error("Can't tail " + fileName + ": " + e.toString());
                 // return "";
             }
         }
-- 
1.7.10.4


>From 630870f813d2deaf2b95d8a133fdfd78e110c05a Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Wed, 30 Jan 2013 18:31:01 +0100
Subject: [PATCH 3/6] TaskoRun Log tail: Handle the case where more bytes are
 requested than the current size of the log.

---
 java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
index 3dfd595..8cc8073 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/TaskoRun.java
@@ -178,7 +178,8 @@ public class TaskoRun {
             try {
                 file = new RandomAccessFile(fileName, "r");
                 if (nBytes >= 0) {
-                    file.seek(file.length() - nBytes);
+                    long seekAmount = file.length() - nBytes;
+                    if (seekAmount > 0) file.seek(seekAmount);
                 }
                 String tail = "";
                 String line;
-- 
1.7.10.4


>From caec97d8d2b88f008cb0e70391cb572207f6b1da Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Wed, 30 Jan 2013 18:37:52 +0100
Subject: [PATCH 4/6] RhnJavaJob: Do not ignore the exit code for external
 programs.

---
 .../src/com/redhat/rhn/taskomatic/task/RhnJavaJob.java     |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/java/code/src/com/redhat/rhn/taskomatic/task/RhnJavaJob.java b/java/code/src/com/redhat/rhn/taskomatic/task/RhnJavaJob.java
index 494bcda..7209bb0 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/task/RhnJavaJob.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/task/RhnJavaJob.java
@@ -93,9 +93,11 @@ public abstract class RhnJavaJob implements RhnJob {
         HibernateFactory.closeSession();
     }
 
-    protected void executeExtCmd(String[] args) {
+    protected void executeExtCmd(String[] args)
+        throws JobExecutionException {
+
         SystemCommandExecutor ce = new SystemCommandExecutor();
-        ce.execute(args);
+        int exitCode = ce.execute(args);
 
         String cmdOutput = ce.getLastCommandOutput();
         String cmdError = ce.getLastCommandErrorMessage();
@@ -105,5 +107,11 @@ public abstract class RhnJavaJob implements RhnJob {
         if (!"".equals(cmdError)) {
             log.error(cmdError);
         }
+
+        if (exitCode != 0) {
+            // use stderr, unless it is empty, then use stdout
+            throw new JobExecutionException(
+                    cmdError.isEmpty() ? cmdOutput : cmdError);
+        }
     }
 }
-- 
1.7.10.4


>From 080232549c07e6c38caaebbaa640530efebcd614 Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Thu, 31 Jan 2013 11:31:36 +0100
Subject: [PATCH 5/6] Introduce ChannelStatus as an agregate way to query both
 the repo-sync and repodata generation status of a
 channel.

The class also carries a log to transport debug information to the
admin. In the future, more data or sub-statuses could be added to
this class.

The ChannelStatus is exposed in ChannelManager::statusForLabel(label)
and ChannelManager::isChannelLabelInProgress(label) gets deprecated
and reimplemented using ChannelManager::statusForLabel(label).

The Task queries get a new query to ask for candidate repodata
generation workers and the active ones gets renamed to keep the
names meanful and consistent.
---
 .../rhn/common/db/datasource/xml/Task_queries.xml  |   10 +-
 .../redhat/rhn/domain/channel/ChannelStatus.java   |  223 ++++++++++++++++++++
 .../redhat/rhn/manager/channel/ChannelManager.java |   18 +-
 .../redhat/rhn/taskomatic/task/TaskConstants.java  |    7 +-
 .../task/repomd/ChannelRepodataWorker.java         |    4 +-
 5 files changed, 252 insertions(+), 10 deletions(-)
 create mode 100644 java/code/src/com/redhat/rhn/domain/channel/ChannelStatus.java

diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/Task_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/Task_queries.xml
index 96f12fc..3bb513c 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/Task_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/Task_queries.xml
@@ -209,7 +209,7 @@ SELECT distinct channel_label
   </query>
 </mode>
 
-<mode name="repomd_details_query">
+<mode name="repomd_active_details_query">
   <query params="channel_label">
 SELECT id, channel_label, client, reason, force, bypass_filters, next_action
   FROM rhnRepoRegenQueue queue
@@ -218,6 +218,14 @@ SELECT id, channel_label, client, reason, force, bypass_filters, next_action
   </query>
 </mode>
 
+<mode name="repomd_candidates_details_query">
+  <query params="channel_label">
+SELECT id, channel_label, client, reason, force, bypass_filters, next_action
+  FROM rhnRepoRegenQueue queue
+   WHERE next_action is not null
+   and channel_label = :channel_label
+  </query>
+</mode>
 
 <write-mode name="repomd_mark_in_progress">
    <query params="channel_label">
diff --git a/java/code/src/com/redhat/rhn/domain/channel/ChannelStatus.java b/java/code/src/com/redhat/rhn/domain/channel/ChannelStatus.java
new file mode 100644
index 0000000..161dd3a
--- /dev/null
+++ b/java/code/src/com/redhat/rhn/domain/channel/ChannelStatus.java
@@ -0,0 +1,223 @@
+package com.redhat.rhn.domain.channel;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.redhat.rhn.common.db.datasource.ModeFactory;
+import com.redhat.rhn.common.db.datasource.SelectMode;
+import com.redhat.rhn.taskomatic.TaskoFactory;
+import com.redhat.rhn.taskomatic.TaskoRun;
+import com.redhat.rhn.taskomatic.TaskoSchedule;
+import com.redhat.rhn.taskomatic.task.TaskConstants;
+
+/**
+ * Consolidated status of a Channel
+ *
+ * Channels are processed in two stages:
+ *
+ * spacewalk-reposync via RepoSyncTask and metadata generation via
+ * a single Taskomatic job creating ChannelRepodataWorkers for
+ * every channel.
+ *
+ * This class builds a simple status based on tasks from both stages
+ * and captures the relevant log in case of problems so that the user
+ * interface can display it.
+ *
+ * @author Duncan Mac-Vicar P. <dmacvi...@suse.de>
+ *
+ */
+public class ChannelStatus {
+
+    private enum Type {
+        UNKNOWN,
+        IN_PROGRESS,
+        SCHEDULED,
+        FAILED,
+        COMPLETED
+    }
+    private final String statusLog;
+    private final Type type;
+
+    /**
+     * Shows the status as string plus the relevant log tail
+     */
+    @Override
+    public String toString() {
+        return type.toString() + (getLog().isEmpty() ? "" : (": " + getLog()));
+    }
+
+    ChannelStatus(Type type, String statusLog) {
+        this.statusLog = statusLog;
+        this.type = type;
+    }
+
+    ChannelStatus(Type type) {
+        this(type, "");
+    }
+
+    /**
+     * @return A log tail related with the status
+     */
+    public String getLog() {
+        return statusLog;
+    }
+
+    public ChannelStatus.Type getType() {
+        return type;
+    }
+
+    /**
+     * @return true if the channel is being worked
+     * on (downloading packages or generating metadata)
+     */
+    public boolean isInProgress() {
+        return getType() == Type.IN_PROGRESS;
+    }
+
+    /**
+     * @return true if the channel has not completed
+     * all the steps to be available, but it is
+     * scheduled to do so.
+     */
+    public boolean isScheduled() {
+        return getType() == Type.SCHEDULED;
+    }
+
+    /**
+     * @return true if the channel steps failed
+     */
+    public boolean isFailed() {
+        return getType() == Type.FAILED;
+    }
+
+    /**
+     * @return true if the status of this channel seems
+     * to be completed (synced and generated)
+     */
+    public boolean isCompleted() {
+        return getType() == Type.COMPLETED;
+    }
+
+    /**
+     * @return true if the status of this channel is unknown
+     */
+    public boolean isUnknown() {
+        return getType() == Type.UNKNOWN;
+    }
+
+    /**
+     * Status of a channel with regard of syncing packages and
+     * generation of the repository metadata.
+     *
+     * @param channel label
+     * @return The status of the channel
+     */
+    public static ChannelStatus statusForLabel(String channel) {
+        ChannelStatus status = repoGenStatus(channel);
+        if (status.getType() == ChannelStatus.Type.UNKNOWN) {
+           return repoSyncStatus(channel);
+        }
+        return status;
+    }
+
+    /**
+     * Status for the repo sync (download of packages) for a given
+     * channel
+     */
+    private static ChannelStatus repoSyncStatus(String channel) {
+        // now check if the channel is in the repo-sync queue
+        // first get all repo-sync running tasks
+        Channel chObj = ChannelFactory.lookupByLabel(channel);
+        if (chObj == null)
+            return new ChannelStatus(ChannelStatus.Type.UNKNOWN, "Unknown channel with label " + channel);
+
+        List<TaskoRun> runningRuns = TaskoFactory.listRunsByBunch("repo-sync-bunch");
+        // they are sorted so that by start time, recent ones first
+        for (TaskoRun run : runningRuns) {
+            TaskoSchedule schedule = TaskoFactory.lookupScheduleById(run.getScheduleId());
+            Map<String, Object> dataMap = schedule.getDataMap();
+            // tasks should have an associated channel with it
+            if (!dataMap.containsKey("channel_id")) {
+                continue;
+            }
+
+            String channelIdString = (String) dataMap.get("channel_id");
+            Long channelId;
+            try {
+                channelId = Long.parseLong(channelIdString);
+            }
+            catch (Exception e) {
+                // if we can't get the id, continue, may be there is
+                // an older job with good metadata
+                continue;
+            }
+
+            if (channelId.equals(chObj.getId())) {
+                return ChannelStatus.singleRepoSyncRunStatus(run);
+            }
+        }
+        return new ChannelStatus(ChannelStatus.Type.UNKNOWN);
+    }
+
+    /**
+     * @param run A Taskomatic run
+     * @return The mapped status for the single taskomatic run
+     */
+    private static ChannelStatus singleRepoSyncRunStatus(TaskoRun run) {
+        ChannelStatus.Type type = ChannelStatus.Type.UNKNOWN;
+        String log = run.getTailOfStdError(1024);
+
+        if (log.isEmpty()) {
+            log = run.getTailOfStdOutput(1024);
+        }
+
+        if (run.getStatus().equals(TaskoRun.STATUS_FAILED)) {
+            type = ChannelStatus.Type.FAILED;
+        }
+        else if (run.getStatus().equals(TaskoRun.STATUS_READY_TO_RUN)) {
+            type = ChannelStatus.Type.SCHEDULED;
+        }
+        else if (run.getStatus().equals(TaskoRun.STATUS_RUNNING)) {
+            type = ChannelStatus.Type.IN_PROGRESS;
+        }
+        else if (run.getStatus().equals(TaskoRun.STATUS_FINISHED)) {
+            type = ChannelStatus.Type.COMPLETED;
+        }
+
+        return new ChannelStatus(type, log);
+    }
+
+    /**
+     * Status of the repo metadata generation for a given
+     * channel.
+     *
+     * @param channel the channel to look for status
+     * @return repodata status
+     */
+    public static ChannelStatus repoGenStatus(String channel) {
+        // First check if the channel is in the repodata generation
+        // queue as in-progress
+        SelectMode selector = ModeFactory.getMode(TaskConstants.MODE_NAME,
+                TaskConstants.TASK_QUERY_REPOMD_ACTIVE_DETAILS_QUERY);
+        Map<Object, Object> params = new HashMap<Object, Object>();
+        params.put("channel_label", channel);
+
+        if (selector.execute(params).size() > 0) {
+            return new ChannelStatus(ChannelStatus.Type.IN_PROGRESS);
+        }
+
+        // now check for queued items
+        selector = ModeFactory.getMode(TaskConstants.MODE_NAME,
+                TaskConstants.TASK_QUERY_REPOMD_CANDIDATES_DETAILS_QUERY);
+        params = new HashMap<Object, Object>();
+        params.put("channel_label", channel);
+
+        if (selector.execute(params).size() > 0) {
+            return new ChannelStatus(ChannelStatus.Type.SCHEDULED);
+        }
+
+        return new ChannelStatus(ChannelStatus.Type.UNKNOWN);
+    }
+}
+
diff --git a/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java b/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java
index da09b61..e92a7c6 100644
--- a/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java
+++ b/java/code/src/com/redhat/rhn/manager/channel/ChannelManager.java
@@ -33,6 +33,7 @@ import com.redhat.rhn.domain.channel.ChannelArch;
 import com.redhat.rhn.domain.channel.ChannelFactory;
 import com.redhat.rhn.domain.channel.ChannelFamily;
 import com.redhat.rhn.domain.channel.ChannelFamilyFactory;
+import com.redhat.rhn.domain.channel.ChannelStatus;
 import com.redhat.rhn.domain.channel.ChannelVersion;
 import com.redhat.rhn.domain.channel.ClonedChannel;
 import com.redhat.rhn.domain.channel.DistChannelMap;
@@ -2735,14 +2736,21 @@ public class ChannelManager extends BaseManager {
     /**
      * Check the status of the cache repo data
      * @param channel the channel to look for status
+     * @deprecated as of release 1.8, replaced by {@link #statusForLabel()}
      * @return repodata status
      */
+    @Deprecated
     public static boolean isChannelLabelInProgress(String channel) {
-        SelectMode selector = ModeFactory.getMode(TaskConstants.MODE_NAME,
-                TaskConstants.TASK_QUERY_REPOMD_DETAILS_QUERY);
-        Map<Object, Object> params = new HashMap<Object, Object>();
-        params.put("channel_label", channel);
-        return (selector.execute(params).size() > 0);
+        return statusForLabel(channel).isInProgress();
+    }
+
+    /**
+     * Consolidated status about repo-sync and metadata generation
+     * @param channel label
+     * @return Status of the channel and log information
+     */
+    public static ChannelStatus statusForLabel(String channel) {
+        return ChannelStatus.statusForLabel(channel);
     }
 
     /**
diff --git a/java/code/src/com/redhat/rhn/taskomatic/task/TaskConstants.java b/java/code/src/com/redhat/rhn/taskomatic/task/TaskConstants.java
index 9d10d52..9194467 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/task/TaskConstants.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/task/TaskConstants.java
@@ -80,8 +80,11 @@ public class TaskConstants {
     public static final String TASK_QUERY_REPOMD_DEQUEUE =
         "repomd_dequeue";
 
-    public static final String TASK_QUERY_REPOMD_DETAILS_QUERY =
-        "repomd_details_query";
+    public static final String TASK_QUERY_REPOMD_ACTIVE_DETAILS_QUERY =
+        "repomd_active_details_query";
+
+    public static final String TASK_QUERY_REPOMD_CANDIDATES_DETAILS_QUERY =
+            "repomd_candidates_details_query";
 
     public static final String TASK_QUERY_REPOMD_MARK_IN_PROGRESS =
         "repomd_mark_in_progress";
diff --git a/java/code/src/com/redhat/rhn/taskomatic/task/repomd/ChannelRepodataWorker.java b/java/code/src/com/redhat/rhn/taskomatic/task/repomd/ChannelRepodataWorker.java
index 8edb085..33e5f11 100644
--- a/java/code/src/com/redhat/rhn/taskomatic/task/repomd/ChannelRepodataWorker.java
+++ b/java/code/src/com/redhat/rhn/taskomatic/task/repomd/ChannelRepodataWorker.java
@@ -139,7 +139,7 @@ public class ChannelRepodataWorker implements QueueWorker {
      */
     private void populateQueueEntryDetails() {
         SelectMode selector = ModeFactory.getMode(TaskConstants.MODE_NAME,
-                TaskConstants.TASK_QUERY_REPOMD_DETAILS_QUERY);
+                TaskConstants.TASK_QUERY_REPOMD_ACTIVE_DETAILS_QUERY);
         Map<Object, Object> params = new HashMap<Object, Object>();
         params.put("channel_label", channelLabelToProcess);
         queueEntries = selector.execute(params);
@@ -151,7 +151,7 @@ public class ChannelRepodataWorker implements QueueWorker {
      */
     private boolean isChannelLabelAlreadyInProcess() {
         SelectMode selector = ModeFactory.getMode(TaskConstants.MODE_NAME,
-                TaskConstants.TASK_QUERY_REPOMD_DETAILS_QUERY);
+                TaskConstants.TASK_QUERY_REPOMD_ACTIVE_DETAILS_QUERY);
         Map<Object, Object> params = new HashMap<Object, Object>();
         params.put("channel_label", channelLabelToProcess);
         return (selector.execute(params).size() > 0);
-- 
1.7.10.4


>From c523b18667ace8acd5dd835378e87d0be45f9473 Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <dmacvi...@suse.de>
Date: Thu, 31 Jan 2013 17:45:25 +0100
Subject: [PATCH 6/6] Improve the Channel Details page by using the status
 generated by ChannelStatus, which includes also
 repo-sync information.

---
 branding/img/sync-spinner.gif                      |  Bin 0 -> 847 bytes
 .../action/channel/ChannelDetailsAction.java       |    5 +++--
 .../frontend/strings/jsp/StringResource_en_US.xml  |    8 +++++++-
 .../webapp/WEB-INF/pages/channel/channeldetail.jsp |   20 ++++++++++++++++----
 4 files changed, 26 insertions(+), 7 deletions(-)
 create mode 100644 branding/img/sync-spinner.gif

diff --git a/branding/img/sync-spinner.gif b/branding/img/sync-spinner.gif
new file mode 100644
index 0000000000000000000000000000000000000000..1af15ef0af0d45b4d15f93f4a577b83a9144296a
GIT binary patch
literal 847
zcmZ?wbhEHb6krfw_`<;O|NsAvuGZhbe=k}*|LC#9T|MnHXHS3q`qi~-S0_#B-?xA7
z_8nV4e)@Rs{MpA(9<N-reEr6?45R?Xe^Smxsfi`2DGKG8B^e5dS&0=n`H3ldnR#jX
z42nNl7`TAODgNj7a}5c0b_{Se(lcOY1PbYZYymlvfi*xup)VzK-ckdR97U~`gjH*2
zh#Z?JW!mt8?Pf<qbT5kyQ)X+xM1fYu&elbJYczElJfnUrQc3!-%VW|6i<T9pYO)ob
zrr8QM!Xlq4Wskn^cY@l>h-^uQf<l-3rJf8esiO~8tZ-0qtvzty;I*Sn96eJSQZqz^
zcn%&=a1iA3IneMSInceC$!W{eZ2_h;6l_+RhNc8=(|)0}Z*lq*gB4=y7A@>|%oaGW
z?8v}v6JTz@Zo|paV89p2W}(H)*{-YzwVVmr@&up{l|N6=xFzDD#dRb=gj07(yWxA|
zMlLJo(}vz#JX)F_vU%vuP`SCWl7T~D-^DYmH?p|(8pB;2?(ju2EHd!m6l>Kn=ySTl
z)t4>c_3SNAsJ&@9GfRz1HgAk3KTkKzQf6dJgCN1$pfH8WP~@n?ie_gywl(6%vb&q+
zFe*AdNw8;V+|IObg0gFqMU_)vL__lK+(l*FLP`r2ULIPU(3sH18|t=9vgnQ^-_nBD
znxE7DH^8i6LAD0uH(>0oaNuz@6gYHJA~#mz_)ZCro(pX^G}r~YSWK7{o@?kxEOS##
z^k9exp25+WYr14BW0H%<7B+@eI}?+1xcXEZ3XH{)k0@_Y|H1o4iQUA^JU~q=Lcc+y
zr&k4LDJ!z2@lZ=WfF9#m=3v5bXwxxACC`Z*8)hv`;IPYUW%V>r>5%A^^ETha>!HJb
zuv53BS*xkpRZ2u)$zk1#2`f4h4lw-`Fzn=z*f8CppU>GmgG1ktC5<&kv%5!4k--|2
HJi!0}wq_5$

literal 0
HcmV?d00001

diff --git a/java/code/src/com/redhat/rhn/frontend/action/channel/ChannelDetailsAction.java b/java/code/src/com/redhat/rhn/frontend/action/channel/ChannelDetailsAction.java
index 8733dc1..09d6ef9 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/channel/ChannelDetailsAction.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/channel/ChannelDetailsAction.java
@@ -17,6 +17,7 @@ package com.redhat.rhn.frontend.action.channel;
 import com.redhat.rhn.common.localization.LocalizationService;
 import com.redhat.rhn.domain.channel.Channel;
 import com.redhat.rhn.domain.channel.ChannelFactory;
+import com.redhat.rhn.domain.channel.ChannelStatus;
 import com.redhat.rhn.domain.role.RoleFactory;
 import com.redhat.rhn.domain.user.User;
 import com.redhat.rhn.frontend.struts.RequestContext;
@@ -88,8 +89,8 @@ public class ChannelDetailsAction extends RhnAction {
         //Check if the channel needed repodata,
         // if so get the status and last build info
         if (chan.isChannelRepodataRequired()) {
-            request.setAttribute("repo_status",
-                    ChannelManager.isChannelLabelInProgress(chan.getLabel()));
+            ChannelStatus status = ChannelManager.statusForLabel(chan.getLabel());
+            request.setAttribute("repo_status", status);
             request.setAttribute("repo_last_build", ChannelManager.getRepoLastBuild(chan));
         }
         // turn on the right radio button
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 d650188..2e7aaab 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
@@ -21239,7 +21239,13 @@ given channel.</source>
 		<source> Completed </source>
       </trans-unit>
       <trans-unit id="channel.jsp.repodata.inProgress">
-		<source> In Progress </source>
+        	<source> In Progress </source>
+      </trans-unit>
+      <trans-unit id="channel.jsp.repodata.scheduled">
+		<source> Scheduled </source>
+      </trans-unit>
+      <trans-unit id="channel.jsp.repodata.failed">
+                <source> Failed </source>
       </trans-unit>
       <trans-unit id="channel.jsp.repolastbuild">
 		<source>Last Repo Build</source>
diff --git a/java/code/webapp/WEB-INF/pages/channel/channeldetail.jsp b/java/code/webapp/WEB-INF/pages/channel/channeldetail.jsp
index f297317..4b77eed 100644
--- a/java/code/webapp/WEB-INF/pages/channel/channeldetail.jsp
+++ b/java/code/webapp/WEB-INF/pages/channel/channeldetail.jsp
@@ -102,14 +102,26 @@
         <th><bean:message key="channel.jsp.repodata"/>:</th>
         <td>
            <c:choose>
-               <c:when test="${repo_status ==  null}">
+               <c:when test="${repo_status.unknown}">
                <span class="no-details">(none)</span>
                </c:when>
-               <c:when test="${repo_status == true}">
+               <c:when test="${repo_status.inProgress}">
+                  <img src="/img/sync-spinner.gif" alt="" />
                   <bean:message key="channel.jsp.repodata.inProgress"/>
                </c:when>
-               <c:when test="${repo_status == false && repo_last_build != null}">
-                    <bean:message key="channel.jsp.repodata.completed"/>
+               <c:when test="${repo_status.scheduled}">
+                  <img src="/img/rhn-listicon-pending.gif" alt="" />
+                  <bean:message key="channel.jsp.repodata.scheduled"/>
+               </c:when>
+               <c:when test="${repo_status.failed}">
+                  <img src="/img/rhn-listicon-error.gif" alt="" />
+                  <a href="javascript:;" onclick="$('channel-error-log').toggle();">
+                    <bean:message key="channel.jsp.repodata.failed"/>
+                  </a>
+                  <textarea id="channel-error-log" style="display: none;" rows="4" cols="80">${repo_status.log}</textarea>
+               </c:when>
+               <c:when test="${repo_status.completed}">
+                    <bean:message key="channel.jsp.repodata.completed"/> 
                </c:when>
                <c:otherwise>
                 <span class="no-details">(none)</span>
-- 
1.7.10.4


_______________________________________________
Spacewalk-devel mailing list
Spacewalk-devel@redhat.com
https://www.redhat.com/mailman/listinfo/spacewalk-devel

Reply via email to