Skip to content

Commit 5b99fc5

Browse files
authored
Merge pull request #101 from AkihiroSuda/lock-dir
sshutil: lock ${LIMA_HOME}/_config
2 parents c1a0fb7 + 2e4f8cf commit 5b99fc5

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/sirupsen/logrus v1.8.1
2222
github.com/urfave/cli/v2 v2.3.0
2323
github.com/yalue/native_endian v1.0.1
24+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
2425
gopkg.in/yaml.v2 v2.4.0
2526
gotest.tools/v3 v3.0.3
2627
)

go.sum

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,9 @@ golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7w
920920
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
921921
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
922922
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
923-
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
924923
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
924+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
925+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
925926
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
926927
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
927928
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=

pkg/lockutil/lockutil.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// From https://github.com/containerd/nerdctl/blob/v0.9.0/pkg/lockutil/lockutil_linux.go
2+
/*
3+
Copyright The containerd Authors.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package lockutil
19+
20+
import (
21+
"os"
22+
23+
"github.com/pkg/errors"
24+
"github.com/sirupsen/logrus"
25+
"golang.org/x/sys/unix"
26+
)
27+
28+
func WithDirLock(dir string, fn func() error) error {
29+
dirFile, err := os.Open(dir)
30+
if err != nil {
31+
return err
32+
}
33+
defer dirFile.Close()
34+
if err := Flock(dirFile, unix.LOCK_EX); err != nil {
35+
return errors.Wrapf(err, "failed to lock %q", dir)
36+
}
37+
defer func() {
38+
if err := Flock(dirFile, unix.LOCK_UN); err != nil {
39+
logrus.WithError(err).Errorf("failed to unlock %q", dir)
40+
}
41+
}()
42+
return fn()
43+
}
44+
45+
func Flock(f *os.File, flags int) error {
46+
fd := int(f.Fd())
47+
for {
48+
err := unix.Flock(fd, flags)
49+
if err == nil || err != unix.EINTR {
50+
return err
51+
}
52+
}
53+
}

pkg/sshutil/sshutil.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"path/filepath"
99
"strings"
1010

11+
"github.com/AkihiroSuda/lima/pkg/lockutil"
1112
"github.com/AkihiroSuda/lima/pkg/osutil"
1213
"github.com/AkihiroSuda/lima/pkg/store"
1314
"github.com/AkihiroSuda/lima/pkg/store/filenames"
@@ -51,11 +52,16 @@ func DefaultPubKeys() ([]PubKey, error) {
5152
if err := os.MkdirAll(configDir, 0700); err != nil {
5253
return nil, errors.Wrapf(err, "could not create %q directory", configDir)
5354
}
54-
keygenCmd := exec.Command("ssh-keygen", "-t", "ed25519", "-q", "-N", "", "-f",
55-
filepath.Join(configDir, filenames.UserPrivateKey))
56-
logrus.Debugf("executing %v", keygenCmd.Args)
57-
if out, err := keygenCmd.CombinedOutput(); err != nil {
58-
return nil, errors.Wrapf(err, "failed to run %v: %q", keygenCmd.Args, string(out))
55+
if err := lockutil.WithDirLock(configDir, func() error {
56+
keygenCmd := exec.Command("ssh-keygen", "-t", "ed25519", "-q", "-N", "", "-f",
57+
filepath.Join(configDir, filenames.UserPrivateKey))
58+
logrus.Debugf("executing %v", keygenCmd.Args)
59+
if out, err := keygenCmd.CombinedOutput(); err != nil {
60+
return errors.Wrapf(err, "failed to run %v: %q", keygenCmd.Args, string(out))
61+
}
62+
return nil
63+
}); err != nil {
64+
return nil, err
5965
}
6066
}
6167
entry, err := readPublicKey(filepath.Join(configDir, filenames.UserPublicKey))

0 commit comments

Comments
 (0)