本文整理汇总了Golang中github.com/Azure/azure-sdk-for-go/management/virtualmachineimage.NewClient函数的典型用法代码示例。如果您正苦于以下问题:Golang NewClient函数的具体用法?Golang NewClient怎么用?Golang NewClient使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewClient函数的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: GetVMImage
func GetVMImage(
t *testing.T,
client management.Client,
filter func(vmimage.VMImage) bool) vmimage.VMImage {
t.Log("Selecting VM image")
allimages, err := vmimage.NewClient(client).ListVirtualMachineImages(vmimage.ListParameters{})
if err != nil {
t.Fatal(err)
}
filtered := []vmimage.VMImage{}
for _, im := range allimages.VMImages {
if filter(im) {
filtered = append(filtered, im)
}
}
if len(filtered) == 0 {
t.Fatal("Filter too restrictive, no images left?")
}
image := filtered[0]
for _, im := range filtered {
if im.PublishedDate > image.PublishedDate {
image = im
}
}
t.Logf("Selecting image '%s'", image.Name)
return image
}
开发者ID:garimakhulbe,项目名称:azure-sdk-for-go,代码行数:29,代码来源:integration_test.go
示例2: Run
func (s *StepCreateImage) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get(constants.RequestManager).(management.Client)
ui := state.Get(constants.Ui).(packer.Ui)
errorMsg := "Error Creating Azure Image: %s"
ui.Say("Creating Azure Image. If Successful, This Will Remove the Temporary VM...")
description := "packer made image"
imageFamily := "PackerMade"
if err := retry.ExecuteAsyncOperation(client, func() (management.OperationID, error) {
return vmi.NewClient(client).Capture(s.TmpServiceName, s.TmpVmName, s.TmpVmName,
s.UserImageName, s.UserImageLabel, vmi.OSStateGeneralized, vmi.CaptureParameters{
Description: description,
ImageFamily: imageFamily,
RecommendedVMSize: s.RecommendedVMSize,
})
}); err != nil {
err := fmt.Errorf(errorMsg, err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// CatpureVMImage removes the VM
state.Put(constants.ImageCreated, 1)
state.Put(constants.VmExists, 0)
return multistep.ActionContinue
}
开发者ID:kolargol,项目名称:packer-azure,代码行数:31,代码来源:step_create_image.go
示例3: NewClientFromSettingsFile
// NewClientFromSettingsFile returns a new Azure management
// client created using a publish settings file.
func (c *Config) NewClientFromSettingsFile() (*Client, error) {
if _, err := os.Stat(c.SettingsFile); os.IsNotExist(err) {
return nil, fmt.Errorf("Publish Settings file %q does not exist!", c.SettingsFile)
}
mc, err := management.ClientFromPublishSettingsFile(c.SettingsFile, c.SubscriptionID)
if err != nil {
return nil, nil
}
return &Client{
mgmtClient: mc,
affinityGroupClient: affinitygroup.NewClient(mc),
hostedServiceClient: hostedservice.NewClient(mc),
secGroupClient: networksecuritygroup.NewClient(mc),
osImageClient: osimage.NewClient(mc),
sqlClient: sql.NewClient(mc),
storageServiceClient: storageservice.NewClient(mc),
vmClient: virtualmachine.NewClient(mc),
vmDiskClient: virtualmachinedisk.NewClient(mc),
vmImageClient: virtualmachineimage.NewClient(mc),
vnetClient: virtualnetwork.NewClient(mc),
mutex: &sync.Mutex{},
}, nil
}
开发者ID:rgl,项目名称:terraform,代码行数:27,代码来源:config.go
示例4: TestVMImageList
func TestVMImageList(t *testing.T) {
client := testutils.GetTestClient(t)
vmic := vmimage.NewClient(client)
il, _ := vmic.ListVirtualMachineImages(vmimage.ListParameters{})
for _, im := range il.VMImages {
t.Logf("%s -%s", im.Name, im.Description)
}
}
开发者ID:garimakhulbe,项目名称:azure-sdk-for-go,代码行数:8,代码来源:integration_test.go
示例5: validateAzureOptions
func (b *Builder) validateAzureOptions(ui packer.Ui, state *multistep.BasicStateBag) error {
var err error
// Check Storage account (& container)
ui.Message("Checking Storage Account...")
availabilityResponse, err := storageservice.NewClient(b.client).CheckStorageAccountNameAvailability(b.config.StorageAccount)
if err != nil {
return err
}
if availabilityResponse.Result {
return fmt.Errorf("Can't Find Storage Account '%s'", b.config.StorageAccount)
}
// Check image exists
imageList, err := osimage.NewClient(b.client).ListOSImages()
if err != nil {
log.Printf("OS image client returned error: %s", err)
return err
}
if osImage, found := FindOSImage(imageList.OSImages, b.config.OSImageLabel, b.config.Location); found {
state.Put(constants.OSImageName, osImage.Name)
state.Put(constants.IsOSImage, true)
return nil
} else {
imageList, err := vmimage.NewClient(b.client).ListVirtualMachineImages()
if err != nil {
log.Printf("VM image client returned error: %s", err)
return err
}
if vmImage, found := FindVmImage(imageList.VMImages, "", b.config.OSImageLabel, b.config.Location); found {
state.Put(constants.OSImageName, vmImage.Name)
state.Put(constants.IsOSImage, false)
return nil
} else {
return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", b.config.OSImageLabel, b.config.Location)
}
}
}
开发者ID:HOSTINGLabs,项目名称:packer-azure,代码行数:42,代码来源:builder.go
示例6: NewClientFromSettingsData
func (c *Config) NewClientFromSettingsData() (*Client, error) {
mc, err := management.ClientFromPublishSettingsData(c.Settings, c.SubscriptionID)
if err != nil {
return nil, nil
}
return &Client{
mgmtClient: mc,
affinityGroupClient: affinitygroup.NewClient(mc),
hostedServiceClient: hostedservice.NewClient(mc),
secGroupClient: networksecuritygroup.NewClient(mc),
osImageClient: osimage.NewClient(mc),
sqlClient: sql.NewClient(mc),
storageServiceClient: storageservice.NewClient(mc),
vmClient: virtualmachine.NewClient(mc),
vmDiskClient: virtualmachinedisk.NewClient(mc),
vmImageClient: virtualmachineimage.NewClient(mc),
vnetClient: virtualnetwork.NewClient(mc),
mutex: &sync.Mutex{},
}, nil
}
开发者ID:saulshanabrook,项目名称:terraform,代码行数:21,代码来源:config.go
示例7: Run
//.........这里部分代码省略.........
Command: "sudo /usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync",
},
&StepStopVm{
TmpVmName: b.config.tmpVmName,
TmpServiceName: b.config.tmpServiceName,
},
&StepCreateImage{
TmpServiceName: b.config.tmpServiceName,
TmpVmName: b.config.tmpVmName,
UserImageName: b.config.userImageName,
UserImageLabel: b.config.UserImageLabel,
RecommendedVMSize: b.config.InstanceSize,
},
}
} else if b.config.OSType == constants.Target_Windows {
steps = []multistep.Step{
new(StepValidate),
&StepCreateService{
Location: b.config.Location,
TmpServiceName: b.config.tmpServiceName,
},
new(StepCreateVm),
&StepPollStatus{
TmpServiceName: b.config.tmpServiceName,
TmpVmName: b.config.tmpVmName,
OSType: b.config.OSType,
},
&win.StepSetProvisionInfrastructure{
VmName: b.config.tmpVmName,
ServiceName: b.config.tmpServiceName,
StorageAccountName: b.config.StorageAccount,
TempContainerName: b.config.tmpContainerName,
ProvisionTimeoutInMinutes: b.config.ProvisionTimeoutInMinutes,
},
&common.StepProvision{},
&StepStopVm{
TmpVmName: b.config.tmpVmName,
TmpServiceName: b.config.tmpServiceName,
},
&StepCreateImage{
TmpServiceName: b.config.tmpServiceName,
TmpVmName: b.config.tmpVmName,
UserImageName: b.config.userImageName,
UserImageLabel: b.config.UserImageLabel,
RecommendedVMSize: b.config.InstanceSize,
},
}
} else {
return nil, fmt.Errorf("Unkonwn OS type: %s", b.config.OSType)
}
// Run the steps.
if b.config.PackerDebug {
b.runner = &multistep.DebugRunner{
Steps: steps,
PauseFn: common.MultistepDebugFn(ui),
}
} else {
b.runner = &multistep.BasicRunner{Steps: steps}
}
b.runner.Run(state)
// Report any errors.
if rawErr, ok := state.GetOk("error"); ok {
return nil, rawErr.(error)
}
// If we were interrupted or cancelled, then just exit.
if _, ok := state.GetOk(multistep.StateCancelled); ok {
return nil, errors.New("Build was cancelled.")
}
if _, ok := state.GetOk(multistep.StateHalted); ok {
return nil, errors.New("Build was halted.")
}
vmImageList, err := vmimage.NewClient(b.client).ListVirtualMachineImages(
vmimage.ListParameters{
Location: b.config.Location,
})
if err != nil {
log.Printf("VM image client returned error: %s", err)
return nil, fmt.Errorf("Can't create artifact")
}
if userImage, found := FindVmImage(vmImageList.VMImages, b.config.userImageName, b.config.UserImageLabel); found {
return &artifact{
imageLabel: userImage.Label,
imageName: userImage.Name,
mediaLocation: userImage.OSDiskConfiguration.MediaLink,
publishSettingsPath: b.config.PublishSettingsPath,
subscriptionID: subscriptionID,
}, nil
} else {
log.Printf("could not find image %s", b.config.userImageName)
return nil, fmt.Errorf("Can't create artifact")
}
}
开发者ID:rchalumeau,项目名称:packer-azure,代码行数:101,代码来源:builder.go
示例8: TestDeployPlatformVMImageCaptureRedeploy
func TestDeployPlatformVMImageCaptureRedeploy(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetLinuxTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying VM: %s", vmname)
createRoleConfiguration(t, client, role, location)
t.Logf("Wait for deployment to enter running state")
vmc := vm.NewClient(client)
status := vm.DeploymentStatusDeploying
for status != vm.DeploymentStatusRunning {
deployment, err := vmc.GetDeployment(vmname, vmname)
if err != nil {
t.Error(err)
break
}
status = deployment.Status
}
t.Logf("Shutting down VM: %s", vmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.ShutdownRole(vmname, vmname, vmname, vm.PostShutdownActionStopped)
}); err != nil {
t.Error(err)
}
if err := WaitForDeploymentInstanceStatus(client, vmname, vmname, vm.InstanceStatusStoppedVM); err != nil {
t.Fatal(err)
}
imagename := GenerateName()
t.Logf("Capturing VMImage: %s", imagename)
if err := Await(client, func() (management.OperationID, error) {
return vmimage.NewClient(client).Capture(vmname, vmname, vmname, imagename, imagename, vmimage.OSStateGeneralized, vmimage.CaptureParameters{})
}); err != nil {
t.Error(err)
}
im := GetUserVMImage(t, client, imagename)
t.Logf("Found image: %+v", im)
newvmname := GenerateName()
role = NewVMConfiguration(newvmname, "Standard_D3")
ConfigureDeploymentFromUserVMImage(&role, im.Name)
ConfigureForLinux(&role, newvmname, "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying new VM from freshly captured VM image: %s", newvmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.CreateDeployment(role, vmname, vm.CreateDeploymentOptions{})
}); err != nil {
t.Error(err)
}
deleteHostedService(t, client, vmname)
}
开发者ID:garimakhulbe,项目名称:azure-sdk-for-go,代码行数:66,代码来源:integration_test.go
示例9: Run
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get(constants.RequestManager).(management.Client)
ui := state.Get(constants.Ui).(packer.Ui)
config := state.Get(constants.Config).(*Config)
ui.Say("Validating Azure options...")
role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)
ui.Message("Checking Storage Account...")
destinationVhd, err := validateStorageAccount(config, client)
if err != nil {
err = fmt.Errorf("Error checking storage account: %v", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))
if err := func() error {
if config.RemoteSourceImageLink != "" {
ui.Message("Checking remote image source link...")
response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
if response != nil && response.Body != nil {
defer response.Body.Close()
}
if err != nil {
log.Printf("HTTP client returned error: %s", err)
return fmt.Errorf("error checking remote image source link: %v", err)
}
if response.StatusCode != 200 {
return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
}
size := float64(response.ContentLength) / 1024 / 1024 / 1024
ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))
vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
if config.ResizeOSVhdGB != nil {
if float64(*config.ResizeOSVhdGB) < size {
return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, size)
}
ui.Say(fmt.Sprintf("Remote image will be resized to %d GiB", *config.ResizeOSVhdGB))
role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
}
} else {
ui.Message("Checking image source...")
imageList, err := osimage.NewClient(client).ListOSImages()
if err != nil {
log.Printf("OS image client returned error: %s", err)
return err
}
if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
if osImage.OS != config.OSType {
return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
}
if config.ResizeOSVhdGB != nil {
if float64(*config.ResizeOSVhdGB) < osImage.LogicalSizeInGB {
return fmt.Errorf("new OS VHD size of %d GiB is smaller than current size of %.1f GiB", *config.ResizeOSVhdGB, osImage.LogicalSizeInGB)
}
ui.Say(fmt.Sprintf("OS image will be resized to %d GiB", *config.ResizeOSVhdGB))
role.OSVirtualHardDisk.ResizedSizeInGB = *config.ResizeOSVhdGB
}
} else {
imageList, err := vmimage.NewClient(client).ListVirtualMachineImages(
vmimage.ListParameters{
Location: config.Location,
})
if err != nil {
log.Printf("VM image client returned error: %s", err)
return err
}
if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel); found {
if config.ResizeOSVhdGB != nil {
return fmt.Errorf("Packer cannot resize VM images")
}
if vmImage.OSDiskConfiguration.OSState != vmimage.OSStateGeneralized {
return fmt.Errorf("Packer can only use VM user images with a generalized OS so that it can be reprovisioned. The specified image OS is not in a generalized state.")
}
if vmImage.Category == vmimage.CategoryUser {
//vmutils.ConfigureDeploymentFromUserVMImage(&role, vmImage.Name)
role.VMImageName = vmImage.Name
} else {
vmutils.ConfigureDeploymentFromPublishedVMImage(&role, vmImage.Name, destinationVhd, true)
}
ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
if vmImage.OSDiskConfiguration.OS != config.OSType {
return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
}
} else {
return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
}
}
}
//.........这里部分代码省略.........
开发者ID:lopaka,项目名称:packer-azure,代码行数:101,代码来源:step_validate.go
示例10: Run
func (*StepValidate) Run(state multistep.StateBag) multistep.StepAction {
client := state.Get(constants.RequestManager).(management.Client)
ui := state.Get(constants.Ui).(packer.Ui)
config := state.Get(constants.Config).(*Config)
ui.Say("Validating Azure options...")
role := vmutils.NewVMConfiguration(config.tmpVmName, config.InstanceSize)
ui.Message("Checking Storage Account...")
destinationVhd, err := validateStorageAccount(config, client)
if err != nil {
err = fmt.Errorf("Error checking storage account: %v", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
ui.Message(fmt.Sprintf("Destination VHD: %s", destinationVhd))
if err := func() error {
if config.RemoteSourceImageLink != "" {
ui.Message("Checking remote image source link...")
response, err := http.DefaultClient.Head(config.RemoteSourceImageLink)
if response != nil && response.Body != nil {
defer response.Body.Close()
}
if err != nil {
log.Printf("HTTP client returned error: %s", err)
return fmt.Errorf("error checking remote image source link: %v", err)
}
if response.StatusCode != 200 {
return fmt.Errorf("Unexpected status while retrieving remote image source at %s: %d %s", config.RemoteSourceImageLink, response.StatusCode, response.Status)
}
size := float64(response.ContentLength) / 1024 / 1024 / 1024
ui.Say(fmt.Sprintf("Remote image size: %.1f GiB", size))
vmutils.ConfigureDeploymentFromRemoteImage(&role, config.RemoteSourceImageLink, config.OSType, fmt.Sprintf("%s-OSDisk", config.tmpVmName), destinationVhd, "")
} else {
ui.Message("Checking image source...")
imageList, err := osimage.NewClient(client).ListOSImages()
if err != nil {
log.Printf("OS image client returned error: %s", err)
return err
}
if osImage, found := FindOSImage(imageList.OSImages, config.OSImageLabel, config.Location); found {
vmutils.ConfigureDeploymentFromPlatformImage(&role, osImage.Name, destinationVhd, "")
ui.Message(fmt.Sprintf("Image source is OS image %q", osImage.Name))
if osImage.OS != config.OSType {
return fmt.Errorf("OS image type (%q) does not match config (%q)", osImage.OS, config.OSType)
}
} else {
imageList, err := vmimage.NewClient(client).ListVirtualMachineImages()
if err != nil {
log.Printf("VM image client returned error: %s", err)
return err
}
if vmImage, found := FindVmImage(imageList.VMImages, "", config.OSImageLabel, config.Location); found {
vmutils.ConfigureDeploymentFromVMImage(&role, vmImage.Name, destinationVhd, true)
ui.Message(fmt.Sprintf("Image source is VM image %q", vmImage.Name))
if vmImage.OSDiskConfiguration.OS != config.OSType {
return fmt.Errorf("VM image type (%q) does not match config (%q)", vmImage.OSDiskConfiguration.OS, config.OSType)
}
} else {
return fmt.Errorf("Can't find VM or OS image '%s' Located at '%s'", config.OSImageLabel, config.Location)
}
}
}
return nil
}(); err != nil {
err = fmt.Errorf("Error determining deployment source: %v", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if config.OSType == constants.Target_Linux {
certThumbprint := state.Get(constants.Thumbprint).(string)
if len(certThumbprint) == 0 {
err := fmt.Errorf("Certificate Thumbprint is empty")
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
vmutils.ConfigureForLinux(&role, config.tmpVmName, config.UserName, "", certThumbprint)
vmutils.ConfigureWithPublicSSH(&role)
} else if config.OSType == constants.Target_Windows {
password := utils.RandomPassword()
state.Put("password", password)
vmutils.ConfigureForWindows(&role, config.tmpVmName, config.UserName, password, true, "")
vmutils.ConfigureWithPublicRDP(&role)
vmutils.ConfigureWithPublicPowerShell(&role)
}
if config.VNet != "" && config.Subnet != "" {
ui.Message("Checking VNet...")
if err := checkVirtualNetworkConfiguration(client, config.VNet, config.Subnet, config.Location); err != nil {
state.Put("error", err)
ui.Error(err.Error())
//.........这里部分代码省略.........
开发者ID:nivertech,项目名称:packer-azure,代码行数:101,代码来源:step_validate.go
示例11: PostProcess
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact /*keep*/, bool, error) {
ui.Say("Validating artifact")
if artifact.BuilderId() != azure.BuilderId {
return nil, false, fmt.Errorf(
"Unknown artifact type: %s\nCan only import from Azure builder artifacts (%s).",
artifact.BuilderId(), azure.BuilderId)
}
publishSettingsPath, ok := artifact.State("publishSettingsPath").(string)
if !ok || publishSettingsPath == "" {
return nil, false, fmt.Errorf(stateError, "publishSettingsPath")
}
subscriptionID, ok := artifact.State("subscriptionID").(string)
if !ok || subscriptionID == "" {
return nil, false, fmt.Errorf(stateError, "subscriptionID")
}
name := artifact.Id()
ui.Message("Creating Azure Service Management client...")
client, err := management.ClientFromPublishSettingsFile(publishSettingsPath, subscriptionID)
if err != nil {
return nil, false, fmt.Errorf("Error creating new Azure client: %v", err)
}
client = azure.GetLoggedClient(client)
vmic := virtualmachineimage.NewClient(client)
ui.Message("Retrieving VM image...")
var image virtualmachineimage.VMImage
if err = retry.ExecuteOperation(func() error {
imageList, err := vmic.ListVirtualMachineImages(
virtualmachineimage.ListParameters{
Category: virtualmachineimage.CategoryUser,
})
if err != nil {
return err
}
for _, i := range imageList.VMImages {
if i.Name == name {
image = i
break
}
}
return nil
}); err != nil {
log.Printf("VM image client returned error: %s", err)
return nil, false, err
}
if image.Name != name {
return nil, false, fmt.Errorf("Could not find image: %s", name)
}
ui.Message(fmt.Sprintf("Deleting VM image (keeping VHDs) %s: %s...", image.Name, image.Label))
err = retry.ExecuteOperation(func() error { return vmic.DeleteVirtualMachineImage(image.Name, false) })
if err != nil {
log.Printf("Error deleting VM image: %s", err)
return nil, false, err
}
blobs := VMBlobListArtifact{
OSDisk: image.OSDiskConfiguration.MediaLink,
DataDisks: make([]string, len(image.DataDiskConfigurations))}
for i, ddc := range image.DataDiskConfigurations {
blobs.DataDisks[i] = ddc.MediaLink
}
return blobs, false, nil
}
开发者ID:rchalumeau,项目名称:packer-azure,代码行数:70,代码来源:post-processor.go
注:本文中的github.com/Azure/azure-sdk-for-go/management/virtualmachineimage.NewClient函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论