diff --git a/circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html b/circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
index 99dfd86..2557ce8 100644
--- a/circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
+++ b/circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
@@ -5,7 +5,7 @@
   {% for a in activities %}
     <div class="activity" data-activity-id="{{ a.pk }}">
       <span class="timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}">
-        <i class="fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-plus{% endif %}"></i>
+        <i class="fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-{{a.icon}}{% endif %}"></i>
       </span>
       <strong title="{{ a.result.get_admin_text }}">
         {{ a.readable_name.get_admin_text|capfirst }}
diff --git a/circle/dashboard/views/node.py b/circle/dashboard/views/node.py
index 83a856b..4817320 100644
--- a/circle/dashboard/views/node.py
+++ b/circle/dashboard/views/node.py
@@ -81,6 +81,20 @@ node_ops = OrderedDict([
 ])
 
 
+def _get_activity_icon(act):
+    op = act.get_operation()
+    if op and op.id in node_ops:
+        return node_ops[op.id].icon
+    else:
+        return "cog"
+
+
+def _format_activities(acts):
+    for i in acts:
+        i.icon = _get_activity_icon(i)
+    return acts
+
+
 class NodeDetailView(LoginRequiredMixin,
                      GraphMixin, DetailView):
     template_name = "dashboard/node-detail.html"
@@ -103,7 +117,7 @@ class NodeDetailView(LoginRequiredMixin,
         context['ops'] = get_operations(self.object, self.request.user)
         context['op'] = {i.op: i for i in context['ops']}
         context['show_show_all'] = len(na) > 10
-        context['activities'] = na[:10]
+        context['activities'] = _format_activities(na[:10])
         context['trait_form'] = form
         context['graphite_enabled'] = (
             settings.GRAPHITE_URL is not None)
@@ -298,8 +312,8 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
         show_all = request.GET.get("show_all", "false") == "true"
         node = Node.objects.get(pk=pk)
 
-        activities = NodeActivity.objects.filter(
-            node=node, parent=None).order_by('-started').select_related()
+        activities = _format_activities(NodeActivity.objects.filter(
+            node=node, parent=None).order_by('-started').select_related())
 
         show_show_all = len(activities) > 10
         if not show_all:
diff --git a/circle/vm/models/activity.py b/circle/vm/models/activity.py
index 7a2ab77..d8bb1a5 100644
--- a/circle/vm/models/activity.py
+++ b/circle/vm/models/activity.py
@@ -215,6 +215,10 @@ class NodeActivity(ActivityModel):
         app_label = 'vm'
         db_table = 'vm_nodeactivity'
 
+    def get_operation(self):
+        return self.node.get_operation_from_activity_code(
+            self.activity_code)
+
     def __unicode__(self):
         if self.parent:
             return '{}({})->{}'.format(self.parent.activity_code,