Skip to content

Commit

Permalink
Add pivot.service as a host API
Browse files Browse the repository at this point in the history
Add a new systemd service that simply executes `pivot`. But note that we
don't have a `pivot.path` unit to auto-trigger it: this needs to be
triggered explicitly by whatever drives pivot. Making it a service and
standizing on a path in `/etc` means that we can trigger a pivot on boot
from Ignition (patch to preset enable the service is pending), as well
as from the MCD by directly starting the unit.

Related: openshift/machine-config-operator#314
  • Loading branch information
jlebon committed Feb 6, 2019
1 parent 7c5a133 commit 695dc99
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ pivot
*.out
# editor
.vscode

systemd/pivot.service
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LDFLAGS := -X main.version=${VERSION} -X main.commitHash=${COMMIT_HASH} -X main.
PREFIX ?= /usr
CONFIG_DIR ?= /etc
BIN_DIR ?= ${PREFIX}/bin
SYSTEMD_UNIT_DIR ?= ${PREFIX}/lib/systemd/system

.PHONY: help build clean deps install lint static test

Expand All @@ -32,11 +33,14 @@ help:
changelog:
git log --format="- %s" `git tag | tail -n 1`..HEAD

systemd/pivot.service: systemd/pivot.service.in
sed "s,@@PIVOT_BINARY_PATH@@,${BIN_DIR}/pivot,g" < systemd/pivot.service.in > systemd/pivot.service

pivot: Gopkg.* *.go cmd/*.go utils/*.go types/*.go
go build -ldflags '${LDFLAGS}' -o pivot main.go
strip pivot

build: pivot
build: pivot systemd/pivot.service

static: clean
CGO_ENABLED=0 go build -ldflags '${LDFLAGS} -w -extldflags "-static"' -a -o pivot main.go
Expand All @@ -51,6 +55,8 @@ deps:
install: build
install -d ${DESTDIR}${BIN_DIR}
install --mode 755 pivot ${DESTDIR}${BIN_DIR}/pivot
install -d ${DESTDIR}${SYSTEMD_UNIT_DIR}
install --mode 664 systemd/pivot.service ${DESTDIR}${SYSTEMD_UNIT_DIR}

lint:
go get -u github.com/golang/lint/golint
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ Though normally, one wants to use digests rather than tags, e.g.:
pivot -r $REGISTRY/os@sha256:fdf70521df4ed1dc135d81fd3c4608574aeca45dc22d1b4e38d16630e9d6f1a7
```

It also comes with a systemd unit to provide a "host API". For example:

```
mkdir -p /etc/pivot
echo $REGISTRY/os:latest > /etc/pivot/image-pullspec
touch /run/pivot-reboot-needed
systemctl start pivot
```

This will start `pivot`, which will read the file and execute the pivot.
If the pivot is completed, the file will be deleted. The expected way to
make use of this is to create the necessary files from Ignition.

See
---
- [openshift/os](https://github.com/openshift/os/)
Expand Down
49 changes: 35 additions & 14 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package cmd

import (
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"strings"

Expand All @@ -21,22 +21,20 @@ var reboot bool
var container string
var exit_77 bool

// the number of times to retry commands that pull data from the network
const numRetriesNetCommands = 5
const (
// the number of times to retry commands that pull data from the network
numRetriesNetCommands = 5
etcPivotFile = "/etc/pivot/image-pullspec"
runPivotRebootFile = "/run/pivot/reboot-needed"
)

// RootCmd houses the cobra config for the main command
var RootCmd = &cobra.Command{
Use: "pivot [FLAGS] <IMAGE_PULLSPEC>",
Use: "pivot [FLAGS] [IMAGE_PULLSPEC]",
DisableFlagsInUseLine: true,
Short: "Allows moving from one OSTree deployment to another",
// Long: ``,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("An image name must be provided")
}
return nil
},
Run: Execute,
Args: cobra.MaximumNArgs(1),
Run: Execute,
}

// init executes upon import
Expand Down Expand Up @@ -150,9 +148,32 @@ func pullAndRebase(container string) (imgid string, changed bool) {

// Execute runs the command
func Execute(cmd *cobra.Command, args []string) {
container := args[0]
var fromFile bool
var container string
if len(args) > 0 {
container = args[0]
fromFile = false
} else {
glog.Infof("Using image pullspec from %s", etcPivotFile)
data, err := ioutil.ReadFile(etcPivotFile)
if err != nil {
glog.Fatalf("Failed to read from %s: %v", etcPivotFile, err)
}
container = strings.TrimSpace(string(data))
fromFile = true
}

imgid, changed := pullAndRebase(container)

// Delete the file now that we successfully rebased
if fromFile {
if err := os.Remove(etcPivotFile); err != nil {
if !os.IsNotExist(err) {
glog.Fatal("Failed to delete %s: %v", etcPivotFile, err)
}
}
}

// By default, delete the image.
if !keep {
// Related: https://github.com/containers/libpod/issues/2234
Expand All @@ -164,7 +185,7 @@ func Execute(cmd *cobra.Command, args []string) {
if exit_77 {
os.Exit(77)
}
} else if reboot {
} else if reboot || utils.FileExists(runPivotRebootFile) {
// Reboot the machine if asked to do so
utils.Run("systemctl", "reboot")
}
Expand Down
11 changes: 7 additions & 4 deletions pivot.spec
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
%define debug_package %{nil}

Name: pivot
Version: 0.0.2
Release: 0.1%{?dist}
Version: 0.0.3
Release: 1%{?dist}
Summary: allows moving from one OSTree deployment to another

License: ASL 2.0
Expand All @@ -21,7 +21,7 @@ deployment to another with minimal effort.
%prep
%autosetup -n %{name}-%{version}
mkdir -p src/github.com/openshift/%{name}/
cp -rf cmd Gopkg.lock Gopkg.toml LICENSE main.go Makefile pivot.spec README.md types utils vendor VERSION src/github.com/openshift/%{name}
cp -rf cmd Gopkg.lock Gopkg.toml LICENSE main.go Makefile pivot.spec README.md types utils vendor VERSION systemd src/github.com/openshift/%{name}

%build
export GOPATH=`pwd`
Expand All @@ -36,9 +36,12 @@ make install DESTDIR=%{buildroot}
%license LICENSE
%doc README.md
%{_bindir}/%{name}

%{_prefix}/lib/systemd/system/pivot.*

%changelog
* Tue Feb 05 2019 Jonathan Lebon <[email protected]> - 0.0.3-1
- Add systemd service unit

* Wed Nov 14 2018 Steve Milner <[email protected]> - 0.0.2-0.1
- Makefile: Add changelog target
- cmd/root: Print pivoting msg before pull
Expand Down
12 changes: 12 additions & 0 deletions systemd/pivot.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Pivot Tool
ConditionPathExists=/etc/pivot/image-pullspec
After=ignition-firstboot-complete.service
Before=kubelet.service

[Service]
Type=simple
ExecStart=@@PIVOT_BINARY_PATH@@

[Install]
WantedBy=multi-user.target
18 changes: 18 additions & 0 deletions utils/fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package utils

import (
"os"

"github.com/golang/glog"
)

// FileExists checks if the file exists, gracefully handling ENOENT.
func FileExists(path string) bool {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return false
}
glog.Fatalf("Failed to stat %s: %v", path, err)
}
return true
}

0 comments on commit 695dc99

Please sign in to comment.