fix: enable orderly poweroff in hyper-v on Azure

Previously Talos would not shutdown gracefully if hyper-v issued the
'perform_shutdown' call. Said call would execute '/sbin/poweroff' which
did not exist in Talos. We hardlink machined to '/sbin/poweroff' and
make it send a shutdown API call to PID 1 machined.

Fixes #5641

Signed-off-by: Philipp Sauter <philipp.sauter@siderolabs.com>
This commit is contained in:
Philipp Sauter 2022-06-13 18:10:53 +02:00
parent 35475ce45b
commit f54d907871
No known key found for this signature in database
GPG Key ID: D3F8AF32D62A348D
3 changed files with 51 additions and 0 deletions

View File

@ -419,6 +419,9 @@ COPY --from=pkg-util-linux-amd64 /lib/libmount.* /rootfs/lib/
COPY --from=pkg-kmod-amd64 /usr/lib/libkmod.* /rootfs/lib/
COPY --from=pkg-kernel-amd64 /lib/modules /rootfs/lib/modules
COPY --from=machined-build-amd64 /machined /rootfs/sbin/init
# the orderly_poweroff call by the kernel will call '/sbin/poweroff'
RUN ln /rootfs/sbin/init /rootfs/sbin/poweroff
RUN chmod +x /rootfs/sbin/poweroff
# NB: We run the cleanup step before creating extra directories, files, and
# symlinks to avoid accidentally cleaning them up.
COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh
@ -462,6 +465,9 @@ COPY --from=pkg-util-linux-arm64 /lib/libmount.* /rootfs/lib/
COPY --from=pkg-kmod-arm64 /usr/lib/libkmod.* /rootfs/lib/
COPY --from=pkg-kernel-arm64 /lib/modules /rootfs/lib/modules
COPY --from=machined-build-arm64 /machined /rootfs/sbin/init
# the orderly_poweroff call by the kernel will call '/sbin/poweroff'
RUN ln /rootfs/sbin/init /rootfs/sbin/poweroff
RUN chmod +x /rootfs/sbin/poweroff
# NB: We run the cleanup step before creating extra directories, files, and
# symlinks to avoid accidentally cleaning them up.
COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh

View File

@ -30,6 +30,7 @@ import (
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/app/machined/pkg/system/services"
"github.com/talos-systems/talos/internal/app/poweroff"
"github.com/talos-systems/talos/internal/app/trustd"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/pkg/machinery/api/common"
@ -302,6 +303,11 @@ func main() {
case "/trustd":
trustd.Main()
return
// Azure uses the hv_utils kernel module to shutdown the node in hyper-v by calling perform_shutdown which will call orderly_poweroff which will call /sbin/poweroff.
case "/sbin/poweroff":
poweroff.Main()
return
default:
}

View File

@ -0,0 +1,39 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package poweroff
import (
"context"
"fmt"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"github.com/talos-systems/talos/pkg/grpc/middleware/authz"
"github.com/talos-systems/talos/pkg/machinery/client"
"github.com/talos-systems/talos/pkg/machinery/constants"
"github.com/talos-systems/talos/pkg/machinery/role"
)
// Main is the entrypoint into /sbin/poweroff.
func Main() {
ctx := context.Background()
md := metadata.Pairs()
authz.SetMetadata(md, role.MakeSet(role.Admin))
adminCtx := metadata.NewOutgoingContext(ctx, md)
client, err := client.New(adminCtx, client.WithUnixSocket(constants.APISocketPath), client.WithGRPCDialOptions(grpc.WithTransportCredentials(insecure.NewCredentials())))
if err != nil {
log.Fatalf(fmt.Errorf("error while creating machinery client: %w", err).Error())
}
err = client.Shutdown(adminCtx)
if err != nil {
log.Fatalf(fmt.Errorf("error while sending shutdown command: %w", err).Error())
}
}