-
Notifications
You must be signed in to change notification settings - Fork 0
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
Cloudfuse service linux cmd #338
base: main
Are you sure you want to change the base?
Conversation
cmd/service_linux.go
Outdated
Short: "Installs the startup process for Cloudfuse. Requires elevated permissions.", | ||
Long: "Installs the startup process for Cloudfuse which remounts any active previously active mounts on startup. elevated permissions.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These descriptions should probably not refer to "the" startup process, since each call to install
only affects a single mount, and we can use this command to make multiple "startup processes."
} | ||
|
||
var installCmd = &cobra.Command{ | ||
Use: "install", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you require two arguments, the usage string should include those.
cmd/service_linux.go
Outdated
// assumes dir is in cloudfuse repo dir | ||
serviceData, err := collectServiceData(fmt.Sprintf("%s/setup/cloudfuse.service", dir)) | ||
if err != nil { | ||
return fmt.Errorf("error collecting data from cloudfuse.service file due to the following error: [%s]", err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For deployment, we need to add the cloudfuse.service
file to the list of deployed files (in .goreleaser.yaml
), and something like this should work. We may need to use filepath.Dir(os.Executable())
(documented here), instead of os.Getwd()
to reliably get the path we need.
isDirEmpty := common.IsDirectoryEmpty(mountPath) | ||
if !isDirEmpty { | ||
return fmt.Errorf("error, the mount path provided is not empty") | ||
// TODO: add useage output upon failure with input | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to check this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cloudfuse outputs an error and will not mount if the provided mount path is not empty
cmd/service_linux.go
Outdated
// TODO: add useage output upon failure with input | ||
} | ||
|
||
configExists := common.DirectoryExists(configPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this works, I don't love that DirectoryExists
is checking existence for a file.
I found another place where we check if the config file exists, and we use os.Stat directly:
if _, err := os.Stat(options.ConfigFile); errors.Is(err, fs.ErrNotExist) {
return errors.New("config file does not exist")
}
}, | ||
} | ||
|
||
var uninstallCmd = &cobra.Command{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The uninstall command will have to require the mount path to know which mount's startup service we need to remove.
cmd/service_linux.go
Outdated
err = modifySericeFile(mountPath, dir) | ||
if err != nil { | ||
return fmt.Errorf("error when attempting to write defaults into service file: [%s]", err.Error()) | ||
} | ||
|
||
err = modifySericeFile(configPath, dir) | ||
if err != nil { | ||
return fmt.Errorf("error when attempting to write defaults into service file: [%s]", err.Error()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're creating a separate service file for each mount that the user wants to mount on startup, we'll want to
- not change our template cloudfuse.service file (we should write the modified unit file data straight to the destination)
- name each new service/unit file after the mount path, so they don't conflict, and so we can find them to remove them when uninstalling
cmd/service_linux.go
Outdated
// 2. retrieve the newUser account from cloudfuse.service file and create it if it doesn't exist | ||
|
||
serviceUser := serviceData["User"] | ||
setUser(serviceUser) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Linux I don't think we need a dedicated user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While failing to specify a user with the appropriate permissions doesn't stop the cloudfuse service from running and working, it opens up a large security risk involving the default permissions that are used when the service is run.
cmd/service_linux.go
Outdated
|
||
//--------------- command section ends | ||
|
||
func collectServiceData(serviceFilePath string) (map[string]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, but I feel like these helper functions could be a lot shorter, and more readable. I feel like these details should be abstracted away by a standard library function that does most or all of this for us...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I'm not sure anything specifically does this, but here is a go program that installs items with systemd that our design could be based around which is a lot cleaner. https://github.com/pioz/god
…le into the /etc/systemd/system/
cmd/service_linux.go
Outdated
} | ||
|
||
folderList := strings.Split(mountPath, "/") | ||
newFile, err := os.Create("/etc/systemd/system/" + folderList[len(folderList)-1] + ".service") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you set this as a constant to refer to at the top of the file.
cmd/service_linux.go
Outdated
} | ||
|
||
// get a list of group from reference user | ||
groups, err := usr.GroupIds() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What groups do we need to add the user to? And why do we need to add them manually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the service user at least needs the current user added to its groups to be able to access and use mount and config file typically located at the end user's home directory. There doesn't seem to be a way around using the usermod command for this.
cmd/service_linux.go
Outdated
|
||
//--------------- command section ends | ||
|
||
func collectServiceData(serviceFilePath string) (map[string]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I'm not sure anything specifically does this, but here is a go program that installs items with systemd that our design could be based around which is a lot cleaner. https://github.com/pioz/god
-changed collectServiceData() to extractValue() that outputs value from file for provided key -changed setUser() to use SUDO_USER env variable to add to service user group. and adjusted permissions for service user.
-corrected typo of moutingpoint that came from cloudfuse.service template file
What type of Pull Request is this? (check all applicable)
Describe your changes in brief
This adds the following commands available to the cloudfuse executable:
cloudfuse service install
cloudfuse service uninstall
Checklist
Related Issues