Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package hawk-apiserver for openSUSE:Factory 
checked in at 2026-11-02 16:39:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hawk-apiserver (Old)
 and      /work/SRC/openSUSE:Factory/.hawk-apiserver.new.1255 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hawk-apiserver"

Mon Nov  2 16:39:52 2026 rev:16 rq:1394422 version:0.6.0+git.1793612600.48f2e53

Changes:
--------
--- /work/SRC/openSUSE:Factory/hawk-apiserver/hawk-apiserver.changes    
2026-10-31 23:09:28.315656935 +0100
+++ /work/SRC/openSUSE:Factory/.hawk-apiserver.new.1255/hawk-apiserver.changes  
2026-11-02 16:40:45.494216846 +0100
@@ -1,0 +2,6 @@
+Mon Nov  2 09:48:17 UTC 2026 - Aleksei Burlakov <[email protected]>
+ 
+- Version 0.6.0+git.1793612600.48f2e53:
+  * Dev: implement /cib/live/resources/types menu
+
+-------------------------------------------------------------------

Old:
----
  hawk-apiserver-0.5.0+git.1793384507.8daa0a1.tar.gz

New:
----
  hawk-apiserver-0.6.0+git.1793612600.48f2e53.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hawk-apiserver.spec ++++++
--- /var/tmp/diff_new_pack.C51Wl0/_old  2026-11-02 16:40:46.882275002 +0100
+++ /var/tmp/diff_new_pack.C51Wl0/_new  2026-11-02 16:40:46.883275044 +0100
@@ -20,7 +20,7 @@
 %define www_base %{_datadir}/hawk
 
 Name:           hawk-apiserver
-Version:        0.5.0+git.1793384507.8daa0a1
+Version:        0.6.0+git.1793612600.48f2e53
 Release:        0
 Summary:        Web server and API provider for Hawk
 License:        GPL-3.0-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.C51Wl0/_old  2026-11-02 16:40:46.929276971 +0100
+++ /var/tmp/diff_new_pack.C51Wl0/_new  2026-11-02 16:40:46.932277097 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/ClusterLabs/hawk-apiserver</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="versionformat">0.5.0+git.%ct.%h</param>
+    <param name="versionformat">0.6.0+git.%ct.%h</param>
     <param name="revision">master</param>
   </service>
   <service name="recompress" mode="disabled">

++++++ hawk-apiserver-0.5.0+git.1793384507.8daa0a1.tar.gz -> 
hawk-apiserver-0.6.0+git.1793612600.48f2e53.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/api/resource_types.go 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/api/resource_types.go
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/api/resource_types.go       
1970-01-01 01:00:00.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/api/resource_types.go       
2026-11-02 10:43:20.000000000 +0100
@@ -0,0 +1,107 @@
+package api
+
+import (
+       "context"
+       "net/http"
+       "os/exec"
+       "time"
+)
+
+type resourceType struct {
+       Name string
+       Path string
+       Icon string
+       Help string
+}
+
+func resourceTypes(ctx context.Context, crm string) []resourceType {
+       types := []resourceType{
+               {
+                       Name: "Primitive",
+                       Path: "primitives",
+                       Icon: "file",
+                       Help: "Primitive resources are the most basic type of 
resource. Define an ID and " +
+                               "select the resource agent class, provider and 
type, then configure its " +
+                               "parameters. For example, an IP address agent 
can manage a floating IP address.",
+               },
+               {
+                       Name: "Group",
+                       Path: "groups",
+                       Icon: "users",
+                       Help: "Groups contain resources that run together, 
start in order and stop in reverse " +
+                               "order. Define an ID and select the member 
resources. For example, group an IP " +
+                               "address, file system and Web server so they 
fail over together.",
+               },
+               {
+                       Name: "Clone",
+                       Path: "clones",
+                       Icon: "copy",
+                       Help: "Clones run instances of a resource on multiple 
cluster nodes. Define an ID and " +
+                               "select a primitive or group as the child 
resource. Instances may behave " +
+                               "identically or use node-specific 
configuration.",
+               },
+               /* Multi-state is deprecated
+               {
+                       Name: "Multi-state",
+                       Path: "masters",
+                       Icon: "superscript",
+                       Help: "Promotable resources are specialized clones 
whose instances can operate in two " +
+                               "modes. A subset of instances can be promoted. 
Define an ID and select the " +
+                               "child resource. DRBD is an example of a 
promotable resource.",
+               },
+               */
+               {
+                       Name: "Tag",
+                       Path: "tags",
+                       Icon: "tag",
+                       Help: "Tags refer to multiple resources without adding 
colocation or ordering " +
+                               "relationships. Define an ID and select the 
objects to reference. A tag can be " +
+                               "used to start or stop related resources with a 
single command.",
+               },
+       }
+       // Match Rails' Util.has_feature?(:rsc_template), with a bounded probe.
+       ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
+       defer cancel()
+       if exec.CommandContext(ctx, crm, "configure", "help", 
"rsc_template").Run() == nil {
+               types = append(types, resourceType{
+                       Name: "Template",
+                       Path: "templates",
+                       Icon: "file-lines",
+                       Help: "Resource templates provide reusable 
configuration for similar resources. " +
+                               "Primitives referencing a template inherit its 
operations, parameters, meta " +
+                               "attributes and utilization attributes. Values 
defined on the primitive " +
+                               "override inherited values.",
+               })
+       }
+       return append(types, resourceType{
+               Name: "Alert",
+               Path: "alerts",
+               Icon: "bullhorn",
+               Help: "Alerts run external agents when cluster events occur, 
such as node failures or " +
+                       "resources starting and stopping. Configure the agent 
and its recipients, " +
+                       "parameters and meta attributes. Recipients can be 
addresses, file names or " +
+                       "other values understood by the agent.",
+       })
+}
+
+func ResourceTypesHandler(w http.ResponseWriter, r *http.Request) {
+       if r.URL.Path != "/cib/live/resources/types" && r.URL.Path != 
"/cib/live/resources/types/" {
+               http.NotFound(w, r)
+               return
+       }
+       if r.Method != http.MethodGet && r.Method != http.MethodHead {
+               w.Header().Set("Allow", "GET, HEAD")
+               http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+               return
+       }
+       data := map[string]any{
+               "Title":         "Add Resource",
+               "ResourceTypes": resourceTypes(r.Context(), "/usr/sbin/crm"),
+       }
+       // This flash is only for backward compatibility with Ruby redirects.
+       if r.URL.Query().Get("flash") == "deleted" {
+               data["AlertType"] = "success"
+               data["AlertMessage"] = "Resource deleted successfully"
+       }
+       renderTemplate(w, "resource_types", data)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/api/resource_types_test.go 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/api/resource_types_test.go
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/api/resource_types_test.go  
1970-01-01 01:00:00.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/api/resource_types_test.go  
2026-11-02 10:43:20.000000000 +0100
@@ -0,0 +1,55 @@
+package api
+
+import (
+       "bytes"
+       "context"
+       "html/template"
+       "net/http"
+       "net/http/httptest"
+       "os"
+       "path/filepath"
+       "testing"
+
+       "github.com/stretchr/testify/require"
+)
+
+func TestResourceTypesWithoutCrm(t *testing.T) {
+       types := resourceTypes(context.Background(), filepath.Join(t.TempDir(), 
"missing-crm"))
+       require.Len(t, types, 5)
+       for _, item := range types {
+               require.NotEqual(t, "templates", item.Path)
+               require.NotEqual(t, "masters", item.Path)
+       }
+       require.Equal(t, "alerts", types[len(types)-1].Path)
+}
+
+func TestResourceTypesWithTemplates(t *testing.T) {
+       crm := filepath.Join(t.TempDir(), "crm")
+       require.NoError(t, os.WriteFile(crm, []byte("#!/bin/sh\n[ \"$1\" = 
configure ] && [ \"$2\" = help ] && [ \"$3\" = rsc_template ]\n"), 0755))
+       types := resourceTypes(context.Background(), crm)
+       require.Len(t, types, 6)
+       tmpl, err := template.ParseFiles("../templates/layout.html", 
"../templates/resource_types.html")
+       require.NoError(t, err)
+       var body bytes.Buffer
+       require.NoError(t, tmpl.ExecuteTemplate(&body, "layout.html", 
map[string]any{"Title": "Add Resource", "ResourceTypes": types}))
+       for _, item := range types {
+               require.NotEqual(t, "masters", item.Path)
+               require.Contains(t, body.String(), 
`href="/cib/live/`+item.Path+`/new"`)
+               require.Contains(t, body.String(), `id="help-`+item.Path+`"`)
+       }
+       require.Contains(t, body.String(), `href="/cib/live/resources"`)
+}
+
+func TestResourceTypesHandlerRejectsOtherRequests(t *testing.T) {
+       for _, tc := range []struct {
+               method, path string
+               status       int
+       }{
+               {http.MethodPost, "/cib/live/resources/types", 
http.StatusMethodNotAllowed},
+               {http.MethodGet, "/cib/live/resources/types/unknown", 
http.StatusNotFound},
+       } {
+               response := httptest.NewRecorder()
+               ResourceTypesHandler(response, httptest.NewRequest(tc.method, 
tc.path, nil))
+               require.Equal(t, tc.status, response.Code)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/main.go 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/main.go
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/main.go     2026-10-30 
19:21:47.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/main.go     2026-11-02 
10:43:20.000000000 +0100
@@ -131,6 +131,8 @@
        // Register BOTH /cib/live/foo and /cib/live/foo/ to avoid conflicts 
with Ruby
        mux.HandleFunc("/cib/live/commands", 
authMiddleware(api.CommandsHandler))
        mux.HandleFunc("/cib/live/commands/", 
authMiddleware(api.CommandsHandler))
+       mux.HandleFunc("/cib/live/resources/types", 
authMiddleware(api.ResourceTypesHandler))
+       mux.HandleFunc("/cib/live/resources/types/", 
authMiddleware(api.ResourceTypesHandler))
        mux.HandleFunc("/cib/live/primitives", 
authMiddleware(api.ResourceEditHandler))
        mux.HandleFunc("/cib/live/primitives/", 
authMiddleware(api.ResourceEditHandler))
        mux.HandleFunc("/cib/live/clones", authMiddleware(api.CloneEditHandler))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/css/resource_types.css 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/css/resource_types.css
--- 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/css/resource_types.css   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/css/resource_types.css   
    2026-11-02 10:43:20.000000000 +0100
@@ -0,0 +1,59 @@
+.resource-types .resource-type-list {
+  margin-top: 30px;
+}
+
+.resource-types .resource-type-list > li + li {
+  margin-top: 20px;
+}
+
+.resource-types .resource-type-list .resource-type-link {
+  display: flex;
+  align-items: center;
+  min-height: 57px;
+  padding: 0;
+  border: 1px solid #ddd;
+  border-radius: 3px;
+  background: linear-gradient(#fafafa, #f5f5f5);
+  color: #444;
+  font-size: 16px;
+  text-align: left;
+  white-space: normal;
+}
+
+.resource-types .resource-type-link:hover,
+.resource-types .resource-type-link:focus {
+  background: #eee;
+}
+
+.resource-type-icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  align-self: stretch;
+  flex: 0 0 56px;
+  min-height: 55px;
+  border-right: 1px solid #ddd;
+  background: #e9e9e9;
+  font-size: 18px;
+}
+
+.resource-type-name {
+  padding: 12px 14px;
+}
+
+.resource-type-add {
+  margin-left: auto;
+  margin-right: 20px;
+  font-size: 19px;
+}
+
+.resource-type-link:hover .resource-type-add,
+.resource-type-link:focus .resource-type-add {
+  color: #00c081;
+}
+
+@media (max-width: 767px) {
+  .resource-types.edit-layout {
+    flex-direction: column;
+  }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/js/commands.js 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/js/commands.js
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/js/commands.js       
2026-10-30 19:21:47.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/js/commands.js       
2026-11-02 10:43:20.000000000 +0100
@@ -1,23 +1,9 @@
 "use strict";
 
-<<<<<<< Updated upstream
-(() => {
-  const container = document.getElementById("commands");
-  const status = document.getElementById("commands-status");
-  const error = document.getElementById("commands-error");
-  const refresh = document.getElementById("commands-refresh");
-
-  async function loadCommands() {
-    refresh.disabled = true;
-    container.setAttribute("aria-busy", "true");
-    error.hidden = true;
-    status.textContent = "Loading commands…";
-=======
 async function loadCommands() {
     const container = document.getElementById("commands");
     const error = document.getElementById("commands-error");
 
->>>>>>> Stashed changes
     try {
         // Keep the Rails command log as the source of truth during the UI 
port.
         const response = await fetch("/cib/live/commands.json", {
@@ -45,29 +31,13 @@
         error.textContent = `Unable to load command log. ${cause.message}`;
         error.hidden = false;
     } finally {
-<<<<<<< Updated upstream
-      refresh.disabled = false;
-      container.setAttribute("aria-busy", "false");
-=======
         container.setAttribute("aria-busy", "false");
->>>>>>> Stashed changes
     }
 }
 
-<<<<<<< Updated upstream
-  // Open the sidebar section containing the current page.
-  document.getElementById("monitoringMenu").classList.remove("in");
-  document.getElementById("troubleshootMenu").classList.add("in");
-  const link = document.querySelector('a[href="/cib/live/commands"]');
-  link.setAttribute("aria-current", "page");
-  refresh.addEventListener("click", loadCommands);
-  loadCommands();
-})();
-=======
 // Open the sidebar section containing the current page.
 document.getElementById("monitoringMenu").classList.remove("in");
 document.getElementById("troubleshootMenu").classList.add("in");
 const link = document.querySelector('a[href="/cib/live/commands"]');
 link.setAttribute("aria-current", "page");
 loadCommands();
->>>>>>> Stashed changes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/js/resource_types.js 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/js/resource_types.js
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/static/js/resource_types.js 
1970-01-01 01:00:00.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/static/js/resource_types.js 
2026-11-02 10:43:20.000000000 +0100
@@ -0,0 +1,24 @@
+// This flash is only for backward compatibility with Ruby redirects.
+// Consume the query parameter so reloading does not show the message again.
+const resourceTypesURL = new URL(window.location.href);
+if (resourceTypesURL.searchParams.get("flash") === "deleted") {
+    resourceTypesURL.searchParams.delete("flash");
+    history.replaceState({}, "", resourceTypesURL);
+}
+
+function showResourceHelp(type) {
+    document.querySelectorAll(".resource-type-help").forEach(section => {
+        section.hidden = section.id !== `help-${type}`;
+    });
+}
+
+const resourceTypeLinks = document.querySelectorAll("[data-resource-type]");
+resourceTypeLinks.forEach(link => {
+    link.addEventListener("mouseenter", () => 
showResourceHelp(link.dataset.resourceType));
+    link.addEventListener("focus", () => 
showResourceHelp(link.dataset.resourceType));
+});
+if (resourceTypeLinks.length) 
showResourceHelp(resourceTypeLinks[0].dataset.resourceType);
+
+document.getElementById("monitoringMenu").classList.remove("in");
+document.getElementById("configurationMenu").classList.add("in");
+document.querySelector('a[href="/cib/live/resources/types"]').setAttribute("aria-current",
 "page");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/templates/commands.html 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/templates/commands.html
--- old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/templates/commands.html     
2026-10-30 19:21:47.000000000 +0100
+++ new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/templates/commands.html     
2026-11-02 10:43:20.000000000 +0100
@@ -1,15 +1,10 @@
 {{ define "content" }}
 <script src="/static/js/commands.js" defer></script>
-<div class="container-fluid">
+<div class="edit-root">
   <h1><i class="fa fa-calendar-days page" aria-hidden="true"></i> Command 
Log</h1>
   <div class="panel panel-default">
     <div class="panel-body">
       <p class="text-muted">Lists crm commands recently executed by hawk, most 
recent first.</p>
-<<<<<<< Updated upstream
-      <button id="commands-refresh" class="btn btn-default" 
type="button">Refresh</button>
-      <p id="commands-status" role="status" aria-live="polite">Loading 
commands…</p>
-=======
->>>>>>> Stashed changes
       <div id="commands-error" class="alert alert-danger" role="alert" 
hidden></div>
       <div id="commands" class="commands" aria-busy="true"></div>
     </div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/templates/resource_types.html 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/templates/resource_types.html
--- 
old/hawk-apiserver-0.5.0+git.1793384507.8daa0a1/templates/resource_types.html   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/hawk-apiserver-0.6.0+git.1793612600.48f2e53/templates/resource_types.html   
    2026-11-02 10:43:20.000000000 +0100
@@ -0,0 +1,38 @@
+{{ define "content" }}
+<link rel="stylesheet" href="/static/css/primitive_edit.css">
+<link rel="stylesheet" href="/static/css/resource_types.css">
+<script src="/static/js/classes/XAlert.js"></script>
+<script src="/static/js/resource_types.js" defer></script>
+<div class="edit-layout resource-types">
+  <div class="edit-left">
+    {{ if .AlertMessage }}
+    <x-alert type="{{ .AlertType }}" message="{{ .AlertMessage }}" 
visible="true"></x-alert>
+    {{ end }}
+    <h1><i class="fas fa-code page" aria-hidden="true"></i> Add Resource
+      <a href="/cib/live/resources" class="btn btn-default pull-right"><i 
class="fas fa-list" aria-hidden="true"></i> List</a>
+    </h1>
+    <ul class="nav nav-pills nav-stacked resource-type-list">
+      {{ range .ResourceTypes }}
+      <li>
+        <a class="resource-type-link" href="/cib/live/{{ .Path }}/new" 
data-resource-type="{{ .Path }}"{{ if eq .Path "clones" }} 
data-help-filter=".clone"{{ else if eq .Path "groups" }} 
data-help-filter=".group"{{ end }} aria-describedby="help-{{ .Path }}">
+          <span class="resource-type-icon" aria-hidden="true">{{ if eq .Path 
"masters" }}<span>x<sup>2</sup></span>{{ else }}<i class="{{ if or (eq .Path 
"primitives") (eq .Path "clones") }}far{{ else }}fas{{ end }} fa-{{ .Icon 
}}"></i>{{ end }}</span>
+          <span class="resource-type-name">{{ .Name }}</span>
+          <i class="fas fa-circle-plus resource-type-add" 
aria-hidden="true"></i>
+        </a>
+      </li>
+      {{ end }}
+    </ul>
+  </div>
+  <aside class="edit-right" aria-label="Resource help">
+    <h2>Resources</h2>
+    <p>Configure a cluster resource for each service or application that you 
want to make highly available, such as a Web server, database, file system or 
virtual machine.</p>
+    <p>Set up the service or application first, and ensure its requirements 
are met on every cluster node before configuring and starting the resource.</p>
+    {{ range .ResourceTypes }}
+    <section id="help-{{ .Path }}" class="resource-type-help">
+      <h3>{{ .Name }}</h3>
+      <p>{{ .Help }}</p>
+    </section>
+    {{ end }}
+  </aside>
+</div>
+{{ end }}

++++++ vendor.tar.gz ++++++

Reply via email to