Skip to content
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

Generate default config #1535

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
883c0a8
added command to generate default config but have modified current ge…
ashruti-msft Oct 7, 2024
5281254
finished
ashruti-msft Oct 8, 2024
ab2d49a
direct io added
ashruti-msft Oct 8, 2024
2093035
haandle error
ashruti-msft Oct 8, 2024
db588c9
minor change
ashruti-msft Oct 8, 2024
4643548
change
ashruti-msft Oct 11, 2024
a189780
modular
ashruti-msft Oct 15, 2024
0ef4306
add tests
ashruti-msft Oct 15, 2024
967ebc9
Merge branch 'main' into ashruti/genConfig
ashruti-msft Oct 16, 2024
d2169b0
solving errors one more commit reqd
ashruti-msft Oct 17, 2024
f579586
Merge branch 'ashruti/genConfig' of https://github.com/Azure/azure-st…
ashruti-msft Oct 17, 2024
6a0ba4d
done
ashruti-msft Oct 17, 2024
780be84
Merge branch 'main' into ashruti/genConfig
ashruti-msft Oct 17, 2024
32bd00e
fix ci
ashruti-msft Oct 23, 2024
104013a
err check
ashruti-msft Oct 23, 2024
da88e91
fix ci
ashruti-msft Oct 23, 2024
fb09832
added test
ashruti-msft Oct 23, 2024
49f9f96
testing
ashruti-msft Oct 24, 2024
cffb5f1
Merge branch 'main' into ashruti/genConfig
ashruti-msft Oct 24, 2024
5eb1a01
debugging
ashruti-msft Oct 30, 2024
266dc07
debugging
ashruti-msft Oct 30, 2024
188c75a
debugging
ashruti-msft Oct 30, 2024
22954fd
fix ci'
ashruti-msft Nov 3, 2024
3880e04
fixes?
ashruti-msft Nov 4, 2024
6955138
added default location for log
ashruti-msft Nov 4, 2024
9fe187d
Merge branch 'main' into ashruti/genConfig
ashruti-msft Nov 4, 2024
1b05248
Sync with main
vibhansa-msft Nov 5, 2024
d79f6b9
Adding tests to dump config to file or console
vibhansa-msft Nov 5, 2024
a119947
updated
vibhansa-msft Nov 5, 2024
fabb40a
Merge branch 'main' into ashruti/genConfig
jainakanksha-msft Nov 5, 2024
24de36c
Merge remote-tracking branch 'origin/main' into ashruti/genConfig
vibhansa-msft Nov 5, 2024
d87ca54
Correcting UT
vibhansa-msft Nov 5, 2024
08a5cce
Sync with main line
vibhansa-msft Nov 5, 2024
1f5d323
Updated
vibhansa-msft Nov 7, 2024
c76696c
Updated
vibhansa-msft Nov 7, 2024
1f9e7b4
Updated
vibhansa-msft Nov 7, 2024
212f2ec
Updated
vibhansa-msft Nov 7, 2024
c6a4a33
Updated
vibhansa-msft Nov 7, 2024
5362d94
Always dump config file
vibhansa-msft Nov 7, 2024
74576f8
updated
vibhansa-msft Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions cmd/gen-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____


Licensed under the MIT License <http://opensource.org/licenses/MIT>.

Copyright Β© 2020-2024 Microsoft Corporation. All rights reserved.
Author : <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
*/

package cmd

import (
"fmt"
"os"
"strings"

"github.com/Azure/azure-storage-fuse/v2/common"
"github.com/Azure/azure-storage-fuse/v2/common/config"
"github.com/Azure/azure-storage-fuse/v2/internal"
"github.com/spf13/cobra"
)

type genConfigParams struct {
blockCache bool `config:"block-cache" yaml:"block-cache,omitempty"`
directIO bool `config:"direct-io" yaml:"direct-io,omitempty"`
readOnly bool `config:"ro" yaml:"ro,omitempty"`
tmpPath string `config:"tmp-path" yaml:"tmp-path,omitempty"`
outputFile string `config:"o" yaml:"o,omitempty"`
}

var optsGenCfg genConfigParams

var generatedConfig = &cobra.Command{
Use: "gen-config",
Short: "Generate default config file.",
Long: "Generate default config file with the values pre-caculated by blobfuse2.",
SuggestFor: []string{"generate default config", "generate config"},
Hidden: true,
Args: cobra.ExactArgs(0),
FlagErrorHandling: cobra.ExitOnError,
RunE: func(cmd *cobra.Command, args []string) error {

// Check if configTmp is not provided when component is fc
if (!optsGenCfg.blockCache) && optsGenCfg.tmpPath == "" {
return fmt.Errorf("temp path is required for file cache mode. Use flag --tmp-path to provide the path")
}

// Set the configs
if optsGenCfg.readOnly {
config.Set("read-only", "true")
}

if optsGenCfg.directIO {
config.Set("direct-io", "true")
}

config.Set("tmp-path", optsGenCfg.tmpPath)

// Create the pipeline
pipeline := []string{"libfuse"}
if optsGenCfg.blockCache {
pipeline = append(pipeline, "block_cache")
} else {
pipeline = append(pipeline, "file_cache")
}
ashruti-msft marked this conversation as resolved.
Show resolved Hide resolved

if !optsGenCfg.directIO {
pipeline = append(pipeline, "attr_cache")
}
pipeline = append(pipeline, "azstorage")

var sb strings.Builder

if optsGenCfg.directIO {
sb.WriteString("direct-io: true\n")
}

if optsGenCfg.readOnly {
sb.WriteString("read-only: true\n\n")
}

sb.WriteString("# Logger configuration\n#logging:\n # type: syslog|silent|base\n # level: log_off|log_crit|log_err|log_warning|log_info|log_trace|log_debug\n")
vibhansa-msft marked this conversation as resolved.
Show resolved Hide resolved
sb.WriteString(" # file-path: <path where log files shall be stored. Default - '$HOME/.blobfuse2/blobfuse2.log'>\n")

sb.WriteString("\ncomponents:\n")
for _, component := range pipeline {
sb.WriteString(fmt.Sprintf(" - %s\n", component))
}

for _, component := range pipeline {
c := internal.GetComponent(component)
if c == nil {
return fmt.Errorf("generatedConfig:: error getting component [%s]", component)
}
sb.WriteString("\n")
sb.WriteString(c.GenConfig())
}

sb.WriteString("\n#Required\n#azstorage:\n # type: block|adls \n # account-name: <name of the storage account>\n # container: <name of the storage container to be mounted>\n # endpoint: <example - https://account-name.blob.core.windows.net>\n ")
sb.WriteString("# mode: key|sas|spn|msi|azcli \n # account-key: <storage account key>\n # OR\n # sas: <storage account sas>\n # OR\n # appid: <storage account app id / client id for MSI>\n # OR\n # tenantid: <storage account tenant id for SPN")

filePath := ""
if optsGenCfg.outputFile == "" {
filePath = "./blobfuse2.yaml"
} else {
filePath = optsGenCfg.outputFile
}

var err error = nil
if optsGenCfg.outputFile == "console" {
fmt.Println(sb.String())
} else {
err = common.WriteToFile(filePath, sb.String(), common.WriteToFileOptions{Flags: os.O_TRUNC, Permission: 0644})
}

return err
},
}

func init() {
rootCmd.AddCommand(generatedConfig)

generatedConfig.Flags().BoolVar(&optsGenCfg.blockCache, "block-cache", false, "Block-Cache shall be used as caching strategy")
generatedConfig.Flags().BoolVar(&optsGenCfg.directIO, "direct-io", false, "Direct-io mode shall be used")
generatedConfig.Flags().BoolVar(&optsGenCfg.readOnly, "ro", false, "Mount in read-only mode")
generatedConfig.Flags().StringVar(&optsGenCfg.tmpPath, "tmp-path", "", "Temp cache path to be used")
generatedConfig.Flags().StringVar(&optsGenCfg.outputFile, "o", "", "Output file location")
}
202 changes: 202 additions & 0 deletions cmd/gen-config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____


Licensed under the MIT License <http://opensource.org/licenses/MIT>.

Copyright Β© 2020-2024 Microsoft Corporation. All rights reserved.
Author : <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
*/

package cmd

import (
"fmt"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

type genConfig struct {
suite.Suite
assert *assert.Assertions
}

func (suite *genConfig) SetupTest() {
suite.assert = assert.New(suite.T())
}

func (suite *genConfig) cleanupTest() {
os.Remove(suite.getDefaultLogLocation())
optsGenCfg = genConfigParams{}
}

func (suite *genConfig) getDefaultLogLocation() string {
return "./blobfuse2.yaml"
}

func (suite *genConfig) TestNoTempPath() {
defer suite.cleanupTest()

_, err := executeCommandC(rootCmd, "gen-config")
suite.assert.NotNil(err)
}

func (suite *genConfig) TestFileCacheConfigGen() {
defer suite.cleanupTest()

tempDir, _ := os.MkdirTemp("", "TestTempDir")
os.MkdirAll(tempDir, 0777)
defer os.RemoveAll(tempDir)

_, err := executeCommandC(rootCmd, "gen-config", fmt.Sprintf("--tmp-path=%s", tempDir))
suite.assert.Nil(err)

logFilePath := suite.getDefaultLogLocation()

//Check if a file is generated named generatedConfig.yaml
suite.assert.FileExists(logFilePath)

//check if the generated file is not empty
file, err := os.ReadFile(logFilePath)
suite.assert.Nil(err)
suite.assert.NotEmpty(file)

//check if the generated file has the correct component
suite.assert.Contains(string(file), "file_cache")

//check if the generated file has the correct temp path
suite.assert.Contains(string(file), tempDir)
}

func (suite *genConfig) TestBlockCacheConfigGen() {
defer suite.cleanupTest()

tempDir, _ := os.MkdirTemp("", "TestTempDir")
os.MkdirAll(tempDir, 0777)
defer os.RemoveAll(tempDir)

_, err := executeCommandC(rootCmd, "gen-config", "--block-cache", fmt.Sprintf("--tmp-path=%s", tempDir))
suite.assert.Nil(err)

logFilePath := suite.getDefaultLogLocation()

//Check if a file is generated named generatedConfig.yaml
suite.assert.FileExists(logFilePath)

//check if the generated file is not empty
file, err := os.ReadFile(logFilePath)
suite.assert.Nil(err)
suite.assert.NotEmpty(file)

//check if the generated file has the correct component
suite.assert.Contains(string(file), "block_cache")
suite.assert.NotContains(string(file), "file_cache")

//check if the generated file has the correct temp path
suite.assert.Contains(string(file), tempDir)
}

func (suite *genConfig) TestBlockCacheConfigGen1() {
defer suite.cleanupTest()

tempDir, _ := os.MkdirTemp("", "TestTempDir")
os.MkdirAll(tempDir, 0777)
defer os.RemoveAll(tempDir)

_, err := executeCommandC(rootCmd, "gen-config", "--block-cache")
suite.assert.Nil(err)

logFilePath := suite.getDefaultLogLocation()

//Check if a file is generated named generatedConfig.yaml
suite.assert.FileExists(logFilePath)

//check if the generated file is not empty
file, err := os.ReadFile(logFilePath)
suite.assert.Nil(err)
suite.assert.NotEmpty(file)

//check if the generated file has the correct component
suite.assert.Contains(string(file), "block_cache")
suite.assert.NotContains(string(file), "file_cache")

//check if the generated file has the correct temp path
suite.assert.NotContains(string(file), tempDir)
}

// test direct io flag
func (suite *genConfig) TestDirectIOConfigGen() {
defer suite.cleanupTest()

_, err := executeCommandC(rootCmd, "gen-config", "--block-cache", "--direct-io")
suite.assert.Nil(err)

logFilePath := suite.getDefaultLogLocation()
suite.assert.FileExists(logFilePath)

//check if the generated file is not empty
file, err := os.ReadFile(logFilePath)
suite.assert.Nil(err)
suite.assert.NotEmpty(file)

//check if the generated file has the correct direct io flag
suite.assert.Contains(string(file), "direct-io: true")
suite.assert.NotContains(string(file), " path: ")
}

func (suite *genConfig) TestOutputFile() {
defer suite.cleanupTest()

_, err := executeCommandC(rootCmd, "gen-config", "--block-cache", "--direct-io", "--o", "1.yaml")
suite.assert.Nil(err)

//check if the generated file is not empty
file, err := os.ReadFile("1.yaml")
suite.assert.Nil(err)
suite.assert.NotEmpty(file)

//check if the generated file has the correct direct io flag
suite.assert.Contains(string(file), "direct-io: true")
suite.assert.NotContains(string(file), " path: ")
_ = os.Remove("1.yaml")
}

func (suite *genConfig) TestConsoleOutput() {
defer suite.cleanupTest()

op, err := executeCommandC(rootCmd, "gen-config", "--block-cache", "--direct-io", "--o", "console")
suite.assert.Nil(err)

//check if the generated file has the correct direct io flag
suite.assert.Empty(op)
}

func TestGenConfig(t *testing.T) {
suite.Run(t, new(genConfig))
}
File renamed without changes.
26 changes: 25 additions & 1 deletion common/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ func IsMountActive(path string) (bool, error) {
var out bytes.Buffer
cmd := exec.Command("pidof", "blobfuse2")
cmd.Stdout = &out

err := cmd.Run()
if err != nil {
if err.Error() == "exit status 1" {
Expand Down Expand Up @@ -476,3 +475,28 @@ func GetFuseMinorVersion() int {

return val
}

type WriteToFileOptions struct {
Flags int
Permission os.FileMode
}

func WriteToFile(filename string, data string, options WriteToFileOptions) error {
// Open the file with the provided flags, create it if it doesn't exist
//check if options.Permission is 0 if so then assign 0777
if options.Permission == 0 {
options.Permission = 0777
}
file, err := os.OpenFile(filename, options.Flags|os.O_CREATE|os.O_WRONLY, options.Permission)
if err != nil {
return fmt.Errorf("error opening file: [%s]", err.Error())
}
defer file.Close() // Ensure the file is closed when we're done

// Write the data content to the file
if _, err := file.WriteString(data); err != nil {
return fmt.Errorf("error writing to file [%s]", err.Error())
}

return nil
}
Loading
Loading