Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
DVDAndroid committed Aug 5, 2024
0 parents commit 9396533
Show file tree
Hide file tree
Showing 13 changed files with 636 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
go.work

.idea
*.iml
glance-docker-container-ext*

.git
.gitignore
assets
README.md
compose.sample.yaml
71 changes: 71 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Create and publish a Docker image

on:
release:
types: [ released ]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'

- name: Build app
run: |
# just to check if it builds correctly
GITHUB_SHA=$(echo ${{ github.sha }} | cut -c1-7)
GOOS=linux
GOARCH=amd64
CGO_ENABLED=0
go build --trimpath -o .
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build Docker image
run: |
GITHUB_SHA=$(echo ${{ github.sha }} | cut -c1-7)
VERSION=$(echo ${{ github.ref }} | sed 's/refs\/tags\///')
IMAGE_TAG=${VERSION}-${GITHUB_SHA}
docker build -t img -f Dockerfile .
# make IMAGE_NAME lowercase
IMAGE_NAME=$(echo ${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]')
major=$(echo $VERSION | cut -d. -f1)
minor=$(echo $VERSION | cut -d. -f2)
tag_major="$major"
tag_minor="$major.$minor"
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:${tag_major}
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:${tag_minor}
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:${VERSION}
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:${IMAGE_TAG}
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:${GITHUB_SHA}
docker tag img ${{ env.REGISTRY }}/${IMAGE_NAME}:latest
- name: Push Docker image
run: |
# make IMAGE_NAME lowercase
IMAGE_NAME=$(echo ${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]')
docker push -a ${{ env.REGISTRY }}/${IMAGE_NAME}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
go.work

.idea
*.iml
glance-docker-container-ext*
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM golang:1.22-alpine AS builder

WORKDIR /build
COPY . .

RUN go mod download
RUN CGO_ENABLED=0 go build --trimpath -o glance-docker-container-ext .

FROM alpine:latest

WORKDIR /app

COPY --from=builder /build/glance-docker-container-ext .
COPY widget.gohtml /app/widget.gohtml

CMD ["./glance-docker-container-ext"]

68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
glance-docker-container-ext
===

[Glance](https://github.com/glanceapp/glance) extension that creates a widget that displays the Docker containers running.

![Sample Screenshot](./assets/screen.png)

## Installation

Assuming you are using Docker compose, add the following to your `docker-compose.yml` file containing Glance container:

```yaml
glance-docker-container-ext:
image: ghcr.io/dvdandroid/glance-docker-container-ext
container_name: glance-docker-container-ext
restart: unless-stopped
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
- PORT=8081 # Optional, default is 8081
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
then in your `glance.yml` config file, add the following:

```yaml
- type: extension
allow-potentially-dangerous-html: true
url: http://glance-docker-container-ext:8081
cache: 5m
parameters:
title: Docker Containers
all: true
order: name,status
```

### Parameters

| Parameter | Description | Default |
|-----------------|--------------------------------------------------------------------------------------------------------------------------|---------------------|
| `title` | Title of the widget | "Docker Containers" |
| `all` | Show all containers or only running ones | `true` |
| `order` | Order of the containers, comma separated **string** of `name`, `status`<br>(`name`,`status`,`name,status`,`status,name`) | `name` |
| `same-tab` | Open the URL in the same tab. Value customizable per container | `false` |
| `ignore-status` | Status of the containers will not be displayed | `false` |

## Configuration

Then, for every container you want to monitor, add the following labels:

```yaml
labels:
glance.enable: true
glance.name: Sonarr
glance.description: TV show search
glance.url: http://sonarr.lan
glance.icon: ./assets/imgs/television-classic.svg
```

| Label | Description | Default |
|----------------------|-------------------------------------------------------------------|----------------|
| `glance.enable` | Enable monitoring for this container | |
| `glance.name` | Name of the container | container name |
| `glance.description` | Description of the container | |
| `glance.url` | URL to open when clicking on the container | |
| `glance.icon` | Icon to display, pointing to assets or Simple Icon (`si:` prefix) | |
| `glance.same-tab` | Open the URL in the same tab | `false` |

Binary file added assets/screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions compose.sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
services:
glance:
image: ghcr.io/dvdandroid/glance:2024-08-05-5da1768
container_name: glance
restart: unless-stopped
volumes:
- ./glance/glance.yml:/app/glance.yml
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
networks:
- ....
- glance-network

glance-docker-container-ext:
image: ghcr.io/dvdandroid/glance-docker-container-ext
container_name: glance-docker-container-ext
restart: unless-stopped
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- glance-network

networks:
glance-network:
name: glance-network
driver_opts:
com.docker.network.bridge.name: br-glance
107 changes: 107 additions & 0 deletions docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
docker "github.com/fsouza/go-dockerclient"
"sort"
"strings"
)

type DockerContainer struct {
Name string
Description string
State string // created|restarting|running|removing|paused|exited|dead
Status string
Icon string
IsSvgIcon bool
URL string
SameTab bool
}

func LoadContainers(dockerClient *docker.Client, p params) ([]DockerContainer, error) {
containerList, err := dockerClient.ListContainers(docker.ListContainersOptions{
All: p.AllContainers,
Filters: map[string][]string{
"label": {"glance.enable=true"},
},
})

if err != nil {
return nil, err
}

containers := make([]DockerContainer, len(containerList))
for i, container := range containerList {
name := container.Names[0][1:]
description := ""
url := ""
icon := ""
sameTab := false

for label, value := range container.Labels {
if value == "" {
continue
}
switch label {
case "glance.name":
name = value
case "glance.description":
description = value
case "glance.icon":
icon = value
if strings.HasPrefix(value, "si:") {
icon = strings.TrimPrefix(value, "si:")
icon = "https://cdnjs.cloudflare.com/ajax/libs/simple-icons/11.14.0/" + icon + ".svg"
}
case "glance.url":
url = value
case "glance.same-tab":
sameTab = value == "true"
}
}

state := container.State
if p.IgnoreStatus {
state = ""
}

containers[i] = DockerContainer{
Name: name,
Description: description,
State: state,
Status: container.Status,
Icon: icon,
IsSvgIcon: strings.Contains(icon, "/simple-icons/") || strings.HasSuffix(icon, ".svg"),
URL: url,
SameTab: p.SameTab || sameTab,
}
}

sortContainers(containers, strings.Split(p.Order, ","))

return containers, nil
}

func sortContainers(containers []DockerContainer, order []string) {
sort.Slice(containers, func(i, j int) bool {
for _, field := range order {
switch field {
case "name":
name1 := strings.ToLower(containers[i].Name)
name2 := strings.ToLower(containers[j].Name)
if name1 != name2 {
return name1 < name2
}
description1 := strings.ToLower(containers[i].Description)
description2 := strings.ToLower(containers[j].Description)
if description1 != description2 {
return description1 < description2
}
case "status":
if containers[i].State != containers[j].State {
return containers[i].State < containers[j].State
}
}
}
return false
})
}
29 changes: 29 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module glance-docker-container-ext

go 1.22

require github.com/fsouza/go-dockerclient v1.11.1

require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/containerd/containerd v1.6.26 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/docker/docker v27.0.3+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gorilla/schema v1.4.1 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/user v0.1.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.22.0 // indirect
)
Loading

0 comments on commit 9396533

Please sign in to comment.