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 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
30 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
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
115 changes: 115 additions & 0 deletions cmd/gen-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____


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/internal"
"github.com/spf13/cobra"
)

type generatedConfigOptions struct {
configComp string
configTmp string
configDirectIO bool
}

var opts2 generatedConfigOptions
ashruti-msft marked this conversation as resolved.
Show resolved Hide resolved

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 {

common.GenConfig = true

if opts2.configComp != "block_cache" && opts2.configComp != "file_cache" {
return fmt.Errorf("component is required and should be either block_cache or file_cache")
ashruti-msft marked this conversation as resolved.
Show resolved Hide resolved
}

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

pipeline := []string{"libfuse", opts2.configComp}
common.TmpPath = opts2.configTmp

if opts2.configDirectIO {
common.DirectIO = true
} else {
pipeline = append(pipeline, "attr_cache")
}

var sb strings.Builder
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")

// Iterate through the pipeline and add each component to the YAML content
for _, component := range pipeline {
sb.WriteString(fmt.Sprintf(" - %s\n", component))
}
sb.WriteString(" - azstorage\n")

_, err := internal.NewPipeline(pipeline, true)
jainakanksha-msft marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf("generatedConfig:: error creating pipeline [%s]", err.Error())
}

sb.WriteString(common.ConfigYaml)

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")

err = common.WriteToFile("generatedConfig.yaml", sb.String(), common.WriteToFileOptions{Flags: os.O_TRUNC, Permission: 0644})
vibhansa-msft marked this conversation as resolved.
Show resolved Hide resolved
return err
},
}

func init() {
rootCmd.AddCommand(generatedConfig)
generatedConfig.Flags().StringVar(&opts2.configComp, "component", "", "Input block_cache or file_cache")
generatedConfig.Flags().StringVar(&opts2.configTmp, "tmp-path", "", "Input path for caching")
generatedConfig.Flags().BoolVar(&opts2.configDirectIO, "direct-io", false, "Choose direct-io mode")
ashruti-msft marked this conversation as resolved.
Show resolved Hide resolved
}
187 changes: 187 additions & 0 deletions cmd/gen-config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/*
_____ _____ _____ ____ ______ _____ ------
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| --- | | | | |-----| |---- | | |-----| |----- ------
| | | | | | | | | | | | |
| ____| |_____ | ____| | ____| | |_____| _____| |_____ |_____


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"
"os/exec"
"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("generatedConfig.yaml")
}

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

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

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "file_cache"), fmt.Sprintf("--tmp-path=%s", tempDir))
_, err := cmd.Output()
suite.assert.Nil(err)

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

//check if the generated file is not empty
file, err := os.ReadFile("generatedConfig.yaml")
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)

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "block_cache"), fmt.Sprintf("--tmp-path=%s", tempDir))
_, err := cmd.Output()
suite.assert.Nil(err)

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

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

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

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

cmd = exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "block_cache"))
_, err = cmd.Output()
suite.assert.Nil(err)

file, err = os.ReadFile("generatedConfig.yaml")
suite.assert.Nil(err)
//check if the generated file has no tmp path
suite.assert.NotContains(string(file), tempDir)
}

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

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "block_cache"), "--direct-io")

_, err := cmd.Output()
suite.assert.Nil(err)

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

//check if the generated file is not empty
file, err := os.ReadFile("generatedConfig.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")
}

func (suite *genConfig) TestInvalidComponent() {
vibhansa-msft marked this conversation as resolved.
Show resolved Hide resolved
defer suite.cleanupTest()

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "invalid_component"))
_, err := cmd.Output()
suite.assert.NotNil(err)
}

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

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "file_cache"))
_, err := cmd.Output()
suite.assert.NotNil(err)
}

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

cmd := exec.Command("../blobfuse2", "gen-config")
_, err := cmd.Output()
suite.assert.NotNil(err)
}

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

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

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--tmp-path=%s", tempDir))
_, err := cmd.Output()
suite.assert.NotNil(err)
}

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

cmd := exec.Command("../blobfuse2", "gen-config", fmt.Sprintf("--component=%s", "file_cache"))
_, err := cmd.Output()
suite.assert.NotNil(err)
}

func TestGenConfig(t *testing.T) {
suite.Run(t, new(genConfig))
}
File renamed without changes.
4 changes: 4 additions & 0 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ var TransferPipe = "/tmp/transferPipe"
var PollingPipe = "/tmp/pollPipe"

var MountPath string
var GenConfig bool = false
var TmpPath string
var DirectIO bool
var ConfigYaml string

// LogLevel enum
type LogLevel int
Expand Down
28 changes: 26 additions & 2 deletions common/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,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 All @@ -117,7 +116,7 @@ func IsMountActive(path string) (bool, error) {

err := cmd.Run()
if err != nil {
return true, fmt.Errorf("failed to get command line arguments for pid %s [%v]", pid, err.Error())
return true, fmt.Errorf("failed to get command line arguments for pid %s [%v] ", pid, err.Error())
}

if strings.Contains(out.String(), path) {
Expand Down Expand Up @@ -475,3 +474,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