Deploy OVA to VCenter with Terraform - vsphere

I am by no means a knowledgeable VMWare user at this point. I think this might just be a case where I just don't understand some essential concepts.
I'm trying to deploy a VM into a VCenter, I have an OVA (template?) that I want to deploy with.
Currently I have unpacked the OVA, uploaded the VMDKs I found therein to a datastore, and then used this terraform definition:
provider "vsphere" {
user = "${var.vsphere_user}"
password = "${var.vsphere_password}"
vsphere_server = "${var.vsphere_server}"
allow_unverified_ssl = true
}
resource "vsphere_virtual_machine" "primary" {
name = "myvm"
vcpu = 2
memory = 16384
datacenter = "${var.vsphere_datacenter}"
resource_pool = "/DATA_CENTER/host/10.132.260.000"
network_interface = {
label = "Private Network - vmnic0 vmnic2"
ipv4_address = "10.132.260.001"
ipv4_gateway = "10.132.260.002"
ipv4_prefix_length = 26
}
disk {
datastore = "datastore1"
vmdk = "/path/to/vmdk/"
bootable = true
type = "thin"
}
}
Which gets stuck, because it can't open the VMDK.
When I deploy the OVA with ovftool the vmdk that the vm is deployed with is very different.
An error was received from the ESX host while powering on VM myvm.
Failed to start the virtual machine. Module DiskEarly power on failed.
Cannot open the disk
'/vmfs/volumes/557fc17b-c078f45c-f5bf-002590faf644/template_folder/my_vm.vmdk'
or one of the snapshot disks it depends on. The file specified is not
a virtual disk
Should I be uploading the OVA file to the datastore instead and change my disk block to look like:
disk {
datastore = "datastore1"
template = "/path/to/ova/"
type = "thin"
}
Or am I just out of luck here? Also, the terraform provider for vsphere doesn't correctly receive the error from VCenter and just continues to poll even though the vm failed.

OVA contains streamOptimized disks. If you directly upload to the datastore vSphere doesn't recognize it as a VMDK for a VM.
You can use vmware-vdiskmanager tool to convert the streamOptimized disk to sparse disk.
vmware-vdiskmanager -r ova_extracted.vmdk -t 0 destination.vmdk

Related

Error with storage when using NEW disk type in Terraform SQL Server virtual machine setup

I'm trying to add the SQL Server "data"/ "log" disk by using Terraform.
There are 3 data disk created for the VM with luns 0,1,2 each set to Standard SSD with 128G of space in Terraform
The following snippet is what I am currently trying to run.
resource "azurerm_mssql_virtual_machine" "sqlconfig" {
virtual_machine_id = azurerm_windows_virtual_machine.vm[var.HOSTNAME_MICROSOFTSQL].id
sql_license_type = "PAYG"
sql_connectivity_port = *redacted
sql_connectivity_type = *redacted
sql_connectivity_update_password = *redacted
sql_connectivity_update_username = *redacted
sql_instance {
collation = "SQL_Latin1_General_CP1_CI_AS"
}
storage_configuration {
disk_type = "NEW"
storage_workload_type = "OLTP"
data_settings {
default_file_path = "F:\\Data"
luns = [0]
}
log_settings {
default_file_path = "G:\\Log"
luns = [1]
}
temp_db_settings {
default_file_path = "G:\\tempDb"
luns = [1]
data_file_count = 8
data_file_size_mb = 8
data_file_growth_in_mb = 64
log_file_size_mb = 8
log_file_growth_mb = 64
}
}
However, I am getting the following error when deploying from azure devops pipeline
polling after CreateOrUpdate: Code="Ext_StorageConfigurationSettingsError" Message="Error: 'Number of disks found do not match the expected count for creating Storage Pool, found :0 target: 1. Detail: Disk with LUN number 0 cannot be pooled. Reason : Insufficient Capacity'"
What does this error mean?
DATA volume seems compatible with PremiumSSD and UltraDisks only. Same for LOGS. Try to change the disk type.
To auick validate, try to create your VM via Azure Portal, when configuring Storage you should only be able to select Ultra or PXX disks.
Hope it helps.
It appears that within Terraform, when creating the Datadisks and attaching them to the VM before to running the section on azurerm_mssql_virtual_machine, it runs into some kind race condition between setting up the disk/attachment and storage configuration within azurerm_mssql_virtual_machine. This problem is solved once we added the following block of code under azurerm_mssql_virtual_machine:
depends_on = [
azurerm_virtual_machine_data_disk_attachment.[disk_attachment_name]
]

WebView2 Fixed Version not working when binaries stored on network share

I want to save the Fixed Version binaries on a network share path, but the WebView2 does not display the web page and does not throw an error.
I set the BrowserExecutableFolder path in the form designer:
CoreWebView2CreationProperties1.BrowserExecutableFolder = "j:\Utilities\Microsoft.WebView2.FixedVersionRuntime.90.0.818.66.x64\"
CoreWebView2CreationProperties1.Language = Nothing
CoreWebView2CreationProperties1.UserDataFolder = Nothing
Me.WebView21.CreationProperties = CoreWebView2CreationProperties1
Me.WebView21.DefaultBackgroundColor = System.Drawing.Color.White
Me.WebView21.Dock = System.Windows.Forms.DockStyle.Fill
Me.WebView21.Location = New System.Drawing.Point(0, 25)
Me.WebView21.Name = "WebView21"
Me.WebView21.Size = New System.Drawing.Size(800, 425)
Me.WebView21.TabIndex = 6
Me.WebView21.ZoomFactor = 1.0R
Setting to a UNC path, doesn't work -
CoreWebView2CreationProperties1.BrowserExecutableFolder = "\UNCFile1\private\Utilities\Microsoft.WebView2.FixedVersionRuntime.90.0.818.66.x64"
Setting to the mapped drive, doesn't work -
CoreWebView2CreationProperties1.BrowserExecutableFolder = "j:\Utilities\Microsoft.WebView2.FixedVersionRuntime.90.0.818.66.x64"
This will work -
CoreWebView2CreationProperties1.BrowserExecutableFolder = "C:\Utilities\Microsoft.WebView2.FixedVersionRuntime.90.0.818.66.x64"
We run the application from a network share path instead of deploying to each users work station and would like to also store the fixed version binaries in the same network share path. Is there a way to make this work?
This is a known issue, according to Microsoft.
It seems WebView2's sandbox environement does not work (yet?) when launched from a network storage.
As an workarround, may disable sandbox using the additional browser arguments or set the environement variable WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS as --no-sandbox before webview initialization.
Sample code in Delphi:
SetEnvironmentVariable('WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS', '--no-sandbox');
EdgeBrowser.BrowserExecutableFolder := '\\unc\path\or\network\drive';
EdgeBrowser.CreateWebView;
Note, this might be a security risk in case if you will access untrusted websites.

Copy/Cache Azure database locally for offline use.

I have a piece of software that connects to an Azure database to gather formulas for several varieties of colors to allow the user to follow a recipe to create their own product.
Basically there is just one big database pull when the application launches, that pulls down all the formulas, and from there the user can simply use, modify, or even delete the formulas as they wish.
The problem is that where this software is used, there are seldom constant internet connections, and the application so far is simply designed to shutdown if there isn't one present.
I am looking for a solution for being able to allow the application to BOTH connect to the database on application startup(If a connection is present) and save a copy locally, or if no connection is present, check for a locally saved copy to work with.
I have looked everywhere, but have been unable to find any methods to "programmatically" retrieve the pertinent(or all, if necessary) data, and either export it to a local file, or cache it somehow for offline use.
Any suggestions?
You don't mention what kind of technology you're using on the client side, and if you require access to a database on the client or just the data - but regardless there are several ways to do this.
Azure Mobile apps have a quickstart which will implements an Azure SQL <-> SQL Lite (mobile) database sync framework (table controllers on the server side). This lets you use libraries on the mobile side to use the local db for getting its data, and when you know you're online you can sync to/from the server. This is quite sophisticated and probably gives you more than just the caching that you're looking for.
I've used two other strategies for caching - one for HTML/javascript based applications (phonegap/cordova) and the other for Xamarin c# apps on iOS and Android. I'm assuming if it's a standard windows desktop app you know how to persist data so you can use whatever kind of cache/file system/db you like.
JavaScript/html - use the html5 localStorage functions to store the JSON output of the web server calls you're making. This is really easy then to abstract, where your app before is making an ajax call to the server to get some data, instead move that to a "liveorcache" class, which can determine whether to go to the server or just use the local storage. Code snippet for saving/loading json in localstorage below:
$scope.saveFixtures = function () {
localStorage["fixtures"] = JSON.stringify($scope.fixtures);
};
$scope.loadFixtures = function () {
if (localStorage["fixtures"] != undefined) {
$scope.fixtures = JSON.parse(localStorage["fixtures"]);
}
};
If you're writing your app in Xamarin you can do the same kind of thing, but using a PCL library - I used "PCLStorage" which works on Android and iOS. Same strategy though, in my code I just write the JSON data to a file with an appropriate filename, but usually wrap the object in another object that contains the cache write date/time. You then serialise the object to the file - something like below.
public class CacheProvider
{
public static async Task<CacheModel> ReadCache<T>(string filename)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
try
{
IFile file = await cache.GetFileAsync(filename);
var data = await file.ReadAllTextAsync();
return JsonConvert.DeserializeObject<T>(data) as CacheModel;
}
catch(FileNotFoundException ex)
{
return null;
}
}
public static async void WriteCache<T>(string filename, CacheModel data)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
IFile file = await cache.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
if (file != null)
{
data.CacheCreated = DateTime.Now;
string json = JsonConvert.SerializeObject(data);
await file.WriteAllTextAsync(json);
}
}
public static async void DeleteCache(string filename)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
IFile file = await cache.GetFileAsync(filename);
if (file != null)
await file.DeleteAsync();
}
}

Configure Slick with Sql Server

I have a project that is currently using MySQL that I would like to migrate to SQL Server (running on Azure). I have tried a lot of combinations of configurations but always get the same generic error message:
Cannot connect to database [default]
Here is my latest configuration attempt:
slick.dbs.default.driver = "com.typesafe.slick.driver.ms.SQLServerDriver"
slick.dbs.default.db.driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
slick.dbs.default.db.url = "jdbc:sqlserver://my_host.database.windows.net:1433;database=my_db"
slick.dbs.default.db.user = "username"
slick.dbs.default.db.password = "password"
slick.dbs.default.db.connectionTimeout="10 seconds"
I have the sqljdbc4.jar in my lib/ folder.
And have added the following to my build.sbt
libraryDependencies += "com.typesafe.slick" %% "slick-extensions" % "3.0.0"
resolvers += "Typesafe Releases" at "http://repo.typesafe.com/typesafe/maven-releases/"
Edit: I can connect from this machine using a GUI app, so the issue is not with any of the network settings.
Edit: 5/30/2017
After the release of Slick 3.2 the driver is now in the core suite, these are examples of Configs with 3.2
oracle = {
driver = "slick.jdbc.OracleProfile$"
db {
host = ${?ORACLE_HOST}
port = ${?ORACLE_PORT}
sid = ${?ORACLE_SID}
url = "jdbc:oracle:thin:#//"${oracle.db.host}":"${oracle.db.port}"/"${oracle.db.sid}
user = ${?ORACLE_USERNAME}
password = ${?ORACLE_PASSWORD}
}
}
sqlserver = {
driver = "slick.jdbc.SQLServerProfile$"
db {
host = ${?SQLSERVER_HOST}
port = ${?SQLSERVER_PORT}
databaseName = ${?SQLSERVER_DB_NAME}
url = "jdbc:sqlserver://"${sqlserver.db.host}":"${sqlserver.db.port}";databaseName="${sqlserver.db.databaseName}
user = ${?SQLSERVER_USERNAME}
password = ${?SQLSERVER_PASSWORD}
}
}
End Edit
I only have experience with the oracle config but I believe it is fairly similar. You are missing the critical $ at the end of the default driver. Also you will need to make sure your SBT project recognizes the lib
This first code snippet should be in application.conf or whatever file you are using for your Configuration
oracle = {
driver = "com.typesafe.slick.driver.oracle.OracleDriver$"
db {
host = ""
port = ""
sid = ""
url = "jdbc:oracle:thin:#//"${oracle.db.host}":"${oracle.db.port}"/"${oracle.db.sid}
user = ${?USERNAME}
password = ${?PASSWORD}
driver = oracle.jdbc.driver.OracleDriver
}
}
This second section is in my build.sbt . I put my oracle driver in the base folder in the /.lib, although their may be a better way.
unmanagedBase := baseDirectory.value / ".lib"
Finally to make sure the config is loading properly. Slick default seems to misbehave, so hopefully you get a right answer, rather than a what works for me answer. However utilizing my config above I can then load that using the last snippet. I found this in an example of a cake implementation and it has worked very well in multiple projects.
val dbConfig: DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig("oracle")
implicit val profile: JdbcProfile = dbConfig.driver
implicit val db: JdbcProfile#Backend#Database = dbConfig.db
This allows you to use the database, the driver for imports and will fail on compile if your configuration is wrong. Hope this helps.
edit : I finished and realized you were working with Azure so make sure that you can fully connect utilizing the same settings from the same machine utilizing a client of your choice. To make sure all firewall and user settings are correct and that the problem truly lies in your code and not in your system configuration.
edit2: Wanted to make sure I didn't give you bad advice since it was an Oracle Config so I set it up against and AWS SQL Server. I utilized the sqljdbc42.jar that is given by Microsoft with their jdbc install. Put that in the .lib and then I had a configuration like follows. As in the upper example you could instead use Environmental variables but this was just a quick proof of concept. Here is a Microsoft SQL Server Config I have now tested to confirm works.
sqlserver = {
driver = "com.typesafe.slick.driver.ms.SQLServerDriver$"
db {
driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
host = ""
port = ""
databaseName = ""
url = "jdbc:sqlserver://"${sqlserver.db.host}":"${sqlserver.db.port}";databaseName="${sqlserver.db.databaseName}
user = ""
password = ""
}
}

Titanium how to move DB to SD card

Im programming in Titanium for Android.
I have 6 sqlite databases and i don't want to store them on the device internal memory because DB amount size is too large.
So, how can i move the sqlite files to SD card programmatically? Or how to install Dbs directly on the SD card when users installs my App from PlayStore?
PD: I try adding "PreferExternal" but this didn't fix my problem.
<manifest android:installLocation="preferExternal</manifest>
thanks in advance!
From Titanium docs of Ti.Database.open.
Open a Database on External Storage (Android)
A database, with a filename of mydb2Installed and located at the absolute path provided, is opened.
if (Ti.Platform.name === 'android' && Ti.Filesystem.isExternalStoragePresent()) {
var db2 = Ti.Database.open(Ti.Filesystem.externalStorageDirectory + 'path' + Ti.Filesystem.separator + 'to' + Ti.Filesystem.separator + 'mydb2Installed');
}
Hopefully this will do the trick.
I have no idea about titanium. But in android you can move DB by below logic:
copy your Database.db file in your projects assets folder.
In manifest file define permission shown below:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
now using code copy database file from /asset to device's external storage
For copy file use below code,
try {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open("your database file name");
// Path to the just created empty db
String outFileName = "path of external storage/<database_file_name>";
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
catch (Exception e)
{
Log.e("error", e.toString());
}
According to this question : Android: use SQLite database on SD Card (not using internal Android Data Store at all)
You can use :
SQLiteDatabase.openOrCreateDatabase(String, SQLiteDatabase.CursorFactory)
Put your path as the first parameter and null as the second.
To get the path of your sdcard do :
Environment.getExternalStorageDirectory();
But note that everyone with a physical access to the device can access to the database file...

Resources