/
setupwriters.go
122 lines (108 loc) · 3.39 KB
/
setupwriters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"flag"
"fmt"
"os"
"path/filepath"
"upspin.io/client"
"upspin.io/config"
"upspin.io/errors"
"upspin.io/subcmd"
"upspin.io/upspin"
"upspin.io/user"
)
func (s *State) setupwriters(args ...string) {
const help = `
Setupwriters creates or updates the Writers file for the given domain.
The file lists the names of users granted access to write to the domain's
store server and to create their own root on the directory server.
A wildcard permits access to all users of a domain ("*@example.com").
The user name of the project's directory server is automatically included in
the list, so the directory server can use the store for its own data storage.
`
fs := flag.NewFlagSet("setupwriters", flag.ExitOnError)
where := fs.String("where", filepath.Join(config.Home(), "upspin", "deploy"), "`directory` containing private configuration files")
domain := fs.String("domain", "", "domain `name` for this Upspin installation")
s.ParseFlags(fs, args, help, "setupwriters [-where=$HOME/upspin/deploy] -domain=<domain> <user names>")
if *where == "" {
s.Failf("the -where flag must not be empty")
usageAndExit(fs)
}
if *domain == "" {
s.Failf("the -domain must not be empty")
usageAndExit(fs)
}
var users []upspin.UserName
for _, arg := range fs.Args() {
u, err := user.Clean(upspin.UserName(arg))
if err != nil {
s.Exit(err)
}
users = append(users, u)
}
cfgDir := filepath.Join(subcmd.Tilde(*where), *domain)
if fi, err := os.Stat(cfgDir); err != nil {
s.Exitf("error reading configuration directory: %v", err)
} else if !fi.IsDir() {
s.Exitf("specified location is not a directory: %v", cfgDir)
}
var dirUser upspin.UserName
storeCfg, err := config.FromFile(filepath.Join(cfgDir, "config"))
if errors.Is(errors.NotExist, err) {
storeCfg, err = config.FromFile(filepath.Join(cfgDir, "storeserver", "config"))
if err != nil {
s.Exit(err)
}
dirCfg, err := config.FromFile(filepath.Join(cfgDir, "dirserver", "config"))
if err != nil {
s.Exit(err)
}
// Created by setupdomain -cluster, separate users for dir and store.
dirUser = dirCfg.UserName()
} else if err != nil {
s.Exit(err)
} else {
// Created by setupdomain -cluster=false, one user for dir and store.
dirUser = storeCfg.UserName()
}
storeUser := storeCfg.UserName()
// Act as the store user.
c := client.New(storeCfg)
// Make the store root.
_, err = c.MakeDirectory(upspin.PathName(storeUser) + "/")
if err != nil && !errors.Is(errors.Exist, err) {
s.Exit(err)
}
// Make the Group directory.
_, err = c.MakeDirectory(upspin.PathName(storeUser) + "/Group")
if err != nil && !errors.Is(errors.Exist, err) {
s.Exit(err)
}
// Prepare Access file and put it to the server.
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "*:%v\n", storeUser)
if dirUser != storeUser {
fmt.Fprintf(buf, "l,r:%v\n", dirUser)
}
_, err = c.Put(upspin.PathName(storeUser)+"/Access", buf.Bytes())
if err != nil {
s.Exit(err)
}
// Prepare Writers file and put it to the server.
buf.Reset()
fmt.Fprintln(buf, storeUser)
if dirUser != storeUser {
fmt.Fprintln(buf, dirUser)
}
for _, u := range users {
fmt.Fprintln(buf, u)
}
_, err = c.Put(upspin.PathName(storeUser)+"/Group/Writers", buf.Bytes())
if err != nil {
s.Exit(err)
}
}