mirror of
https://github.com/cuigh/swirl
synced 2024-12-28 14:51:57 +00:00
Finish image management
This commit is contained in:
parent
722c7e3e09
commit
5693f1426e
@ -1944,4 +1944,44 @@ var Swirl;
|
||||
Volume.NewPage = NewPage;
|
||||
})(Volume = Swirl.Volume || (Swirl.Volume = {}));
|
||||
})(Swirl || (Swirl = {}));
|
||||
var Swirl;
|
||||
(function (Swirl) {
|
||||
var Image;
|
||||
(function (Image) {
|
||||
var Modal = Swirl.Core.Modal;
|
||||
var Table = Swirl.Core.ListTable;
|
||||
class ListPage {
|
||||
constructor() {
|
||||
this.table = new Table("#table-items");
|
||||
this.table.on("delete-image", this.deleteImage.bind(this));
|
||||
$("#btn-delete").click(this.deleteImages.bind(this));
|
||||
}
|
||||
deleteImage(e) {
|
||||
let $tr = $(e.target).closest("tr");
|
||||
let name = $tr.find("td:eq(1)").text().trim();
|
||||
let id = $tr.find(":checkbox:first").val();
|
||||
Modal.confirm(`Are you sure to remove image: <strong>${name}</strong>?`, "Delete image", (dlg, e) => {
|
||||
$ajax.post("delete", { ids: id }).trigger(e.target).encoder("form").json(() => {
|
||||
$tr.remove();
|
||||
dlg.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
deleteImages() {
|
||||
let ids = this.table.selectedKeys();
|
||||
if (ids.length == 0) {
|
||||
Modal.alert("Please select one or more items.");
|
||||
return;
|
||||
}
|
||||
Modal.confirm(`Are you sure to remove ${ids.length} images?`, "Delete images", (dlg, e) => {
|
||||
$ajax.post("delete", { ids: ids.join(",") }).trigger(e.target).encoder("form").json(() => {
|
||||
this.table.selectedRows().remove();
|
||||
dlg.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Image.ListPage = ListPage;
|
||||
})(Image = Swirl.Image || (Swirl.Image = {}));
|
||||
})(Swirl || (Swirl = {}));
|
||||
//# sourceMappingURL=swirl.js.map
|
File diff suppressed because one or more lines are too long
45
assets/swirl/ts/image/list.ts
Normal file
45
assets/swirl/ts/image/list.ts
Normal file
@ -0,0 +1,45 @@
|
||||
///<reference path="../core/core.ts" />
|
||||
namespace Swirl.Image {
|
||||
import Modal = Swirl.Core.Modal;
|
||||
import AjaxResult = Swirl.Core.AjaxResult;
|
||||
import Table = Swirl.Core.ListTable;
|
||||
|
||||
export class ListPage {
|
||||
private table: Table;
|
||||
|
||||
constructor() {
|
||||
this.table = new Table("#table-items");
|
||||
|
||||
// bind events
|
||||
this.table.on("delete-image", this.deleteImage.bind(this));
|
||||
$("#btn-delete").click(this.deleteImages.bind(this));
|
||||
}
|
||||
|
||||
private deleteImage(e: JQueryEventObject) {
|
||||
let $tr = $(e.target).closest("tr");
|
||||
let name = $tr.find("td:eq(1)").text().trim();
|
||||
let id = $tr.find(":checkbox:first").val();
|
||||
Modal.confirm(`Are you sure to remove image: <strong>${name}</strong>?`, "Delete image", (dlg, e) => {
|
||||
$ajax.post("delete", { ids: id }).trigger(e.target).encoder("form").json<AjaxResult>(() => {
|
||||
$tr.remove();
|
||||
dlg.close();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
private deleteImages() {
|
||||
let ids = this.table.selectedKeys();
|
||||
if (ids.length == 0) {
|
||||
Modal.alert("Please select one or more items.");
|
||||
return;
|
||||
}
|
||||
|
||||
Modal.confirm(`Are you sure to remove ${ids.length} images?`, "Delete images", (dlg, e) => {
|
||||
$ajax.post("delete", { ids: ids.join(",") }).trigger(e.target).encoder("form").json<AjaxResult>(() => {
|
||||
this.table.selectedRows().remove();
|
||||
dlg.close();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -53,9 +53,12 @@ func ContainerInspect(id string) (container types.ContainerJSON, err error) {
|
||||
|
||||
// ContainerInspectRaw return container raw information.
|
||||
func ContainerInspectRaw(id string) (container types.ContainerJSON, raw []byte, err error) {
|
||||
mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
container, raw, err = cli.ContainerInspectWithRaw(ctx, id, true)
|
||||
return
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
// ImageList return images on the host.
|
||||
@ -38,3 +42,36 @@ func ImageList(name string, pageIndex, pageSize int) (images []*model.ImageListI
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ImageInspect returns image information.
|
||||
func ImageInspect(id string) (image types.ImageInspect, raw []byte, err error) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
return cli.ImageInspectWithRaw(ctx, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ImageHistory returns the changes in an image in history format.
|
||||
func ImageHistory(id string) (histories []image.HistoryResponseItem, err error) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
return cli.ImageHistory(ctx, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ImageRemove remove a image.
|
||||
func ImageRemove(id string) error {
|
||||
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
|
||||
opts := types.ImageRemoveOptions{}
|
||||
_, err = cli.ImageRemove(ctx, id, opts)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
@ -99,18 +99,24 @@ func NetworkDisconnect(name, container string) error {
|
||||
|
||||
// NetworkInspect return network information.
|
||||
func NetworkInspect(name string) (network types.NetworkResource, err error) {
|
||||
mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
network, err = cli.NetworkInspect(ctx, name, types.NetworkInspectOptions{})
|
||||
return
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NetworkInspectRaw return network raw information.
|
||||
func NetworkInspectRaw(name string) (raw []byte, err error) {
|
||||
mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
_, raw, err = cli.NetworkInspectWithRaw(ctx, name, types.NetworkInspectOptions{})
|
||||
return
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -51,10 +51,13 @@ func NodeRemove(id string) error {
|
||||
|
||||
// NodeInspect return node information.
|
||||
func NodeInspect(id string) (node swarm.Node, raw []byte, err error) {
|
||||
mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
|
||||
node, raw, err = cli.NodeInspectWithRaw(ctx, id)
|
||||
return
|
||||
})
|
||||
var (
|
||||
ctx context.Context
|
||||
cli *client.Client
|
||||
)
|
||||
if ctx, cli, err = mgr.Client(); err == nil {
|
||||
return cli.NodeInspectWithRaw(ctx, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/auxo/util/cast"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
@ -51,13 +49,12 @@ func Container() (c *ContainerController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Container", container).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("Container", container).Add("Raw", j)
|
||||
return ctx.Render("container/raw", m)
|
||||
}
|
||||
|
||||
|
@ -1,34 +1,83 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/auxo/util/cast"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
type ImageController struct {
|
||||
List web.HandlerFunc `path:"/" name:"image.list" authorize:"!" desc:"image list page"`
|
||||
//Detail web.HandlerFunc `path:"/:id/detail" name:"image.detail" authorize:"!" desc:"image detail page"`
|
||||
//Raw web.HandlerFunc `path:"/:id/raw" name:"image.raw" authorize:"!" desc:"image raw page"`
|
||||
List web.HandlerFunc `path:"/" name:"image.list" authorize:"!" desc:"image list page"`
|
||||
Detail web.HandlerFunc `path:"/:id/detail" name:"image.detail" authorize:"!" desc:"image detail page"`
|
||||
Raw web.HandlerFunc `path:"/:id/raw" name:"image.raw" authorize:"!" desc:"image raw page"`
|
||||
Delete web.HandlerFunc `path:"/delete" method:"post" name:"image.delete" authorize:"!" desc:"delete image"`
|
||||
}
|
||||
|
||||
func Image() (c *ImageController) {
|
||||
c = &ImageController{}
|
||||
return &ImageController{
|
||||
List: imageList,
|
||||
Detail: imageDetail,
|
||||
Raw: imageRaw,
|
||||
Delete: imageDelete,
|
||||
}
|
||||
}
|
||||
|
||||
c.List = func(ctx web.Context) error {
|
||||
name := ctx.Q("name")
|
||||
page := cast.ToIntD(ctx.Q("page"), 1)
|
||||
images, totalCount, err := docker.ImageList(name, page, model.PageSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newPagerModel(ctx, totalCount, model.PageSize, page).
|
||||
Add("Name", name).
|
||||
Add("Images", images)
|
||||
return ctx.Render("image/list", m)
|
||||
func imageList(ctx web.Context) error {
|
||||
name := ctx.Q("name")
|
||||
page := cast.ToIntD(ctx.Q("page"), 1)
|
||||
images, totalCount, err := docker.ImageList(name, page, model.PageSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
m := newPagerModel(ctx, totalCount, model.PageSize, page).
|
||||
Add("Name", name).
|
||||
Add("Images", images)
|
||||
return ctx.Render("image/list", m)
|
||||
}
|
||||
|
||||
func imageDetail(ctx web.Context) error {
|
||||
id := ctx.P("id")
|
||||
image, _, err := docker.ImageInspect(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
histories, err := docker.ImageHistory(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Image", image).Add("Histories", histories)
|
||||
return ctx.Render("image/detail", m)
|
||||
}
|
||||
|
||||
func imageRaw(ctx web.Context) error {
|
||||
id := ctx.P("id")
|
||||
image, raw, err := docker.ImageInspect(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Image", image).Add("Raw", j)
|
||||
return ctx.Render("image/raw", m)
|
||||
}
|
||||
|
||||
func imageDelete(ctx web.Context) error {
|
||||
ids := strings.Split(ctx.F("ids"), ",")
|
||||
for _, id := range ids {
|
||||
if err := docker.ImageRemove(id); err != nil {
|
||||
return ajaxResult(ctx, err)
|
||||
}
|
||||
}
|
||||
return ajaxSuccess(ctx, nil)
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/swirl/biz"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
@ -88,13 +86,12 @@ func Network() (c *NetworkController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Network", name).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("Network", name).Add("Raw", j)
|
||||
return ctx.Render("network/raw", m)
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
@ -60,13 +58,12 @@ func Node() (c *NodeController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("ID", id).Add("Node", node).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("ID", id).Add("Node", node).Add("Raw", j)
|
||||
return ctx.Render("node/raw", m)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -12,6 +11,7 @@ import (
|
||||
"github.com/cuigh/auxo/util/cast"
|
||||
"github.com/cuigh/swirl/biz"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
@ -77,13 +77,12 @@ func Service() (c *ServiceController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Service", name).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("Service", name).Add("Raw", j)
|
||||
return ctx.Render("service/raw", m)
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
)
|
||||
|
||||
type TaskController struct {
|
||||
@ -34,13 +32,12 @@ func Task() (c *TaskController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Task", task).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("Task", task).Add("Raw", j)
|
||||
return ctx.Render("task/raw", m)
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/cuigh/auxo/net/web"
|
||||
"github.com/cuigh/auxo/util/cast"
|
||||
"github.com/cuigh/swirl/biz"
|
||||
"github.com/cuigh/swirl/biz/docker"
|
||||
"github.com/cuigh/swirl/misc"
|
||||
"github.com/cuigh/swirl/model"
|
||||
)
|
||||
|
||||
@ -94,13 +93,12 @@ func Volume() (c *VolumeController) {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
j, err := misc.JSONIndent(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := newModel(ctx).Add("Volume", name).Add("Raw", string(buf.Bytes()))
|
||||
m := newModel(ctx).Add("Volume", name).Add("Raw", j)
|
||||
return ctx.Render("volume/raw", m)
|
||||
}
|
||||
|
||||
|
15
misc/util.go
15
misc/util.go
@ -1,8 +1,11 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Funcs = map[string]interface{}{
|
||||
@ -32,6 +35,9 @@ var Funcs = map[string]interface{}{
|
||||
}
|
||||
return s
|
||||
},
|
||||
"trimPrefix": func(s, prefix string) string {
|
||||
return strings.TrimPrefix(s, prefix)
|
||||
},
|
||||
"slice": func(values ...interface{}) interface{} {
|
||||
return values
|
||||
},
|
||||
@ -47,3 +53,12 @@ func Page(count, pageIndex, pageSize int) (start, end int) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func JSONIndent(raw []byte) (s string, err error) {
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, raw, "", " ")
|
||||
if err == nil {
|
||||
s = buf.String()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
113
views/image/detail.jet
Normal file
113
views/image/detail.jet
Normal file
@ -0,0 +1,113 @@
|
||||
{{ extends "../_layouts/default" }}
|
||||
{{ import "../_modules/detail" }}
|
||||
|
||||
{{ block body() }}
|
||||
<section class="hero is-info">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-2">
|
||||
IMAGE
|
||||
</h1>
|
||||
<h2 class="subtitle is-5">
|
||||
Manage images.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="container">
|
||||
<nav class="breadcrumb has-succeeds-separator is-small is-marginless" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><a href="/">Dashboard</a></li>
|
||||
<li><a href="/image/">Images</a></li>
|
||||
<li class="is-active"><a>Detail</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<section class="hero is-small is-light">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<h2 class="title is-2">
|
||||
{{ limit(.Image.ID, 32) }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<nav class="navbar has-shadow">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item is-tab is-active" href="/image/{{ .Image.ID }}/detail">
|
||||
Detail
|
||||
</a>
|
||||
<a class="navbar-item is-tab" href="/image/{{ .Image.ID }}/raw">
|
||||
Raw
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
|
||||
<div class="message is-primary">
|
||||
<div class="message-body">
|
||||
<dl class="is-horizontal is-marginless">
|
||||
<dt class="has-text-left">ID</dt>
|
||||
<dd>{{ .Image.ID }}</dd>
|
||||
<dt class="has-text-left">Size</dt>
|
||||
<dd>{{ printf("%0.1f", .Image.Size / 1024 / 1024) }} MB</dd>
|
||||
<dt class="has-text-left">Created at</dt>
|
||||
<dd>{{ .Image.Created }}</dd>
|
||||
<dt class="has-text-left">Docker version</dt>
|
||||
<dd>{{ .Image.DockerVersion }}</dd>
|
||||
<dt class="has-text-left">Platform</dt>
|
||||
<dd>{{ .Image.Os }}/{{ .Image.Architecture }}</dd>
|
||||
{{ if .Image.Author }}
|
||||
<dt class="has-text-left">Author</dt>
|
||||
<dd>{{ .Image.Author }}</dd>
|
||||
{{ end }}
|
||||
{{ if .Image.RepoTags }}
|
||||
<dt class="has-text-left">Tags</dt>
|
||||
{{ range .Image.RepoTags }}
|
||||
<dd><span class="tag is-success">{{ . }}</span></dd>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ if .Histories }}
|
||||
<div class="block">
|
||||
<div class="block-header">
|
||||
<p>Layers</p>
|
||||
</div>
|
||||
<div class="block-body is-paddingless">
|
||||
<table id="table-containers" class="table is-bordered is-striped is-narrow is-fullwidth is-marginless">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Instruction</th>
|
||||
<th>Size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Histories }}
|
||||
<tr>
|
||||
<td>{{ trimPrefix(.CreatedBy, "/bin/sh -c #(nop) ") }}</td>
|
||||
<td>{{ printf("%0.1f", .Size / 1024 / 1024) }} MB</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<a href="/image/" class="button is-primary">
|
||||
<span class="icon"><i class="fa fa-reply"></i></span>
|
||||
<span>Return</span>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
@ -1,6 +1,10 @@
|
||||
{{ extends "../_layouts/default" }}
|
||||
{{ import "../_modules/pager" }}
|
||||
|
||||
{{ block script() }}
|
||||
<script>$(() => new Swirl.Image.ListPage())</script>
|
||||
{{ end }}
|
||||
|
||||
{{ block body() }}
|
||||
<section class="hero is-info">
|
||||
<div class="hero-body">
|
||||
@ -38,14 +42,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right side -->
|
||||
{*<div class="level-right">*}
|
||||
{*<p class="level-item">*}
|
||||
{*<button id="btn-delete" class="button is-danger"><span class="icon"><i class="fa fa-remove"></i></span><span>Delete</span></button>*}
|
||||
{*</p>*}
|
||||
{*<p class="level-item">*}
|
||||
{*<a class="button is-success" href="new"><span class="icon"><i class="fa fa-plus"></i></span><span>New</span></a>*}
|
||||
{*</p>*}
|
||||
{*</div>*}
|
||||
<div class="level-right">
|
||||
<p class="level-item">
|
||||
<button id="btn-delete" class="button is-danger"><span class="icon"><i class="fa fa-remove"></i></span><span>Delete</span></button>
|
||||
</p>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<table id="table-items" class="table is-bordered is-striped is-narrow is-fullwidth">
|
||||
@ -56,14 +57,14 @@
|
||||
<th>Tags</th>
|
||||
<th>Size</th>
|
||||
<th>Created</th>
|
||||
{*<th width="160">Action</th>*}
|
||||
<th width="160">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Images}}
|
||||
<tr>
|
||||
<td><input type="checkbox" value="{{.ID}}" data-action="check"></td>
|
||||
<td>{{ limit(.ID, 30) }}</td>
|
||||
<td><a href="/image/{{ .ID }}/detail">{{ limit(.ID, 30) }}</a></td>
|
||||
<td>
|
||||
<div class="tags">
|
||||
{{range .RepoTags}}
|
||||
@ -73,11 +74,9 @@
|
||||
</td>
|
||||
<td>{{ printf("%0.1f", .Size / 1024 / 1024) }} MB</td>
|
||||
<td>{{ time(.CreatedAt) }}</td>
|
||||
{*<td>*}
|
||||
{*<div class="field has-addons">*}
|
||||
{*<p class="control"><button class="button is-small is-danger is-outlined" data-action="delete-service">Delete</button></p>*}
|
||||
{*</div>*}
|
||||
{*</td>*}
|
||||
<td>
|
||||
<button class="button is-small is-danger is-outlined" data-action="delete-image">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
|
70
views/image/raw.jet
Normal file
70
views/image/raw.jet
Normal file
@ -0,0 +1,70 @@
|
||||
{{ extends "../_layouts/default" }}
|
||||
|
||||
{{ block style() }}
|
||||
<link rel="stylesheet" href="/highlight/highlight.css?v=9.12">
|
||||
{{ end }}
|
||||
|
||||
{{ block script() }}
|
||||
<script src="/highlight/highlight.pack.js?v=9.12"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
{{ end }}
|
||||
|
||||
{{ block body() }}
|
||||
<section class="hero is-info">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<h1 class="title is-2">
|
||||
IMAGE
|
||||
</h1>
|
||||
<h2 class="subtitle is-5">
|
||||
Manage images.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="container">
|
||||
<nav class="breadcrumb has-succeeds-separator is-small is-marginless" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><a href="/">Dashboard</a></li>
|
||||
<li><a href="/image/">Images</a></li>
|
||||
<li class="is-active"><a>Raw</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<section class="hero is-small is-light">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<h2 class="title is-2">
|
||||
{{ limit(.Image.ID, 32) }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<nav class="navbar has-shadow">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item is-tab" href="/image/{{ .Image.ID }}/detail">
|
||||
Detail
|
||||
</a>
|
||||
<a class="navbar-item is-tab is-active" href="/image/{{ .Image.ID }}/raw">
|
||||
Raw
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<pre class="is-paddingless"><code class="json">{{ .Raw }}</code></pre>
|
||||
</div>
|
||||
<a href="/image/" class="button is-primary">
|
||||
<span class="icon"><i class="fa fa-reply"></i></span>
|
||||
<span>Return</span>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
@ -75,7 +75,7 @@
|
||||
</header>
|
||||
<div class="card-content">
|
||||
{*{{yield progress(title="System", percent=0)}}*}
|
||||
{{yield progress(title="Image", percent=30)}}
|
||||
{{yield progress(title="Image", percent=100)}}
|
||||
{{yield progress(title="Container", percent=35)}}
|
||||
{{yield progress(title="Volume", percent=100)}}
|
||||
</div>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<a class="navbar-item is-tab is-active" href="/network/{{.Network.Name}}/detail">
|
||||
Detail
|
||||
</a>
|
||||
<a class="navbar-item is-tab " href="/network/{{.Network.Name}}/raw">
|
||||
<a class="navbar-item is-tab" href="/network/{{.Network.Name}}/raw">
|
||||
Raw
|
||||
</a>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user