Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMM-12573 Update podman via UI. #3128

Merged
merged 13 commits into from
Oct 21, 2024
8 changes: 8 additions & 0 deletions build/packer/ansible/roles/podman-setup/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@
group: admin
mode: '0644'

- name: Copy watchtower environment file for service to user-specific directory
template:
src: watchtower.env
dest: /home/admin/.config/systemd/user/
owner: admin
group: admin
mode: '0644'

- name: Copy watchtower systemd service file to user-specific directory
template:
src: watchtower.service
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PMM_WATCHTOWER_HOST=http://watchtower:8080
PMM_WATCHTOWER_TOKEN=123
PMM_SERVER_UPDATE_VERSION=docker.io/perconalab/pmm-server:3-dev-container
PMM_DEV_UPDATE_DOCKER_IMAGE=docker.io/perconalab/pmm-server:3-dev-container
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be dropped before GA

PMM_IMAGE={{ pmm_server_image_name }}
PMM_DISTRIBUTION_METHOD={{ pmm_distribution_method }}
PMM_DISTRIBUTION_METHOD={{ pmm_distribution_method }}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ RestartSec=20
ExecStart=/usr/bin/podman run \
--volume /home/admin/volume/srv:/srv \
--volume /home/admin/.ssh/:/home/pmm/.ssh/ \
--volume /home/admin/.config/:/home/pmm/config/ \
--volume /home/admin/.config/systemd/user/:/home/pmm/update/ \
--rm --replace=true --name %N \
--env-file=/home/admin/.config/systemd/user/pmm-server.env \
--net pmm_default \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
WATCHTOWER_HTTP_API_UPDATE=1
WATCHTOWER_HTTP_API_TOKEN=123
WATCHTOWER_NO_RESTART=1
WATCHTOWER_DEBUG=1
WATCHTOWER_CLEANUP=1
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,14 @@ After=time-sync.target
[Service]
Restart=on-failure
RestartSec=20

Environment=WATCHTOWER_HTTP_API_UPDATE=1
Environment=WATCHTOWER_HTTP_API_TOKEN=123
Environment=WATCHTOWER_NO_RESTART=1
Environment=WATCHTOWER_DEBUG=1
EnvironmentFile=/home/admin/.config/systemd/user/watchtower.env

ExecStart=/usr/bin/podman run --rm --replace=true --name %N \
-v ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/docker.sock \
-e WATCHTOWER_HTTP_API_UPDATE=${WATCHTOWER_HTTP_API_UPDATE} \
-e WATCHTOWER_HTTP_API_TOKEN=${WATCHTOWER_HTTP_API_TOKEN} \
-e WATCHTOWER_NO_RESTART=${WATCHTOWER_NO_RESTART} \
-e WATCHTOWER_DEBUG=${WATCHTOWER_DEBUG} \
--env-file=/home/admin/.config/systemd/user/watchtower.env \
--net pmm_default \
--cap-add=net_admin,net_raw \
-p 8080:8080/tcp docker.io/perconalab/watchtower
docker.io/perconalab/watchtower

ExecStop=/usr/bin/podman stop -t 10 %N

Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ services:
- PMM_WATCHTOWER_HOST=${PMM_WATCHTOWER_HOST:-http://watchtower:8080}
- PMM_WATCHTOWER_TOKEN=${PMM_WATCHTOWER_TOKEN:-INSECURE_TOKEN}
- PMM_RELEASE_VERSION=3.0.0-alpha
# - PMM_DISTRIBUTION_METHOD=${PMM_DISTRIBUTION_METHOD:-docker}
- PMM_DEV_UPDATE_DOCKER_IMAGE=${PMM_DEV_UPDATE_DOCKER_IMAGE:-}
# - PMM_DEV_VERSION_SERVICE_URL=http://localhost:11000
# - PMM_DEV_PERCONA_PLATFORM_ADDRESS=https://check.localhost
# - PMM_DEV_PERCONA_PLATFORM_INSECURE=1
# - PMM_DEV_PERCONA_PLATFORM_PUBLIC_KEY=<public key>
# - PMM_DEV_TELEMETRY_INTERVAL=10s
# - PMM_DEV_TELEMETRY_DISABLE_START_DELAY=1
Expand Down Expand Up @@ -80,6 +84,7 @@ services:
volumes:
- ./:/root/go/src/github.com/percona/pmm
- ./Makefile.devcontainer:/root/go/src/github.com/percona/pmm/Makefile:ro # substitute Makefile in devcontainer
- ./managed/testdata/updater/:/home/pmm/.config/systemd/user/
# caching
- go-modules:/root/go/pkg/mod
- root-cache:/root/.cache
Expand All @@ -103,6 +108,7 @@ services:
- WATCHTOWER_HTTP_LISTEN_PORT=8080
- WATCHTOWER_HTTP_API_UPDATE=1
- WATCHTOWER_HTTP_API_TOKEN=${PMM_WATCHTOWER_TOKEN:-INSECURE_TOKEN}
- WATCHTOWER_NO_RESTART=${WATCHTOWER_NO_RESTART:-0}
hostname: watchtower
networks:
- ${NETWORK:-default}
Expand Down
35 changes: 35 additions & 0 deletions managed/services/server/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const (
updateCheckInterval = 24 * time.Hour
updateCheckResultFresh = updateCheckInterval + 10*time.Minute
updateDefaultTimeout = 30 * time.Second
envfilePath = "/home/pmm/update/pmm-server.env"
)

var fileName = "/etc/pmm-server-update-version.json"
Expand Down Expand Up @@ -173,6 +174,19 @@ func (up *Updater) StartUpdate(ctx context.Context, newImageName string) error {
return grpcstatus.Errorf(codes.FailedPrecondition, "failed to check watchtower host")
}

if _, e := os.Stat(envfilePath); e == nil {
err := up.updatePodmanEnvironmentVariables(envfilePath, newImageName)
if err != nil {
up.running = false
up.l.WithError(err).Error("Failed to update environment variables file")
return errors.Wrap(err, "failed to update environment variables file")
}
} else if !os.IsNotExist(e) {
up.running = false
up.l.WithError(e).Error("Failed to check environment variables file")
return errors.Wrap(e, "failed to check environment variables file")
}

if err := up.sendRequestToWatchtower(ctx, newImageName); err != nil {
up.running = false
up.l.WithError(err).Error("Failed to trigger update")
Expand Down Expand Up @@ -475,6 +489,27 @@ func (up *Updater) checkWatchtowerHost() error {
return nil
}

func (up *Updater) updatePodmanEnvironmentVariables(filename string, name string) error {
if len(strings.Split(name, "/")) < 3 {
name = "docker.io/" + name
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

podman requires full name to update.

}
file, err := os.ReadFile(filename)
if err != nil {
return errors.Wrap(err, "failed to read file")
}
lines := strings.Split(string(file), "\n")
for i, line := range lines {
if strings.Contains(line, "PMM_IMAGE") {
lines[i] = fmt.Sprintf("PMM_IMAGE=%s", name)
}
}
err = os.WriteFile(filename, []byte(strings.Join(lines, "\n")), 0o644)
if err != nil {
return errors.Wrap(err, "failed to write file")
}
return nil
}

func isHostAvailable(host string, port string, timeout time.Duration) bool {
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout)
if err != nil {
Expand Down
23 changes: 23 additions & 0 deletions managed/services/server/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
func TestUpdater(t *testing.T) {
gRPCMessageMaxSize := uint32(100 * 1024 * 1024)
watchtowerURL, _ := url.Parse("http://watchtower:8080")
const tmpDistributionFile = "/tmp/distribution"

t.Run("TestNextVersion", func(t *testing.T) {
type args struct {
Expand Down Expand Up @@ -292,4 +293,26 @@ func TestUpdater(t *testing.T) {
assert.Equal(t, "2.41.1", latest.DockerImage)
assert.Equal(t, time.Date(2024, 3, 20, 15, 48, 7, 145620000, time.UTC), latest.BuildTime)
})

t.Run("TestUpdateEnvFile", func(t *testing.T) {
u := NewUpdater(watchtowerURL, gRPCMessageMaxSize)
tmpFile := filepath.Join(os.TempDir(), "pmm-service.env")
content := `PMM_WATCHTOWER_HOST=http://watchtower:8080
PMM_WATCHTOWER_TOKEN=123
PMM_SERVER_UPDATE_VERSION=docker.io/perconalab/pmm-server:3-dev-container
PMM_IMAGE=docker.io/perconalab/pmm-server:3-dev-latest
PMM_DISTRIBUTION_METHOD=ami`
err := os.WriteFile(tmpFile, []byte(content), 0o644)
require.NoError(t, err)

err = u.updatePodmanEnvironmentVariables(tmpFile, "perconalab/pmm-server:3-dev-container")
require.NoError(t, err)
newContent, err := os.ReadFile(tmpFile)
require.NoError(t, err)
assert.Equal(t, `PMM_WATCHTOWER_HOST=http://watchtower:8080
PMM_WATCHTOWER_TOKEN=123
PMM_SERVER_UPDATE_VERSION=docker.io/perconalab/pmm-server:3-dev-container
PMM_IMAGE=docker.io/perconalab/pmm-server:3-dev-container
PMM_DISTRIBUTION_METHOD=ami`, string(newContent))
})
}
4 changes: 4 additions & 0 deletions managed/testdata/updater/pmm-server.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PMM_WATCHTOWER_HOST=http://watchtower:8080
PMM_WATCHTOWER_TOKEN=123
PMM_IMAGE=docker.io/perconalab/pmm-server:3-dev-latest
PMM_DISTRIBUTION_METHOD=ami
Loading